aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Brooksby2012-09-15 14:52:06 +0100
committerRichard Brooksby2012-09-15 14:52:06 +0100
commit0353e7c200f33fbd5da1fe981840987639580dbd (patch)
tree1dd68489ce0ce4ad79ee4a1badcd4b44bab1a669 /mps/code
parenteb30f6bc82d9493db1b1382c8c06c37ab15f639c (diff)
downloademacs-0353e7c200f33fbd5da1fe981840987639580dbd.tar.gz
emacs-0353e7c200f33fbd5da1fe981840987639580dbd.zip
Moving the platform-dependent event clock to its own header, preparing to generalise it for other purposes.
Copied from Perforce Change: 179501 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/clock.h191
-rw-r--r--mps/code/eventcom.h136
2 files changed, 192 insertions, 135 deletions
diff --git a/mps/code/clock.h b/mps/code/clock.h
new file mode 100644
index 00000000000..881d74e2715
--- /dev/null
+++ b/mps/code/clock.h
@@ -0,0 +1,191 @@
1/* clock.h -- Fast clocks and timers
2 *
3 * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
4 * $Id$
5 */
6
7#ifndef clock_h
8#define clock_h
9
10#include <limits.h>
11#include "mpmtypes.h" /* for Word */
12
13
14/* EVENT_CLOCK -- fast event timestamp clock
15 *
16 * On platforms that support it, we want to stamp events with a very cheap
17 * and fast high-resolution timer.
18 *
19 * TODO: This is a sufficiently complicated nest of ifdefs that it should
20 * be quarantined in its own header with KEEP OUT signs attached.
21 * RB 2012-09-11
22 */
23
24/* TODO: Clang supposedly provides a cross-platform builtin for a fast
25 timer, but it doesn't seem to be present on Mac OS X 10.8. We should
26 use it if it ever appears.
27 <http://clang.llvm.org/docs/LanguageExtensions.html#builtins> */
28#if defined(MPS_BUILD_LL)
29
30#if __has_builtin(__builtin_readcyclecounter)
31#error "__builtin_readcyclecounter is available but not used"
32#endif /* __has_builtin(__builtin_readcyclecounter) */
33
34#endif
35
36/* Microsoft C provides an intrinsic for the Intel rdtsc instruction.
37 <http://msdn.microsoft.com/en-US/library/twchhe95%28v=vs.100%29.aspx> */
38#if (defined(MPS_ARCH_I3) || defined(MPS_ARCH_I6)) && defined(MPS_BUILD_MV)
39
40typedef unsigned __int64 EventClock;
41
42typedef union EventClockUnion {
43 struct {
44 unsigned low, high;
45 } half;
46 unsigned __int64 whole;
47} EventClockUnion;
48
49#if _MSC_VER >= 1400
50
51#pragma intrinsic(__rdtsc)
52
53#define EVENT_CLOCK(lvalue) \
54 BEGIN \
55 (lvalue) = __rdtsc(); \
56 END
57
58#else /* _MSC_VER < 1400 */
59
60/* This is mostly a patch for Open Dylan's bootstrap on Windows, which is
61 using Microsoft Visual Studio 6 because of support for CodeView debugging
62 information. */
63
64#include <windows.h> /* KILL IT WITH FIRE! */
65
66#define EVENT_CLOCK(lvalue) \
67 BEGIN \
68 LARGE_INTEGER _count; \
69 QueryPerformanceCounter(&_count); \
70 (lvalue) = _count.QuadPart; \
71 END
72
73#endif /* _MSC_VER < 1400 */
74
75#if defined(MPS_ARCH_I3)
76
77/* We can't use a shift to get the top half of the 64-bit event clock,
78 because that introduces a dependency on `__aullshr` in the C run-time. */
79
80#define EVENT_CLOCK_PRINT(stream, clock) \
81 fprintf(stream, "%08lX%08lX", \
82 (*(EventClockUnion *)&(clock)).half.high, \
83 (*(EventClockUnion *)&(clock)).half.low)
84
85#define EVENT_CLOCK_WRITE(stream, clock) \
86 WriteF(stream, "$W$W", \
87 (*(EventClockUnion *)&(clock)).half.high, \
88 (*(EventClockUnion *)&(clock)).half.low, \
89 NULL)
90
91#elif defined(MPS_ARCH_I6)
92
93#define EVENT_CLOCK_PRINT(stream, clock) \
94 fprintf(stream, "%016lX", (clock));
95
96#define EVENT_CLOCK_WRITE(stream, clock) \
97 WriteF(stream, "$W", (WriteFW)(clock), NULL)
98
99#endif
100
101#endif /* Microsoft C on Intel */
102
103/* If we have GCC or Clang, assemble the rdtsc instruction */
104#if !defined(EVENT_CLOCK) && \
105 (defined(MPS_ARCH_I3) || defined(MPS_ARCH_I6)) && \
106 (defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL))
107
108/* Use __extension__ to enable use of a 64-bit type on 32-bit pedantic GCC */
109__extension__ typedef unsigned long long EventClock;
110
111#define EVENT_CLOCK(lvalue) \
112 BEGIN \
113 unsigned _l, _h; \
114 __asm__ __volatile__("rdtsc" : "=a"(_l), "=d"(_h)); \
115 (lvalue) = ((EventClock)_h << 32) | _l; \
116 END
117
118/* The __extension__ keyword doesn't work on printf formats, so we
119 concatenate two 32-bit hex numbers to print the 64-bit value. */
120#define EVENT_CLOCK_PRINT(stream, clock) \
121 fprintf(stream, "%08lX%08lX", \
122 (unsigned long)((clock) >> 32), \
123 (unsigned long)(clock))
124
125#define EVENT_CLOCK_WRITE(stream, clock) \
126 WriteF(stream, "$W$W", (WriteFW)((clock) >> 32), (WriteFW)clock, NULL)
127
128#endif /* Intel, GCC or Clang */
129
130/* no fast clock, use plinth, probably from the C library */
131#ifndef EVENT_CLOCK
132
133typedef mps_clock_t EventClock;
134
135#define EVENT_CLOCK(lvalue) \
136 BEGIN \
137 (lvalue) = mps_clock(); \
138 END
139
140#define EVENT_CLOCK_PRINT(stream, clock) \
141 fprintf(stream, "%lu", (unsigned long)clock)
142
143#define EVENT_CLOCK_WRITE(stream, clock) \
144 WriteF(stream, "$W", (WriteFW)clock, NULL)
145
146#endif
147
148
149#endif /* clock_h */
150
151
152/* C. COPYRIGHT AND LICENSE
153 *
154 * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
155 * All rights reserved. This is an open source license. Contact
156 * Ravenbrook for commercial licensing options.
157 *
158 * Redistribution and use in source and binary forms, with or without
159 * modification, are permitted provided that the following conditions are
160 * met:
161 *
162 * 1. Redistributions of source code must retain the above copyright
163 * notice, this list of conditions and the following disclaimer.
164 *
165 * 2. Redistributions in binary form must reproduce the above copyright
166 * notice, this list of conditions and the following disclaimer in the
167 * documentation and/or other materials provided with the distribution.
168 *
169 * 3. Redistributions in any form must be accompanied by information on how
170 * to obtain complete source code for this software and any accompanying
171 * software that uses this software. The source code must either be
172 * included in the distribution or be available for no more than the cost
173 * of distribution plus a nominal fee, and must be freely redistributable
174 * under reasonable conditions. For an executable file, complete source
175 * code means the source code for all modules it contains. It does not
176 * include source code for modules or files that typically accompany the
177 * major components of the operating system on which the executable file
178 * runs.
179 *
180 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
181 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
182 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
183 * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
184 * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
185 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
186 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
187 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
188 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
189 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
190 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
191 */
diff --git a/mps/code/eventcom.h b/mps/code/eventcom.h
index 131bc8e1823..6114b045d48 100644
--- a/mps/code/eventcom.h
+++ b/mps/code/eventcom.h
@@ -12,141 +12,7 @@
12#include <limits.h> 12#include <limits.h>
13#include "mpmtypes.h" /* for Word */ 13#include "mpmtypes.h" /* for Word */
14#include "eventdef.h" 14#include "eventdef.h"
15 15#include "clock.h"
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 * TODO: This is a sufficiently complicated nest of ifdefs that it should
23 * be quarantined in its own header with KEEP OUT signs attached.
24 * RB 2012-09-11
25 */
26
27/* TODO: Clang supposedly provides a cross-platform builtin for a fast
28 timer, but it doesn't seem to be present on Mac OS X 10.8. We should
29 use it if it ever appears.
30 <http://clang.llvm.org/docs/LanguageExtensions.html#builtins> */
31#if defined(MPS_BUILD_LL)
32
33#if __has_builtin(__builtin_readcyclecounter)
34#error "__builtin_readcyclecounter is available but not used"
35#endif /* __has_builtin(__builtin_readcyclecounter) */
36
37#endif
38
39/* Microsoft C provides an intrinsic for the Intel rdtsc instruction.
40 <http://msdn.microsoft.com/en-US/library/twchhe95%28v=vs.100%29.aspx> */
41#if (defined(MPS_ARCH_I3) || defined(MPS_ARCH_I6)) && defined(MPS_BUILD_MV)
42
43typedef unsigned __int64 EventClock;
44
45typedef union EventClockUnion {
46 struct {
47 unsigned low, high;
48 } half;
49 unsigned __int64 whole;
50} EventClockUnion;
51
52#if _MSC_VER >= 1400
53
54#pragma intrinsic(__rdtsc)
55
56#define EVENT_CLOCK(lvalue) \
57 BEGIN \
58 (lvalue) = __rdtsc(); \
59 END
60
61#else /* _MSC_VER < 1400 */
62
63/* This is mostly a patch for Open Dylan's bootstrap on Windows, which is
64 using Microsoft Visual Studio 6 because of support for CodeView debugging
65 information. */
66
67#include <windows.h> /* KILL IT WITH FIRE! */
68
69#define EVENT_CLOCK(lvalue) \
70 BEGIN \
71 LARGE_INTEGER _count; \
72 QueryPerformanceCounter(&_count); \
73 (lvalue) = _count.QuadPart; \
74 END
75
76#endif /* _MSC_VER < 1400 */
77
78#if defined(MPS_ARCH_I3)
79
80/* We can't use a shift to get the top half of the 64-bit event clock,
81 because that introduces a dependency on `__aullshr` in the C run-time. */
82
83#define EVENT_CLOCK_PRINT(stream, clock) \
84 fprintf(stream, "%08lX%08lX", \
85 (*(EventClockUnion *)&(clock)).half.high, \
86 (*(EventClockUnion *)&(clock)).half.low)
87
88#define EVENT_CLOCK_WRITE(stream, clock) \
89 WriteF(stream, "$W$W", \
90 (*(EventClockUnion *)&(clock)).half.high, \
91 (*(EventClockUnion *)&(clock)).half.low, \
92 NULL)
93
94#elif defined(MPS_ARCH_I6)
95
96#define EVENT_CLOCK_PRINT(stream, clock) \
97 fprintf(stream, "%016lX", (clock));
98
99#define EVENT_CLOCK_WRITE(stream, clock) \
100 WriteF(stream, "$W", (WriteFW)(clock), NULL)
101
102#endif
103
104#endif /* Microsoft C on Intel */
105
106/* If we have GCC or Clang, assemble the rdtsc instruction */
107#if !defined(EVENT_CLOCK) && \
108 (defined(MPS_ARCH_I3) || defined(MPS_ARCH_I6)) && \
109 (defined(MPS_BUILD_GC) || defined(MPS_BUILD_LL))
110
111/* Use __extension__ to enable use of a 64-bit type on 32-bit pedantic GCC */
112__extension__ typedef unsigned long long EventClock;
113
114#define EVENT_CLOCK(lvalue) \
115 BEGIN \
116 unsigned _l, _h; \
117 __asm__ __volatile__("rdtsc" : "=a"(_l), "=d"(_h)); \
118 (lvalue) = ((EventClock)_h << 32) | _l; \
119 END
120
121/* The __extension__ keyword doesn't work on printf formats, so we
122 concatenate two 32-bit hex numbers to print the 64-bit value. */
123#define EVENT_CLOCK_PRINT(stream, clock) \
124 fprintf(stream, "%08lX%08lX", \
125 (unsigned long)((clock) >> 32), \
126 (unsigned long)(clock))
127
128#define EVENT_CLOCK_WRITE(stream, clock) \
129 WriteF(stream, "$W$W", (WriteFW)((clock) >> 32), (WriteFW)clock, NULL)
130
131#endif /* Intel, GCC or Clang */
132
133/* no fast clock, use plinth, probably from the C library */
134#ifndef EVENT_CLOCK
135
136typedef mps_clock_t EventClock;
137
138#define EVENT_CLOCK(lvalue) \
139 BEGIN \
140 (lvalue) = mps_clock(); \
141 END
142
143#define EVENT_CLOCK_PRINT(stream, clock) \
144 fprintf(stream, "%lu", (unsigned long)clock)
145
146#define EVENT_CLOCK_WRITE(stream, clock) \
147 WriteF(stream, "$W", (WriteFW)clock, NULL)
148
149#endif
150 16
151 17
152/* Event Kinds --- see <design/telemetry/> 18/* Event Kinds --- see <design/telemetry/>