예제 #1
0
파일: imp.go 프로젝트: CaptainSoOmA/Uni
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
}
예제 #2
0
파일: impr.go 프로젝트: CaptainSoOmA/Uni
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
}
예제 #3
0
파일: imp.go 프로젝트: CaptainSoOmA/Uni
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
}
예제 #4
0
파일: imp.go 프로젝트: CaptainSoOmA/Uni
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
}