Beispiel #1
0
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
}
Beispiel #2
0
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
}