refactor coroutine lowering and tasks

This commit is contained in:
Jaden Weiss
2020-01-03 00:23:37 -05:00
committed by Ayke
parent 2521cacb51
commit 6a50f25a48
40 changed files with 1830 additions and 1515 deletions
+98
View File
@@ -0,0 +1,98 @@
package task
const asserts = false
// Queue is a FIFO container of tasks.
// The zero value is an empty queue.
type Queue struct {
head, tail *Task
}
// Push a task onto the queue.
func (q *Queue) Push(t *Task) {
if asserts && t.Next != nil {
panic("runtime: pushing a task to a queue with a non-nil Next pointer")
}
if q.tail != nil {
q.tail.Next = t
}
q.tail = t
t.Next = nil
if q.head == nil {
q.head = t
}
}
// Pop a task off of the queue.
func (q *Queue) Pop() *Task {
t := q.head
if t == nil {
return nil
}
q.head = t.Next
if q.tail == t {
q.tail = nil
}
t.Next = nil
return t
}
// Append pops the contents of another queue and pushes them onto the end of this queue.
func (q *Queue) Append(other *Queue) {
if q.head == nil {
q.head = other.head
} else {
q.tail.Next = other.head
}
q.tail = other.tail
other.head, other.tail = nil, nil
}
// Stack is a LIFO container of tasks.
// The zero value is an empty stack.
// This is slightly cheaper than a queue, so it can be preferable when strict ordering is not necessary.
type Stack struct {
top *Task
}
// Push a task onto the stack.
func (s *Stack) Push(t *Task) {
if asserts && t.Next != nil {
panic("runtime: pushing a task to a stack with a non-nil Next pointer")
}
s.top, t.Next = t, s.top
}
// Pop a task off of the stack.
func (s *Stack) Pop() *Task {
t := s.top
if t != nil {
s.top = t.Next
}
t.Next = nil
return t
}
// tail follows the chain of tasks.
// If t is nil, returns nil.
// Otherwise, returns the task in the chain where the Next field is nil.
func (t *Task) tail() *Task {
if t == nil {
return nil
}
for t.Next != nil {
t = t.Next
}
return t
}
// Queue moves the contents of the stack into a queue.
// Elements can be popped from the queue in the same order that they would be popped from the stack.
func (s *Stack) Queue() Queue {
head := s.top
s.top = nil
return Queue{
head: head,
tail: head.tail(),
}
}