Browse Source

Get rid of optimistic semaphores.

They never worked, according to Nemo. Cool idea though.

Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Ronald G. Minnich 7 years ago
parent
commit
8ca6a76eaa
3 changed files with 0 additions and 336 deletions
  1. 0 1
      sys/src/9/amd64/BUILD
  2. 0 1
      sys/src/9/port/port.json
  3. 0 334
      sys/src/9/port/syssem.c

+ 0 - 1
sys/src/9/amd64/BUILD

@@ -108,7 +108,6 @@ PORT_SRCS = [
 	"//sys/src/9/port/sysfile.c",
 	"//sys/src/9/port/sysproc.c",
 	"//sys/src/9/port/sysseg.c",
-	"//sys/src/9/port/syssem.c",
 	"//sys/src/9/port/syszio.c",
 	"//sys/src/9/port/taslock.c",
 	"//sys/src/9/port/tod.c",

+ 0 - 1
sys/src/9/port/port.json

@@ -73,7 +73,6 @@
 			"../port/sysfile.c",
 			"../port/sysproc.c",
 			"../port/sysseg.c",
-			"../port/syssem.c",
 			"../port/syszio.c",
 			"../port/taslock.c",
 			"../port/tod.c",

+ 0 - 334
sys/src/9/port/syssem.c

@@ -1,334 +0,0 @@
-/*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
-
-#include	"u.h"
-#include	"../port/lib.h"
-#include	"mem.h"
-#include	"dat.h"
-#include	"fns.h"
-#include	"../port/error.h"
-
-static int semtrytimes = 100;
-
-
-/*
- * Support for user-level optimistic semaphores.
- *
- * A semaphore is an integer n.
- * If n > 0, there are tickets
- * If n == 0, there are no tickets
- * If n < 0, there are |n| processes waiting for tickets
- * or preparing to wait for tickets.
- *
- * CAUTION: Do not use adec/ainc for semaphores, they would
- * trap if the integer is negative, but that's ok for semaphores.
- */
-
-
-static void
-semwakeup(Sem *s, int didwake, int dolock)
-{
-	Proc *up = externup();
-	Proc *p;
-
-	DBG("semwakeup up %#p sem %#p\n", up, s->np);
-	if(dolock)
-		lock(&s->l);
-	/*
-	 * If there are more processes sleeping than |*s->np| then
-	 * there are ups not yet seen by sleepers, wake up those that
-	 * have tickets.
-	 */
-	while(s->nq > 0 && s->nq > - *s->np){
-		p = s->q[0];
-		s->nq--;
-		s->q[0] = s->q[s->nq];
-		if(didwake){
-			DBG("semwakeup up %#p waking up %#p\n", up, p);
-			p->waitsem = s;
-			/*
-			 * p can be up if it's being killed, in which
-			 * case it might be consuming a ticket being
-			 * put while dying. In that case, another
-			 * process might wait because we would get the
-			 * ticket. Up must call semwakeup to be sure
-			 * that other process no longer sleeps.
-			 * But we can't be put in the scheduler queue.
-			 */
-			if(p != up)
-				ready(p);
-		}
-	}
-	if(dolock)
-		unlock(&s->l);
-}
-
-static void
-semsleep(Sem *s, int dontblock)
-{
-	Proc *up = externup();
-	DBG("semsleep up %#p sem %#p\n", up, s->np);
-	if(dontblock){
-		/*
-		 * User tried to down non-blocking, but someone else
-		 * got the ticket between looking at n and adec(n).
-		 * we have to safely undo our temporary down here.
-		 * Adjust the value of the semaphore to reflect that we
-		 * wanted a ticket for a while but no longer want one.
-		 * Make sure that no other process is waiting because we
-		 * made a temporary down.
-		 */
-		semainc(s->np);
-		semwakeup(s, 1, 1);
-		return;
-	}
-	lock(&s->l);
-	if(*s->np >= 0){
-		/*
-		 * A ticket came, either it came while calling the kernel,
-		 * or it was a temporary sleep that didn't block.
-		 * Either way, we are done.
-		 */
-		unlock(&s->l);
-		goto Done;
-	}
-	/*
-	 * Commited to wait, we'll have to wait until
-	 * some other process changes our state.
-	 */
-	s->q = realloc(s->q, (s->nq+1) * sizeof s->q[0]);
-	if(s->q == nil)
-		panic("semsleep: no memory");
-	s->q[s->nq++] = up;
-	up->waitsem = nil;
-	up->state = Semdown;
-	unlock(&s->l);
-	DBG("semsleep up %#p blocked\n", up);
-	sched();
-Done:
-	DBG("semsleep up %#p awaken\n", up);
-	if(up->waitsem == nil){
-		/*
-		 * nobody did awake us, we are probably being
-		 * killed; we no longer want a ticket.
-		 */
-		lock(&s->l);
-		semainc(s->np);	/* we are no longer waiting; killed */
-		semwakeup(s, 1, 0);
-		unlock(&s->l);
-	}
-}
-
-void
-syssemsleep(Ar0* ar0, ...)
-{
-	Proc *up = externup();
-	int *np;
-	int dontblock;
-	Sem *s;
-	Segment *sg;
-	va_list list;
-	va_start(list, ar0);
-
-	/*
-	 * void semsleep(int*);
-	 */
-	np = va_arg(list, int*);
-	np = validaddr(np, sizeof *np, 1);
-	evenaddr(PTR2UINT(np));
-	dontblock = va_arg(list, int);
-	if((sg = seg(up, PTR2UINT(np), 0)) == nil)
-		error(Ebadarg);
-	s = segmksem(sg, np);
-	semsleep(s, dontblock);
-	va_end(list);
-}
-
-void
-syssemwakeup(Ar0* ar0, ...)
-{
-	Proc *up = externup();
-	int *np;
-	Sem *s;
-	Segment *sg;
-	va_list list;
-	va_start(list, ar0);
-
-	/*
-	 * void semwakeup(int*);
-	 */
-	np = va_arg(list, int*);
-	np = validaddr(np, sizeof *np, 1);
-	evenaddr(PTR2UINT(np));
-	if((sg = seg(up, PTR2UINT(np), 0)) == nil)
-		error(Ebadarg);
-	s = segmksem(sg, np);
-	semwakeup(s, 1, 1);
-	va_end(list);
-}
-
-static void
-semdequeue(Sem *s)
-{
-	Proc *up = externup();
-	int i;
-
-	assert(s != nil);
-	lock(&s->l);
-	for(i = 0; i < s->nq; i++)
-		if(s->q[i] == up)
-			break;
-
-	if(i == s->nq){
-		/*
-		 * We didn't perform a down on s, yet we are no longer queued
-		 * on it; it must be because someone gave us its
-		 * ticket in the mean while. We must put it back.
-		 */
-		semainc(s->np);
-		semwakeup(s, 0, 0);
-	}else{
-		s->nq--;
-		s->q[i] = s->q[s->nq];
-	}
-	unlock(&s->l);
-}
-
-/*
- * Alternative down of a Sem in ss[].
- * The logic is similar to multiple downs, see comments in semsleep().
- */
-static int
-semalt(Sem *ss[], int n)
-{
-	Proc *up = externup();
-	int i, j, r;
-	Sem *s;
-
-	DBG("semalt up %#p ss[0] %#p\n", up, ss[0]->np);
-	r = -1;
-	for(i = 0; i < n; i++){
-		s = ss[i];
-		n = semadec(s->np);
-		if(n >= 0){
-			r = i;
-			goto Done;
-		}
-		lock(&s->l);
-		s->q = realloc(s->q, (s->nq+1) * sizeof s->q[0]);
-		if(s->q == nil)
-			panic("semalt: not enough memory");
-		s->q[s->nq++] = up;
-		unlock(&s->l);
-	}
-
-	DBG("semalt up %#p blocked\n", up);
-	up->state = Semdown;
-	sched();
-
-Done:
-	DBG("semalt up %#p awaken\n", up);
-	for(j = 0; j < i; j++){
-		assert(ss[j] != nil);
-		if(ss[j] != up->waitsem)
-			semdequeue(ss[j]);
-		else
-			r = j;
-	}
-	if(r < 0)
-		panic("semalt");
-	return r;
-}
-
-void
-syssemalt(Ar0 *ar0, ...)
-{
-	Proc *up = externup();
-	int **sl;
-	int i, *np, ns;
-	Segment *sg;
-	Sem *ksl[16];
-	va_list list;
-	va_start(list, ar0);
-
-	/*
-	 * void semalt(int*[], int);
-	 */
-	ar0->i = -1;
-	sl = va_arg(list, int**);
-	ns = va_arg(list, int);
-	sl = validaddr(sl, ns * sizeof(int*), 1);
-	if(ns > nelem(ksl))
-		panic("syssemalt: bug: too many semaphores in alt");
-	for(i = 0; i < ns; i++){
-		np = sl[i];
-		np = validaddr(np, sizeof(int), 1);
-		evenaddr(PTR2UINT(np));
-		if((sg = seg(up, PTR2UINT(np), 0)) == nil)
-			error(Ebadarg);
-		ksl[i] = segmksem(sg, np);
-	}
-	ar0->i = semalt(ksl, ns);
-	va_end(list);
-}
-
-/*
- * These are the entry points from the C library, adapted
- * for use within the kernel, so that kprocs may share sems
- * with users.
- * They must be run in a process context.
- * Within the kernel, semaphores are used through their
- * kernel Sem structures, and not directly by their int* value.
- * Otherwise, we would have to look up each time they are used.
- */
-
-void
-upsem(Sem *s)
-{
-	int n;
-
-	n = semainc(s->np);
-	if(n <= 0)
-		semwakeup(s, 1, 1);
-}
-
-int
-downsem(Sem *s, int dontblock)
-{
-	int n, i;
-
-	for(i = 0; *s->np <= 0 && i < semtrytimes; i++)
-		yield();
-	if(*s->np <= 0 && dontblock)
-		return -1;
-	n = semadec(s->np);
-	if(n < 0)
-		semsleep(s, dontblock);
-	return 0;
-}
-
-int
-altsems(Sem *ss[], int n)
-{
-	int i, w;
-
-	/* busy wait */
-	for(w = 0; w < semtrytimes; w++){
-		for(i = 0; i < n; i++)
-			if(*ss[i]->np > 0)
-				break;
-		if(i < n)
-			break;
-	}
-	for(i = 0; i < n; i++)
-		if(downsem(ss[i], 1) != -1)
-			return i;
-	return semalt(ss, n);
-}
-