func NewR(h []*host.Imp, p []uint) *ImpR { // n := uint(len(h)) if n == 0 { ker.Panic("dlock.NewR for n == 0") } me := uint(0) for i := uint(0); i < n; i++ { if host.Local(h[i].String()) { me = i } } k := (me + n - 1) / n in := nchan.New(false, h[k].String(), uint16(p[k]), true) k = (me + 1) / n out := nchan.New(false, h[k].String(), uint16(p[k]), true) x := new(ImpR) x.entry.Lock() x.exit.Lock() go func() { for { if halt { break } in.Recv() if x.crit { x.entry.Unlock() x.exit.Lock() } out.Send(true) } in.Terminate() out.Terminate() }() if me == 0 { out.Send(true) } return x }
func New(H []string) *Imp { // if len(H) < 2 { return nil } x := new(Imp) x.n = uint(len(H)) x.deferred = make([]bool, x.n) x.host = make([]string, x.n) for h := zero; h < x.n; h++ { if h > 0 { for i := zero; i < x.n; i++ { if H[h] == x.host[i] { return nil } } } x.host[h] = H[h] if host.Local(x.host[h]) { x.me = h } } x.critSect.Lock() x.request = make([][]*nchan.Imp, x.n) x.reply = make([][]*nchan.Imp, x.n) for i := zero; i < x.n; i++ { x.request[i] = make([]*nchan.Imp, x.n) x.reply[i] = make([]*nchan.Imp, x.n) } partner := "" for h := zero; h < x.n; h++ { for i := zero; i < x.n; i++ { if h != i && (x.me == h || x.me == i) { if x.me == h { partner = x.host[i] } else { // me == i partner = x.host[h] } k := uint16((nFLocks*x.n*x.n+h)*x.n + i) x.request[h][i] = nchan.New(x.ownTime, partner, k, true) x.reply[h][i] = nchan.New(x.ownTime, partner, k+uint16(x.n*x.n), true) } } } for h := zero; h < x.n; h++ { if h != x.me { go func(i uint) { // bookkeeping of request for !terminated { otherTime := x.request[i][x.me].Recv().(uint) x.mutex.Lock() if otherTime > x.time { x.time = otherTime } if x.requesting && (x.ownTime < otherTime || (x.ownTime == otherTime && x.me < i)) { x.deferred[i] = true } else { x.reply[x.me][i].Send(ok) } x.mutex.Unlock() } done <- true }(h) go func(i uint) { // bookkeeping of ok-replies for !terminated { _ = x.reply[i][x.me].Recv().(uint) x.mutex.Lock() x.noReplies++ if x.noReplies == x.n-1 { x.critSect.Unlock() } x.mutex.Unlock() } done <- true }(h) } } nFLocks++ return x }