diff options
Diffstat (limited to 'mps/code/eventcom.h')
| -rw-r--r-- | mps/code/eventcom.h | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/mps/code/eventcom.h b/mps/code/eventcom.h index 1bf0a67c311..64fe935edde 100644 --- a/mps/code/eventcom.h +++ b/mps/code/eventcom.h | |||
| @@ -10,11 +10,84 @@ | |||
| 10 | #define eventcom_h | 10 | #define eventcom_h |
| 11 | 11 | ||
| 12 | #include <limits.h> | 12 | #include <limits.h> |
| 13 | #include "config.h" /* for EventClock */ | ||
| 14 | #include "mpmtypes.h" /* for Word */ | 13 | #include "mpmtypes.h" /* for Word */ |
| 15 | #include "eventdef.h" | 14 | #include "eventdef.h" |
| 16 | 15 | ||
| 17 | 16 | ||
| 17 | /* EVENT_CLOCK -- fast event timestamp clock | ||
| 18 | * | ||
| 19 | * On platforms that support it, we want to stamp events with a very cheap | ||
| 20 | * and fast high-resolution timer. | ||
| 21 | */ | ||
| 22 | |||
| 23 | /* http://msdn.microsoft.com/en-US/library/twchhe95%28v=vs.100%29.aspx */ | ||
| 24 | #if (defined(MPS_ARCH_I3) || defined(MPS_ARCH_I6)) && defined(MPS_BUILD_MV) | ||
| 25 | |||
| 26 | #pragma intrinsic(__rdtsc) | ||
| 27 | |||
| 28 | typedef unsigned __int64 EventClock; | ||
| 29 | |||
| 30 | #define EVENT_CLOCK(lvalue) \ | ||
| 31 | BEGIN \ | ||
| 32 | (lvalue) = __rdtsc(); \ | ||
| 33 | END | ||
| 34 | |||
| 35 | #define EVENT_CLOCK_PRINT(stream, clock) fprintf(stream, "%llu", clock) | ||
| 36 | |||
| 37 | /* http://clang.llvm.org/docs/LanguageExtensions.html#builtins */ | ||
| 38 | #elif defined(MPS_BUILD_LL) | ||
| 39 | |||
| 40 | #if __has_builtin(__builtin_readcyclecounter) | ||
| 41 | |||
| 42 | typedef unsigned long long EventClock; | ||
| 43 | |||
| 44 | #define EVENT_CLOCK(lvalue) \ | ||
| 45 | BEGIN \ | ||
| 46 | (lvalue) = __builtin_readcyclecounter(); \ | ||
| 47 | END | ||
| 48 | |||
| 49 | #define EVENT_CLOCK_PRINT(stream, clock) fprintf(stream, "%llu", clock) | ||
| 50 | |||
| 51 | #endif /* __has_builtin(__builtin_readcyclecounter) */ | ||
| 52 | |||
| 53 | #endif | ||
| 54 | |||
| 55 | /* Assemble the rdtsc instruction */ | ||
| 56 | #if !defined(EVENT_CLOCK) && \ | ||
| 57 | (defined(MPS_ARCH_I3) || defined(MPS_ARCH_I6)) && \ | ||
| 58 | (defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL)) | ||
| 59 | |||
| 60 | /* Use __extension__ to enable use of a 64-bit type on 32-bit pedantic GCC */ | ||
| 61 | __extension__ typedef unsigned long long EventClock; | ||
| 62 | |||
| 63 | #define EVENT_CLOCK(lvalue) \ | ||
| 64 | BEGIN \ | ||
| 65 | unsigned _l, _h; \ | ||
| 66 | __asm__ __volatile__("rdtsc" : "=a"(_l), "=d"(_h)); \ | ||
| 67 | (lvalue) = ((EventClock)_h << 32) | _l; \ | ||
| 68 | END | ||
| 69 | |||
| 70 | #define EVENT_CLOCK_PRINT(stream, clock) \ | ||
| 71 | fprintf(stream, "%lu", (unsigned long)clock) /* FIXME: Should be %llu */ | ||
| 72 | |||
| 73 | #endif /* Intel, GCC or Clang */ | ||
| 74 | |||
| 75 | /* no fast clock, use plinth, probably from the C library */ | ||
| 76 | #ifndef EVENT_CLOCK | ||
| 77 | |||
| 78 | typedef Word EventClock; | ||
| 79 | |||
| 80 | #define EVENT_CLOCK(lvalue) \ | ||
| 81 | BEGIN \ | ||
| 82 | (lvalue) = mps_clock(); \ | ||
| 83 | END | ||
| 84 | |||
| 85 | #define EVENT_CLOCK_PRINT(stream, clock) \ | ||
| 86 | fprintf(stream, "%llu", (unsigned long long)clock) | ||
| 87 | |||
| 88 | #endif | ||
| 89 | |||
| 90 | |||
| 18 | /* Types for event fields */ | 91 | /* Types for event fields */ |
| 19 | 92 | ||
| 20 | typedef unsigned short EventCode; | 93 | typedef unsigned short EventCode; |