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