-
Notifications
You must be signed in to change notification settings - Fork 1
/
slow-detector-invocation.go
80 lines (70 loc) · 1.86 KB
/
slow-detector-invocation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
© 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import (
"strconv"
"sync/atomic"
"time"
"unsafe"
)
// SlowDetectorInvocation is a container used by SlowDetectorCore
type SlowDetectorInvocation struct {
sID slowID
threadID ThreadID
invoLabel string
t0 time.Time
stop func(sdi *SlowDetectorInvocation, value ...time.Time)
sd *SlowDetectorCore
tx AtomicReference[time.Time]
intervals []Interval
}
type Interval struct {
label string
t time.Time
}
// Stop ends an invocation part of SlowDetectorCore
func (sdi *SlowDetectorInvocation) Stop(value ...time.Time) {
sdi.stop(sdi, value...)
}
// Stop ends an invocation part of SlowDetectorCore
func (sdi *SlowDetectorInvocation) Interval(label string, t ...time.Time) {
if label == "" {
label = strconv.Itoa(len(sdi.intervals) + 1)
}
var t0 time.Time
if len(t) > 0 {
t0 = t[0]
}
if t0.IsZero() {
t0 = time.Now()
}
sdi.intervals = append(sdi.intervals, Interval{label: label, t: t0})
}
// ThreadID returns the thread ID dor the thread invoking Start
func (sdi *SlowDetectorInvocation) ThreadID() (threadID ThreadID) {
return sdi.threadID
}
// T0 returns the effective time of the invocation of Start
func (sdi *SlowDetectorInvocation) T0() (t0 time.Time) {
return sdi.t0
}
// Label returns the label for this invocation
func (sdi *SlowDetectorInvocation) Label() (label string) {
return sdi.invoLabel
}
// T0 returns the effective time of the invocation of Start
func (sdi *SlowDetectorInvocation) Time(t time.Time) (previousT time.Time) {
addr := (*unsafe.Pointer)(unsafe.Pointer(&sdi.tx))
var tp *time.Time
if t.IsZero() {
tp = (*time.Time)(atomic.LoadPointer(addr))
} else {
tp = (*time.Time)(atomic.SwapPointer(addr, unsafe.Pointer(&t)))
}
if tp != nil {
previousT = *tp
}
return
}