Support dynamic trace flags.
This MR adds an API to the RTS (exposed via Rts.h) that allows users to dynamically change the trace flags. Currently, users are able to stop and start the profiling and heap profiling timers (via startProfTimer/stopProfTimer and startHeapProfTimer/stopHeapProfTimer). This extends that functionality to also cover the core event types.
/*
* An enumeration for the runtime trace flags.
*/
typedef enum {
TRACE_SCHEDULER,
TRACE_GC,
TRACE_NONMOVING_GC,
TRACE_SPARK_SAMPLED,
TRACE_SPARK_FULL,
TRACE_USER,
TRACE_CAP,
} RUNTIME_TRACE_FLAG;
/*
* Get the value of the given runtime trace flag.
*
* Warning: The trace flag cache is not thread-safe. After initialisation, the
* RTS never writes to these values, but concurrently using getTraceFlag and
* setTraceFlag for the same flag is a race condition.
*/
bool getTraceFlag(RUNTIME_TRACE_FLAG flag);
/*
* Set the value of the given runtime trace flag.
*
* Warning: The trace flag cache is not thread-safe. After initialisation, the
* RTS never writes to these values. However, inconsistent reads may lead to
* incorrect tracing for a short time after setting a trace flag.
*/
void setTraceFlag(RUNTIME_TRACE_FLAG flag, bool value);
The getTraceFlag/setTraceFlag functions read and write the values of the trace flag cache, which is allocated by Trace.c, rather than modifying the members of RtsFlags.TraceFlags. This is done under the assumption that the members of RtsFlags should not be modified after RTS initialisation. Consequently, if the user modifies the trace flags using setTraceFlag, the object returned by getTraceFlags (from base) will not reflect these changes.
The trace flags are not protected by locks of any sort. Hence, these functions are not technically thread-safe. However, the trace flags are not modified by the RTS after initialisation, only read, so the race conditions introduced by one user modifying them are most likely benign.
This MR does not add any tests for this functionality. However, I've tested this implementation in the test suite for eventlog-socket (see wenkokke/dynamic-trace-flags).
For more discussion of this design, see #27186.
This PR also puts the trace flag cache in a single global struct, as opposed to a collection of global variables, and changes the types of the individual flags from uint8_t to bool, as these have the same size on both Clang and GCC and are a better semantic match. Prior to the change to uint8_t, they had type int, see 42c47cd6. However, even with its deprecation in C23, I don't think there should be any issue depending on stdbool.h.