void EventFinish(void) { AVER(eventInited); AVER(eventUserCount > 0); EventSync(); --eventUserCount; }
void EventFlush(EventKind kind) { AVER(eventInited); AVER(NONNEGATIVE(kind)); AVER(kind < EventKindLIMIT); AVER(EventBuffer[kind] <= EventLast[kind]); AVER(EventLast[kind] <= EventWritten[kind]); AVER(EventWritten[kind] <= EventBuffer[kind] + EventBufferSIZE); /* Send all pending events to the event stream. */ EventSync(); /* Flush the in-memory buffer whether or not we send this buffer, so that we can continue to record recent events. */ EventLast[kind] = EventWritten[kind] = EventBuffer[kind] + EventBufferSIZE; }
void EventInit(void) { /* Make local enums for all event params in order to check that the indexes in the parameter definition macros are in order, and that parameter idents are unique. */ #define EVENT_CHECK_ENUM_PARAM(name, index, sort, ident) \ Event##name##Param##ident, #define EVENT_CHECK_ENUM(X, name, code, always, kind) \ enum Event##name##ParamEnum { \ EVENT_##name##_PARAMS(EVENT_CHECK_ENUM_PARAM, name) \ Event##name##ParamLIMIT \ }; EVENT_LIST(EVENT_CHECK_ENUM, X) /* Check consistency of the event definitions. These are all compile-time checks and should get optimised away. */ #define EVENT_PARAM_CHECK_P(name, index, ident) #define EVENT_PARAM_CHECK_A(name, index, ident) #define EVENT_PARAM_CHECK_W(name, index, ident) #define EVENT_PARAM_CHECK_U(name, index, ident) #define EVENT_PARAM_CHECK_D(name, index, ident) #define EVENT_PARAM_CHECK_B(name, index, ident) #define EVENT_PARAM_CHECK_S(name, index, ident) \ AVER(index + 1 == Event##name##ParamLIMIT); /* strings must come last */ #define EVENT_PARAM_CHECK(name, index, sort, ident) \ AVER(index == Event##name##Param##ident); \ AVER(sizeof(EventF##sort) >= 0); /* check existence of type */ \ EVENT_PARAM_CHECK_##sort(name, index, ident) #define EVENT_CHECK(X, name, code, always, kind) \ AVER(size_tAlignUp(sizeof(Event##name##Struct), MPS_PF_ALIGN) \ <= EventSizeMAX); \ AVER(Event##name##Code == code); \ AVER(0 <= code); \ AVER(code <= EventCodeMAX); \ AVER(sizeof(#name) - 1 <= EventNameMAX); \ AVER((Bool)Event##name##Always == always); \ AVERT(Bool, always); \ AVER(0 <= Event##name##Kind); \ AVER((EventKind)Event##name##Kind < EventKindLIMIT); \ EVENT_##name##_PARAMS(EVENT_PARAM_CHECK, name) EVENT_LIST(EVENT_CHECK, X); /* Ensure that no event can be larger than the maximum event size. */ AVER(EventBufferSIZE <= EventSizeMAX); /* Only if this is the first call. */ if(!eventInited) { /* See .trans.log */ EventKind kind; for (kind = 0; kind < EventKindLIMIT; ++kind) { AVER(EventLast[kind] == NULL); AVER(EventWritten[kind] == NULL); EventLast[kind] = EventWritten[kind] = EventBuffer[kind] + EventBufferSIZE; } eventUserCount = (Count)1; eventInited = TRUE; EventKindControl = (Word)mps_lib_telemetry_control(); EventInternSerial = (Serial)1; /* 0 is reserved */ (void)EventInternString(MPSVersion()); /* emit version */ EVENT7(EventInit, EVENT_VERSION_MAJOR, EVENT_VERSION_MEDIAN, EVENT_VERSION_MINOR, EventCodeMAX, EventNameMAX, MPS_WORD_WIDTH, mps_clocks_per_sec()); /* flush these initial events to get the first ClockSync out. */ EventSync(); } else { ++eventUserCount; } }