Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 20 additions & 31 deletions src/runtime/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
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
// set new base time
sleepQueueBaseTime = now
}

// 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.
Expand Down Expand Up @@ -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
Expand Down