func New0(a Any, n uint, f FuncSpectrum, p PredSpectrum, s string, port uint) *Imp { // if n == 0 { Stop(pack, 1) } // if tst { println ("fmon.New0 started for host", h) } x := new(Imp) x.object = Clone(a) x.nFuncs = n x.ch = make([]*nchan.Imp, x.nFuncs) x.f, x.p, x.s = f, p, s x.serve0 = Null x.pm = perm.New(x.nFuncs) x.isServer = host.Local(s) for i := uint(0); i < x.nFuncs; i++ { x.ch[i] = nchan.New0(x.object, s, uint16(port+i), false) if x.ch[i].IsServer() != x.isServer { Stop(pack, 2) } } if tst { print("fmon.New0 ok for ") if x.isServer { print("server ") } else { print("client ") } println(s) } return x }
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 New0(a Any, h string, p uint16, o bool) *Imp { // if str.Empty(h) || p >= 1<<16-Port0 { return nil } if a == nil { a = false } x := new(Imp) if tst { println("nchan.New0 started for host", h, "/ port", p) } x.object, x.width = Clone(a), Codelen(a) str.RemSpaces(&h) x.farHost = host.New() if !x.farHost.Defined(h) { errh.Error("Hostname "+h+" is not resolvable", 0) Stop(pack, 1) } x.isServer = host.Local(h) x.server = h x.port = Port0 + p x.oneOne = o if x.oneOne { if x.isServer { x.isServer = first(x.port) } else { x.isServer = x.farHost.Sonstewas() } } x.buf = make([]byte, x.width) // x.info = true if tst { println("nchan.New0 for host", h, "is done") } 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 }