Res EventFlush(EventKind kind) { Res res; size_t size; AVER(eventInited); AVER(0 <= kind && kind < EventKindLIMIT); AVER(EventBuffer[kind] <= EventLast[kind]); AVER(EventLast[kind] <= EventBuffer[kind] + EventBufferSIZE); /* Is event logging enabled for this kind of event, or are or are we just writing to the buffer for backtraces, cores, and other debugging? */ if (BS_IS_MEMBER(EventKindControl, kind)) { size = (size_t)(EventBuffer[kind] + EventBufferSIZE - EventLast[kind]); /* Checking the size avoids creating the event stream when the arena is destroyed and no events have been logged. */ if (size == 0) return ResOK; /* Ensure the IO stream is open. We do this late so that no stream is created if no events are enabled by telemetry control. */ if (!eventIOInited) { res = (Res)mps_io_create(&eventIO); if(res != ResOK) goto failCreate; eventIOInited = TRUE; } /* Writing might be faster if the size is aligned to a multiple of the C library or kernel's buffer size. We could pad out the buffer with a marker for this purpose. */ res = (Res)mps_io_write(eventIO, (void *)EventLast[kind], size); if (res != ResOK) goto failWrite; } res = ResOK; failWrite: failCreate: /* Flush the in-memory buffer whether or not we succeeded, so that we can record recent events there. */ EventLast[kind] = EventBuffer[kind] + EventBufferSIZE; return res; }
void EventSync(void) { EventKind kind; Bool wrote = FALSE; for (kind = 0; kind < EventKindLIMIT; ++kind) { /* Is event logging enabled for this kind of event, or are or are we just writing to the buffer for backtraces, cores, and other debugging? */ if (BS_IS_MEMBER(EventKindControl, kind)) { size_t size; Res res; AVER(EventBuffer[kind] <= EventLast[kind]); AVER(EventLast[kind] <= EventWritten[kind]); AVER(EventWritten[kind] <= EventBuffer[kind] + EventBufferSIZE); size = (size_t)(EventWritten[kind] - EventLast[kind]); if (size > 0) { /* Ensure the IO stream is open. We do this late so that no stream is created if no events are enabled by telemetry control. */ if (!eventIOInited) { res = (Res)mps_io_create(&eventIO); if(res != ResOK) { /* TODO: Consider taking some other action if open fails. */ return; } eventIOInited = TRUE; } /* Writing might be faster if the size is aligned to a multiple of the C library or kernel's buffer size. We could pad out the buffer with a marker for this purpose. */ res = (Res)mps_io_write(eventIO, (void *)EventLast[kind], size); if (res == ResOK) { /* TODO: Consider taking some other action if a write fails. */ EventWritten[kind] = EventLast[kind]; wrote = TRUE; } } } } /* If we wrote out events, send an EventClockSync event and flush the telemetry stream. */ if (wrote) { (void)eventClockSync(); (void)mps_io_flush(eventIO); } }