Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
trace.h
Go to the documentation of this file.
1/* -*- C -*-
2 * Serene programming language
3 * Copyright (C) 2019-2026 Sameer Rahmani <[email protected]>
4 *
5 * This library is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20/** @file
21 Platform neutral static tracepoints.
22
23 SRN_TP(group, name, args...) is a probe a tracer observes only when
24 attached. It maps to the native facility per platform and falls back to a no-op
25 that still marks its arguments used on platforms with no facility, such as
26 WebAssembly. Call sites never name a platform; this header owns that choice.
27*/
28
29// Keep the arguments in an unevaluated context. Nothing is evaluated, no side
30// effect runs, but each argument counts as used, so -Werror -Wunused is happy.
31#define SRN_TP_CONSUME(...)
32//((void)sizeof((0 __VA_OPT__(, ) __VA_ARGS__)))
33
34/**
35 * Placement matters. SRN_TRACEPOINT expands to a probe instruction the compiler
36 * may leave right at a function's epilogue. Never put it as the last statement
37 * before a fiber's `return`. A fiber entry returns into the context switch
38 * trampoline, and a tracer breakpoint sitting on that teardown trips the stack
39 * protector and aborts the process under perf. Put it on an ordinary reachable
40 * statement with real code after it, and never right after a loop that never
41 * exits, where the optimizer deletes the probe. To mark a fiber's own start and
42 * end, emit from the scheduler around the switch rather than from inside the
43 * fiber.
44 */
45#if defined(__linux__)
46# include "../../vendor/usdt.h"
47# define SRN_TRACEPOINT(name, ...) USDT(serene, name __VA_OPT__(, ) __VA_ARGS__)
48# define SRN_TRACEPOINT_WITH_GROUP(group, name, ...) \
49 USDT(serene_##group, name __VA_OPT__(, ) __VA_ARGS__)
50
51#elif defined(__APPLE__)
52# include <os/signpost.h>
53# define SRN_TRACEPOINT(name, ...) \
54 do { \
55 os_signpost_event_emit(OS_LOG_DEFAULT, OS_SIGNPOST_ID_EXCLUSIVE, "serene." #name); \
56 SRN_TP_CONSUME(__VA_ARGS__); \
57 } while (0)
58# define SRN_TRACEPOINT_WITH_GROUP(group, name, ...) \
59 do { \
60 os_signpost_event_emit(OS_LOG_DEFAULT, OS_SIGNPOST_ID_EXCLUSIVE, "serene." #group #name); \
61 SRN_TP_CONSUME(__VA_ARGS__); \
62 } while (0)
63
64#elif defined(_WIN32)
65# include <TraceLoggingProvider.h>
66# include <windows.h>
67TRACELOGGING_DECLARE_PROVIDER(srn_trace_provider);
68# define SRN_TRACEPOINT(name, ...) \
69 do { \
70 TraceLoggingWrite(srn_trace_provider, #name, TraceLoggingString("serene", "group")); \
71 SRN_TP_CONSUME(__VA_ARGS__); \
72 } while (0)
73# define SRN_TRACEPOINT_WITH_GROUP(group, name, ...) \
74 do { \
75 TraceLoggingWrite(srn_trace_provider, #name, TraceLoggingString("serene_" #group, "group")); \
76 SRN_TP_CONSUME(__VA_ARGS__); \
77 } while (0)
78#else // WebAssembly and any platform with no tracing facility
79# define SRN_TRACEPOINT(name, ...) SRN_TP_CONSUME(__VA_ARGS__)
80# define SRN_TRACEPOINT_WITH_GROUP(group, name, ...) SRN_TP_CONSUME(__VA_ARGS__)
81#endif