Hi there,

The work-stealing implementation of the scheduler is lock-free and uses 
load-acquire store-release (proc.go). I can understand part of the 
implementation, but I have some questions. 

1. runqgrab function: why does it need the atomic load of runqtail? From 
comments, I know it is used to synchronize with the producer. But how? Does 
it synchronize with the runqget?
2. runqsteal function: why doesn't it use the atomic load of runqtail?

I am learning the load-acquire store-release concept, and I am still 
confused with this part of the implementation.

Thank you in advance.

func runqgrab(_p_ *p, batch *[256]guintptr, batchHead uint32, stealRunNextG 
bool) uint32 {

        for {

                h := atomic.Load(&_p_.runqhead) // load-acquire, synchronize 
with other consumers

                t := atomic.Load(&_p_.runqtail) // load-acquire, synchronize 
with the producer
                ...

                
                if atomic.Cas(&_p_.runqhead, h, h+n) { // cas-release, commits 
consume
                        return n
                }
             }
}


func runqsteal(_p_, p2 *p, stealRunNextG bool) *g {
        t := _p_.runqtail
        n := runqgrab(p2, &_p_.runq, t, stealRunNextG)
        ...
        h := atomic.Load(&_p_.runqhead) // load-acquire, synchronize with 
consumers
        if t-h+n >= uint32(len(_p_.runq)) {
                throw("runqsteal: runq overflow")
        }
        atomic.Store(&_p_.runqtail, t+n) // store-release, makes the item 
available for consumption
        return gp
}







-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to