]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/include/xray/xray_log_interface.h
MFV r328247: 8959 Add notifications when a scrub is paused or resumed
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / include / xray / xray_log_interface.h
1 //===-- xray_log_interface.h ----------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of XRay, a function call tracing system.
11 //
12 // APIs for installing a new logging implementation.
13 //
14 //===----------------------------------------------------------------------===//
15 ///
16 /// XRay allows users to implement their own logging handlers and install them
17 /// to replace the default runtime-controllable implementation that comes with
18 /// compiler-rt/xray. The "flight data recorder" (FDR) mode implementation uses
19 /// this API to install itself in an XRay-enabled binary. See
20 /// compiler-rt/lib/xray_fdr_logging.{h,cc} for details of that implementation.
21 ///
22 /// The high-level usage pattern for these APIs look like the following:
23 ///
24 ///   // Before we try initializing the log implementation, we must set it as
25 ///   // the log implementation. We provide the function pointers that define
26 ///   // the various initialization, finalization, and other pluggable hooks
27 ///   // that we need.
28 ///   __xray_set_log_impl({...});
29 ///
30 ///   // Once that's done, we can now initialize the implementation. Each
31 ///   // implementation has a chance to let users customize the implementation
32 ///   // with a struct that their implementation supports. Roughly this might
33 ///   // look like:
34 ///   MyImplementationOptions opts;
35 ///   opts.enable_feature = true;
36 ///   ...
37 ///   auto init_status = __xray_log_init(
38 ///       BufferSize, MaxBuffers, &opts, sizeof opts);
39 ///   if (init_status != XRayLogInitStatus::XRAY_LOG_INITIALIZED) {
40 ///     // deal with the error here, if there is one.
41 ///   }
42 ///
43 ///   // When the log implementation has had the chance to initialize, we can
44 ///   // now patch the sleds.
45 ///   auto patch_status = __xray_patch();
46 ///   if (patch_status != XRayPatchingStatus::SUCCESS) {
47 ///     // deal with the error here, if it is an error.
48 ///   }
49 ///
50 ///   // If we want to stop the implementation, we can then finalize it (before
51 ///   // optionally flushing the log).
52 ///   auto fin_status = __xray_log_finalize();
53 ///   if (fin_status != XRayLogInitStatus::XRAY_LOG_FINALIZED) {
54 ///     // deal with the error here, if it is an error.
55 ///   }
56 ///
57 ///   // We can optionally wait before flushing the log to give other threads a
58 ///   // chance to see that the implementation is already finalized. Also, at
59 ///   // this point we can optionally unpatch the sleds to reduce overheads at
60 ///   // runtime.
61 ///   auto unpatch_status = __xray_unpatch();
62 ///   if (unpatch_status != XRayPatchingStatus::SUCCESS) {
63 //      // deal with the error here, if it is an error.
64 //    }
65 ///
66 ///   // If there are logs or data to be flushed somewhere, we can do so only
67 ///   // after we've finalized the log. Some implementations may not actually
68 ///   // have anything to log (it might keep the data in memory, or periodically
69 ///   // be logging the data anyway).
70 ///   auto flush_status = __xray_log_flushLog();
71 ///   if (flush_status != XRayLogFlushStatus::XRAY_LOG_FLUSHED) {
72 ///     // deal with the error here, if it is an error.
73 ///   }
74 ///
75 ///
76 /// NOTE: Before calling __xray_patch() again, consider re-initializing the
77 /// implementation first. Some implementations might stay in an "off" state when
78 /// they are finalized, while some might be in an invalid/unknown state.
79 ///
80 #ifndef XRAY_XRAY_LOG_INTERFACE_H
81 #define XRAY_XRAY_LOG_INTERFACE_H
82
83 #include "xray/xray_interface.h"
84 #include <stddef.h>
85
86 extern "C" {
87
88 /// This enum defines the valid states in which the logging implementation can
89 /// be at.
90 enum XRayLogInitStatus {
91   /// The default state is uninitialized, and in case there were errors in the
92   /// initialization, the implementation MUST return XRAY_LOG_UNINITIALIZED.
93   XRAY_LOG_UNINITIALIZED = 0,
94
95   /// Some implementations support multi-stage init (or asynchronous init), and
96   /// may return XRAY_LOG_INITIALIZING to signal callers of the API that
97   /// there's an ongoing initialization routine running. This allows
98   /// implementations to support concurrent threads attempting to initialize,
99   /// while only signalling success in one.
100   XRAY_LOG_INITIALIZING = 1,
101
102   /// When an implementation is done initializing, it MUST return
103   /// XRAY_LOG_INITIALIZED. When users call `__xray_patch()`, they are
104   /// guaranteed that the implementation installed with
105   /// `__xray_set_log_impl(...)` has been initialized.
106   XRAY_LOG_INITIALIZED = 2,
107
108   /// Some implementations might support multi-stage finalization (or
109   /// asynchronous finalization), and may return XRAY_LOG_FINALIZING to signal
110   /// callers of the API that there's an ongoing finalization routine running.
111   /// This allows implementations to support concurrent threads attempting to
112   /// finalize, while only signalling success/completion in one.
113   XRAY_LOG_FINALIZING = 3,
114
115   /// When an implementation is done finalizing, it MUST return
116   /// XRAY_LOG_FINALIZED. It is up to the implementation to determine what the
117   /// semantics of a finalized implementation is. Some implementations might
118   /// allow re-initialization once the log is finalized, while some might always
119   /// be on (and that finalization is a no-op).
120   XRAY_LOG_FINALIZED = 4,
121 };
122
123 /// This enum allows an implementation to signal log flushing operations via
124 /// `__xray_log_flushLog()`, and the state of flushing the log.
125 enum XRayLogFlushStatus {
126   XRAY_LOG_NOT_FLUSHING = 0,
127   XRAY_LOG_FLUSHING = 1,
128   XRAY_LOG_FLUSHED = 2,
129 };
130
131 /// This enum indicates the installation state of a logging implementation, when
132 /// associating a mode to a particular logging implementation through
133 /// `__xray_log_register_impl(...)` or through `__xray_log_select_mode(...`.
134 enum XRayLogRegisterStatus {
135   XRAY_REGISTRATION_OK = 0,
136   XRAY_DUPLICATE_MODE = 1,
137   XRAY_MODE_NOT_FOUND = 2,
138   XRAY_INCOMPLETE_IMPL = 3,
139 };
140
141 /// A valid XRay logging implementation MUST provide all of the function
142 /// pointers in XRayLogImpl when being installed through `__xray_set_log_impl`.
143 /// To be precise, ALL the functions pointers MUST NOT be nullptr.
144 struct XRayLogImpl {
145   /// The log initialization routine provided by the implementation, always
146   /// provided with the following parameters:
147   ///
148   ///   - buffer size
149   ///   - maximum number of buffers
150   ///   - a pointer to an argument struct that the implementation MUST handle
151   ///   - the size of the argument struct
152   ///
153   /// See XRayLogInitStatus for details on what the implementation MUST return
154   /// when called.
155   ///
156   /// If the implementation needs to install handlers aside from the 0-argument
157   /// function call handler, it MUST do so in this initialization handler.
158   ///
159   /// See xray_interface.h for available handler installation routines.
160   XRayLogInitStatus (*log_init)(size_t, size_t, void *, size_t);
161
162   /// The log finalization routine provided by the implementation.
163   ///
164   /// See XRayLogInitStatus for details on what the implementation MUST return
165   /// when called.
166   XRayLogInitStatus (*log_finalize)();
167
168   /// The 0-argument function call handler. XRay logging implementations MUST
169   /// always have a handler for function entry and exit events. In case the
170   /// implementation wants to support arg1 (or other future extensions to XRay
171   /// logging) those MUST be installed by the installed 'log_init' handler.
172   ///
173   /// Because we didn't want to change the ABI of this struct, the arg1 handler
174   /// may be silently overwritten during initialization as well.
175   void (*handle_arg0)(int32_t, XRayEntryType);
176
177   /// The log implementation provided routine for when __xray_log_flushLog() is
178   /// called.
179   ///
180   /// See XRayLogFlushStatus for details on what the implementation MUST return
181   /// when called.
182   XRayLogFlushStatus (*flush_log)();
183 };
184
185 /// This function installs a new logging implementation that XRay will use. In
186 /// case there are any nullptr members in Impl, XRay will *uninstall any
187 /// existing implementations*. It does NOT patch the instrumentation sleds.
188 ///
189 /// NOTE: This function does NOT attempt to finalize the currently installed
190 /// implementation. Use with caution.
191 ///
192 /// It is guaranteed safe to call this function in the following states:
193 ///
194 ///   - When the implementation is UNINITIALIZED.
195 ///   - When the implementation is FINALIZED.
196 ///   - When there is no current implementation installed.
197 ///
198 /// It is logging implementation defined what happens when this function is
199 /// called while in any other states.
200 void __xray_set_log_impl(XRayLogImpl Impl);
201
202 /// This function registers a logging implementation against a "mode"
203 /// identifier. This allows multiple modes to be registered, and chosen at
204 /// runtime using the same mode identifier through
205 /// `__xray_log_select_mode(...)`.
206 ///
207 /// We treat the Mode identifier as a null-terminated byte string, as the
208 /// identifier used when retrieving the log impl.
209 ///
210 /// Returns:
211 ///   - XRAY_REGISTRATION_OK on success.
212 ///   - XRAY_DUPLICATE_MODE when an implementation is already associated with
213 ///     the provided Mode; does not update the already-registered
214 ///     implementation.
215 XRayLogRegisterStatus __xray_log_register_mode(const char *Mode,
216                                                XRayLogImpl Impl);
217
218 /// This function selects the implementation associated with Mode that has been
219 /// registered through __xray_log_register_mode(...) and installs that
220 /// implementation (as if through calling __xray_set_log_impl(...)). The same
221 /// caveats apply to __xray_log_select_mode(...) as with
222 /// __xray_log_set_log_impl(...).
223 ///
224 /// Returns:
225 ///   - XRAY_REGISTRATION_OK on success.
226 ///   - XRAY_MODE_NOT_FOUND if there is no implementation associated with Mode;
227 ///     does not update the currently installed implementation.
228 XRayLogRegisterStatus __xray_log_select_mode(const char *Mode);
229
230 /// This function removes the currently installed implementation. It will also
231 /// uninstall any handlers that have been previously installed. It does NOT
232 /// unpatch the instrumentation sleds.
233 ///
234 /// NOTE: This function does NOT attempt to finalize the currently installed
235 /// implementation. Use with caution.
236 ///
237 /// It is guaranteed safe to call this function in the following states:
238 ///
239 ///   - When the implementation is UNINITIALIZED.
240 ///   - When the implementation is FINALIZED.
241 ///   - When there is no current implementation installed.
242 ///
243 /// It is logging implementation defined what happens when this function is
244 /// called while in any other states.
245 void __xray_remove_log_impl();
246
247 /// Invokes the installed implementation initialization routine. See
248 /// XRayLogInitStatus for what the return values mean.
249 XRayLogInitStatus __xray_log_init(size_t BufferSize, size_t MaxBuffers,
250                                   void *Args, size_t ArgsSize);
251
252 /// Invokes the installed implementation finalization routine. See
253 /// XRayLogInitStatus for what the return values mean.
254 XRayLogInitStatus __xray_log_finalize();
255
256 /// Invokes the install implementation log flushing routine. See
257 /// XRayLogFlushStatus for what the return values mean.
258 XRayLogFlushStatus __xray_log_flushLog();
259
260 } // extern "C"
261
262 namespace __xray {
263
264 /// Options used by the LLVM XRay FDR logging implementation.
265 struct FDRLoggingOptions {
266   bool ReportErrors = false;
267   int Fd = -1;
268 };
269
270 /// Options used by the LLVM XRay Basic (Naive) logging implementation.
271 struct BasicLoggingOptions {
272   int DurationFilterMicros = 0;
273   size_t MaxStackDepth = 0;
274   size_t ThreadBufferSize = 0;
275 };
276
277 } // namespace __xray
278
279 #endif // XRAY_XRAY_LOG_INTERFACE_H