@@ -11,11 +11,19 @@ import (
11
11
"unsafe"
12
12
)
13
13
14
+ // Temporary scaffolding while the new timer code is added.
15
+ const oldTimers = true
16
+
14
17
// Package time knows the layout of this structure.
15
18
// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
16
19
type timer struct {
17
- tb * timersBucket // the bucket the timer lives in
18
- i int // heap index
20
+ tb * timersBucket // the bucket the timer lives in (oldTimers)
21
+ i int // heap index (oldTimers)
22
+
23
+ // If this timer is on a heap, which P's heap it is on.
24
+ // puintptr rather than *p to match uintptr in the versions
25
+ // of this struct defined in other packages. (!oldTimers)
26
+ pp puintptr
19
27
20
28
// Timer wakes up at when, and then at when+period, ... (period > 0 only)
21
29
// each time calling f(arg, now) in the timer goroutine, so f must be
@@ -25,6 +33,12 @@ type timer struct {
25
33
f func (interface {}, uintptr )
26
34
arg interface {}
27
35
seq uintptr
36
+
37
+ // What to set the when field to in timerModifiedXX status. (!oldTimers)
38
+ nextwhen int64
39
+
40
+ // The status field holds one of the values below. (!oldTimers)
41
+ status uint32
28
42
}
29
43
30
44
// timersLen is the length of timers array.
@@ -69,6 +83,84 @@ type timersBucket struct {
69
83
t []* timer
70
84
}
71
85
86
+ // Code outside this file has to be careful in using a timer value.
87
+ //
88
+ // The pp, status, and nextwhen fields may only be used by code in this file.
89
+ //
90
+ // Code that creates a new timer value can set the when, period, f,
91
+ // arg, and seq fields.
92
+ // A new timer value may be passed to addtimer (called by time.startTimer).
93
+ // After doing that no fields may be touched.
94
+ //
95
+ // An active timer (one that has been passed to addtimer) may be
96
+ // passed to deltimer (time.stopTimer), after which it is no longer an
97
+ // active timer. It is an inactive timer.
98
+ // In an inactive timer the period, f, arg, and seq fields may be modified,
99
+ // but not the when field.
100
+ // It's OK to just drop an inactive timer and let the GC collect it.
101
+ // It's not OK to pass an inactive timer to addtimer.
102
+ // Only newly allocated timer values may be passed to addtimer.
103
+ //
104
+ // An active timer may be passed to modtimer. No fields may be touched.
105
+ // It remains an active timer.
106
+ //
107
+ // An inactive timer may be passed to resettimer to turn into an
108
+ // active timer with an updated when field.
109
+ // It's OK to pass a newly allocated timer value to resettimer.
110
+ //
111
+ // Timer operations are addtimer, deltimer, modtimer, resettimer,
112
+ // cleantimers, adjusttimers, and runtimer.
113
+ //
114
+ // We don't permit calling addtimer/deltimer/modtimer/resettimer simultaneously,
115
+ // but adjusttimers and runtimer can be called at the same time as any of those.
116
+ //
117
+ // Active timers live in heaps attached to P, in the timers field.
118
+ // Inactive timers live there too temporarily, until they are removed.
119
+
120
+ // Values for the timer status field.
121
+ const (
122
+ // Timer has no status set yet.
123
+ timerNoStatus = iota
124
+
125
+ // Waiting for timer to fire.
126
+ // The timer is in some P's heap.
127
+ timerWaiting
128
+
129
+ // Running the timer function.
130
+ // A timer will only have this status briefly.
131
+ timerRunning
132
+
133
+ // The timer is deleted and should be removed.
134
+ // It should not be run, but it is still in some P's heap.
135
+ timerDeleted
136
+
137
+ // The timer is being removed.
138
+ // The timer will only have this status briefly.
139
+ timerRemoving
140
+
141
+ // The timer has been stopped.
142
+ // It is not in any P's heap.
143
+ timerRemoved
144
+
145
+ // The timer is being modified.
146
+ // The timer will only have this status briefly.
147
+ timerModifying
148
+
149
+ // The timer has been modified to an earlier time.
150
+ // The new when value is in the nextwhen field.
151
+ // The timer is in some P's heap, possibly in the wrong place.
152
+ timerModifiedEarlier
153
+
154
+ // The timer has been modified to the same or a later time.
155
+ // The new when value is in the nextwhen field.
156
+ // The timer is in some P's heap, possibly in the wrong place.
157
+ timerModifiedLater
158
+
159
+ // The timer has been modified and is being moved.
160
+ // The timer will only have this status briefly.
161
+ timerMoving
162
+ )
163
+
72
164
// Package time APIs.
73
165
// Godoc uses the comments in package time, not these.
74
166
@@ -77,6 +169,14 @@ type timersBucket struct {
77
169
// timeSleep puts the current goroutine to sleep for at least ns nanoseconds.
78
170
//go:linkname timeSleep time.Sleep
79
171
func timeSleep (ns int64 ) {
172
+ if oldTimers {
173
+ timeSleepOld (ns )
174
+ return
175
+ }
176
+ throw ("new timeSleep not yet implemented" )
177
+ }
178
+
179
+ func timeSleepOld (ns int64 ) {
80
180
if ns <= 0 {
81
181
return
82
182
}
@@ -97,7 +197,7 @@ func timeSleep(ns int64) {
97
197
unlock (& tb .lock )
98
198
badTimer ()
99
199
}
100
- goparkunlock (& tb .lock , waitReasonSleep , traceEvGoSleep , 2 )
200
+ goparkunlock (& tb .lock , waitReasonSleep , traceEvGoSleep , 3 )
101
201
}
102
202
103
203
// startTimer adds t to the timer heap.
@@ -133,6 +233,14 @@ func goroutineReady(arg interface{}, seq uintptr) {
133
233
}
134
234
135
235
func addtimer (t * timer ) {
236
+ if oldTimers {
237
+ addtimerOld (t )
238
+ return
239
+ }
240
+ throw ("new addtimer not yet implemented" )
241
+ }
242
+
243
+ func addtimerOld (t * timer ) {
136
244
tb := t .assignBucket ()
137
245
lock (& tb .lock )
138
246
ok := tb .addtimerLocked (t )
@@ -179,6 +287,14 @@ func (tb *timersBucket) addtimerLocked(t *timer) bool {
179
287
// Delete timer t from the heap.
180
288
// Do not need to update the timerproc: if it wakes up early, no big deal.
181
289
func deltimer (t * timer ) bool {
290
+ if oldTimers {
291
+ return deltimerOld (t )
292
+ }
293
+ throw ("no deltimer not yet implemented" )
294
+ return false
295
+ }
296
+
297
+ func deltimerOld (t * timer ) bool {
182
298
if t .tb == nil {
183
299
// t.tb can be nil if the user created a timer
184
300
// directly, without invoking startTimer e.g
@@ -227,6 +343,14 @@ func (tb *timersBucket) deltimerLocked(t *timer) (removed, ok bool) {
227
343
}
228
344
229
345
func modtimer (t * timer , when , period int64 , f func (interface {}, uintptr ), arg interface {}, seq uintptr ) {
346
+ if oldTimers {
347
+ modtimerOld (t , when , period , f , arg , seq )
348
+ return
349
+ }
350
+ throw ("new modtimer not yet implemented" )
351
+ }
352
+
353
+ func modtimerOld (t * timer , when , period int64 , f func (interface {}, uintptr ), arg interface {}, seq uintptr ) {
230
354
tb := t .tb
231
355
232
356
lock (& tb .lock )
@@ -250,6 +374,14 @@ func modtimer(t *timer, when, period int64, f func(interface{}, uintptr), arg in
250
374
// This should be called instead of addtimer if the timer value has been,
251
375
// or may have been, used previously.
252
376
func resettimer (t * timer , when int64 ) {
377
+ if oldTimers {
378
+ resettimerOld (t , when )
379
+ return
380
+ }
381
+ throw ("new resettimer not yet implemented" )
382
+ }
383
+
384
+ func resettimerOld (t * timer , when int64 ) {
253
385
t .when = when
254
386
addtimer (t )
255
387
}
0 commit comments