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