xref: /aosp_15_r20/external/kotlinx.atomicfu/atomicfu/src/commonMain/kotlin/kotlinx/atomicfu/Trace.common.kt (revision 68017707106cb9da9fed635c150bc497c09c160f)
1 /*
2  * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 @file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
6 
7 package kotlinx.atomicfu
8 
9 import kotlin.internal.InlineOnly
10 
11 /**
12  * Creates `Trace` object for tracing atomic operations.
13  *
14  * To use a trace create a separate field for `Trace`:
15  *
16  * ```
17  * val trace = Trace(size)
18  * ```
19  *
20  * Using it to add trace messages:
21  *
22  * ```
23  * trace { "Doing something" }
24  * ```
25  * or you can do multi-append in a garbage-free manner
26  * ```
27  * // Before queue.send(element) invocation
28  * trace.append("Adding element to the queue", element, Thread.currentThread())
29  * ```
30  *
31  * Pass it to `atomic` constructor to automatically trace all modifications of the corresponding field:
32  *
33  * ```
34  * val state = atomic(initialValue, trace)
35  * ```
36  * An optional [named][TraceBase.named] call can be used to name all the messages related to this specific instance:
37  *
38  * ```
39  * val state = atomic(initialValue, trace.named("state"))
40  * ```
41  *
42  * An optional [format] parameter can be specified to add context-specific information to each trace.
43  * The default format is [traceFormatDefault].
44  */
45 @Suppress("FunctionName")
Tracenull46 public expect fun Trace(size: Int = 32, format: TraceFormat = traceFormatDefault): TraceBase
47 
48 /**
49  * Adds a name to the trace. For example:
50  *
51  * ```
52  * val state = atomic(initialValue, trace.named("state"))
53  * ```
54  */
55 public expect fun TraceBase.named(name: String): TraceBase
56 
57 /**
58  * The default trace string formatter.
59  *
60  * On JVM when `kotlinx.atomicfu.trace.thread` system property is set, then the default format
61  * also includes thread name for each operation.
62  */
63 public expect val traceFormatDefault: TraceFormat
64 
65 /**
66  * Base class for implementations of `Trace`.
67  */
68 @OptionalJsName(TRACE_BASE_CONSTRUCTOR)
69 public open class TraceBase internal constructor() {
70     /**
71      * Accepts the logging [event] and appends it to the trace.
72      */
73     @OptionalJsName(TRACE_APPEND_1)
74     public open fun append(event: Any) {}
75 
76     /**
77      * Accepts the logging events [event1], [event2] and appends them to the trace.
78      */
79     @OptionalJsName(TRACE_APPEND_2)
80     public open fun append(event1: Any, event2: Any) {}
81 
82     /**
83      * Accepts the logging events [event1], [event2], [event3] and appends them to the trace.
84      */
85     @OptionalJsName(TRACE_APPEND_3)
86     public open fun append(event1: Any, event2: Any, event3: Any) {}
87 
88     /**
89      * Accepts the logging events [event1], [event2], [event3], [event4] and appends them to the trace.
90      */
91     @OptionalJsName(TRACE_APPEND_4)
92     public open fun append(event1: Any, event2: Any, event3: Any, event4: Any) {}
93 
94     /**
95      * Accepts the logging [event] and appends it to the trace.
96      */
97     @InlineOnly
98     public inline operator fun invoke(event: () -> Any) {
99         append(event())
100     }
101 
102     /**
103      * NOP tracing.
104      */
105     public object None : TraceBase()
106 }