github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/src/runtime/slqueue.go (about) 1 package runtime 2 3 type slqueue struct { 4 m mutex 5 head sguintptr 6 tail sguintptr 7 size uint64 8 } 9 10 //go:nosplit 11 //go:nowritebarrier 12 func slqget(q *slqueue, locked bool) (*sudog, *sudog, int) { 13 if !locked { 14 MarkNoFutex() 15 lock(&q.m) 16 MarkFutex() 17 } 18 head, tail, size := q.head, q.tail, q.size 19 q.head, q.tail, q.size = 0, 0, 0 20 if !locked { 21 unlock(&q.m) 22 } 23 if size == 1 && head != tail { 24 throw("slqueue: head != tail for size 1.") 25 } 26 return head.ptr(), tail.ptr(), int(size) 27 } 28 29 //go:nosplit 30 //go:nowritebarrier 31 func slqput(q *slqueue, elem *sudog) { 32 var tail *sudog = elem 33 var size uint64 = 1 34 for tail.schednext != 0 { 35 // Just going through the list to find the tail 36 size++ 37 tail = tail.schednext.ptr() 38 } 39 if tail == nil { 40 throw("slqueue tail is nil...") 41 } 42 MarkNoFutex() 43 lock(&q.m) 44 MarkFutex() 45 if q.tail == 0 { 46 if q.head != 0 || q.size != 0 { 47 throw("Malformed slqueue: the head is not nil, but tail is") 48 } 49 q.head.set(elem) 50 } else { 51 q.tail.ptr().schednext.set(elem) 52 } 53 q.tail.set(tail) 54 q.size += size 55 unlock(&q.m) 56 }