Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Framework/Foundation/include/Framework/Signpost.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,20 @@ bool _o2_lock_free_stack_push(_o2_lock_free_stack& stack, const int& value, bool
bool _o2_lock_free_stack_pop(_o2_lock_free_stack& stack, int& value, bool spin = false);
void* _o2_log_create(char const* name, int stacktrace);
void _o2_signpost_event_emit(_o2_log_t* log, _o2_signpost_id_t id, char const* name, char const* const format, ...);
void _o2_singpost_action(_o2_log_t* log, void (*callback)(void*));
void _o2_signpost_interval_begin(_o2_log_t* log, _o2_signpost_id_t id, char const* name, char const* const format, ...);
void _o2_signpost_interval_end(_o2_log_t* log, _o2_signpost_id_t id, char const* name, char const* const format, ...);
void _o2_log_set_stacktrace(_o2_log_t* log, int stacktrace);

// Helper to invoke a callback when the signpost is enabled. The callback
// gets passed some previously stored context (nullptr for now).
// TODO: I use a separate function because in the future this might change and I might
// allow to store some context as part of the activity.
inline void _o2_signpost_action(_o2_log_t* log, void (*callback)(void*))
{
callback(nullptr);
}

// This generates a unique id for a signpost. Do not use this directly, use O2_SIGNPOST_ID_GENERATE instead.
// Notice that this is only valid on a given computer.
// This is guaranteed to be unique at 5 GHz for at least 63 years, if my math is correct.
Expand Down Expand Up @@ -488,6 +498,17 @@ void o2_debug_log_set_stacktrace(_o2_log_t* log, int stacktrace)
})
#define O2_SIGNPOST_ID_FROM_POINTER(name, log, pointer) _o2_signpost_id_t name = _o2_signpost_id_make_with_pointer(private_o2_log_##log, pointer)
#define O2_SIGNPOST_ID_GENERATE(name, log) _o2_signpost_id_t name = _o2_signpost_id_generate_local(private_o2_log_##log)

// Execute the provided callback if the log is enabled. Useful e.g. to dump IgProf profiles
// only if the signpost is enabled or to add remote telemetry for certain events.
#define O2_SIGNPOST_ACTION(log, callback) __extension__({ \
if (O2_BUILTIN_UNLIKELY(O2_SIGNPOST_ENABLED_MAC(log))) { \
_o2_signpost_action(private_o2_log_##log, callback); \
} else if (O2_BUILTIN_UNLIKELY(private_o2_log_##log->stacktrace)) { \
_o2_signpost_action(private_o2_log_##log, callback); \
} \
})

// In case Instruments is attached, we switch to the Apple signpost API otherwise, both one
// mac and on linux we use our own implementation, using the logger. We can use the same ids because
// they are compatible between the two implementations, we also use remove_engineering_type to remove
Expand Down
7 changes: 7 additions & 0 deletions Framework/Foundation/test/test_SignpostLogger.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,11 @@ int main(int argc, char** argv)
O2_SIGNPOST_ID_GENERATE(idStacktrace, SignpostStacktrace);
O2_LOG_ENABLE(SignpostStacktrace);
O2_SIGNPOST_EVENT_EMIT_ERROR(SignpostStacktrace, idStacktrace, "Test category", "An error with stacktrace %d \n", 1);
// Test actions associtated to a given debug stream.
static bool testMustCall = false;
static bool testMustNotCall = false;
O2_SIGNPOST_ACTION(SignpostStacktrace, [](void*) { testMustCall = true; });
O2_LOG_DISABLE(SignpostStacktrace);
O2_SIGNPOST_ACTION(SignpostStacktrace, [](void*) { testMustNotCall = true; });
return testMustCall && (!testMustNotCall) ? 0 : 1;
}