fix sleep queue corruption bug
Этот коммит содержится в:
родитель
8a5fa51f60
коммит
a718b10502
1 изменённых файлов: 20 добавлений и 31 удалений
|
@ -133,42 +133,28 @@ func addSleepTask(t *task) {
|
|||
now := ticks()
|
||||
if sleepQueue == nil {
|
||||
scheduleLog(" -> sleep new queue")
|
||||
// Create new linked list for the sleep queue.
|
||||
sleepQueue = t
|
||||
|
||||
// set new base time
|
||||
sleepQueueBaseTime = now
|
||||
return
|
||||
}
|
||||
|
||||
// Make sure state.data is relative to the queue time base.
|
||||
state := t.state()
|
||||
|
||||
// Insert at front of sleep queue.
|
||||
if state.data < sleepQueue.state().data {
|
||||
scheduleLog(" -> sleep at start")
|
||||
sleepQueue.state().data -= state.data
|
||||
state.next = sleepQueue
|
||||
sleepQueue = t
|
||||
return
|
||||
}
|
||||
|
||||
// Add to sleep queue (in the middle or at the end).
|
||||
queueIndex := sleepQueue
|
||||
for {
|
||||
state.data -= queueIndex.state().data
|
||||
if queueIndex.state().next == nil || queueIndex.state().data > state.data {
|
||||
if queueIndex.state().next == nil {
|
||||
scheduleLog(" -> sleep at end")
|
||||
state.next = nil
|
||||
} else {
|
||||
scheduleLog(" -> sleep in middle")
|
||||
state.next = queueIndex.state().next
|
||||
state.next.state().data -= state.data
|
||||
}
|
||||
queueIndex.state().next = t
|
||||
// Add to sleep queue.
|
||||
q := &sleepQueue
|
||||
for ; *q != nil; q = &((*q).state()).next {
|
||||
if t.state().data < (*q).state().data {
|
||||
// this will finish earlier than the next - insert here
|
||||
break
|
||||
} else {
|
||||
// this will finish later - adjust delay
|
||||
t.state().data -= (*q).state().data
|
||||
}
|
||||
queueIndex = queueIndex.state().next
|
||||
}
|
||||
if *q != nil {
|
||||
// cut delay time between this sleep task and the next
|
||||
(*q).state().data -= t.state().data
|
||||
}
|
||||
t.state().next = *q
|
||||
*q = t
|
||||
}
|
||||
|
||||
// Run the scheduler until all tasks have finished.
|
||||
|
@ -204,8 +190,11 @@ func scheduler() {
|
|||
timeLeft := timeUnit(sleepQueue.state().data) - (now - sleepQueueBaseTime)
|
||||
if schedulerDebug {
|
||||
println(" sleeping...", sleepQueue, uint(timeLeft))
|
||||
for t := sleepQueue; t != nil; t = t.state().next {
|
||||
println(" task sleeping:", t, timeUnit(t.state().data))
|
||||
}
|
||||
}
|
||||
sleepTicks(timeUnit(timeLeft))
|
||||
sleepTicks(timeLeft)
|
||||
if asyncScheduler {
|
||||
// The sleepTicks function above only sets a timeout at which
|
||||
// point the scheduler will be called again. It does not really
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче