# HG changeset patch # User Akshat Kumar # Date 1327700714 0 # Node ID 35f5add268d315f5d2e9dcfaf493411a0775c924 # Parent 65307256b5257902153f11edd174638b14e15b6d nix: tsemacquire. Forked a tsemacquire from semacquire, leaving semacquire unchanged. "For testing purposes only." R=nix-dev, john, rminnich, nemo, ality CC=nix-dev http://codereview.appspot.com/5569056 Committer: John Floren diff -r 65307256b525 -r 35f5add268d3 sys/include/libc.h --- a/sys/include/libc.h Fri Jan 27 18:54:26 2012 +0100 +++ b/sys/include/libc.h Fri Jan 27 21:45:14 2012 +0000 @@ -683,6 +683,7 @@ extern long semrelease(long*, long); extern int sleep(long); extern int stat(char*, uchar*, int); +extern int tsemacquire(long*, ulong); extern Waitmsg* wait(void); extern int waitpid(void); extern long write(int, void*, long); diff -r 65307256b525 -r 35f5add268d3 sys/src/libc/9syscall/sys.h --- a/sys/src/libc/9syscall/sys.h Fri Jan 27 18:54:26 2012 +0100 +++ b/sys/src/libc/9syscall/sys.h Fri Jan 27 21:45:14 2012 +0000 @@ -56,4 +56,4 @@ #define ZIOPREAD 57 #define ZIOPWRITE 58 #define ZIOFREE 59 - +#define TSEMACQUIRE 60 diff -r 65307256b525 -r 35f5add268d3 sys/src/nix/port/syscallfmt.c --- a/sys/src/nix/port/syscallfmt.c Fri Jan 27 18:54:26 2012 +0100 +++ b/sys/src/nix/port/syscallfmt.c Fri Jan 27 21:45:14 2012 +0000 @@ -247,6 +247,11 @@ i[0] = va_arg(list, int); fmtprint(&fmt, "%#p %d", v, i[0]); break; + case TSEMACQUIRE: + v = va_arg(list, int*); + l = va_arg(list, ulong); + fmtprint(&fmt, "%#p %ld", v, l); + break; case SEMSLEEP: case SEMWAKEUP: v = va_arg(list, int*); diff -r 65307256b525 -r 35f5add268d3 sys/src/nix/port/sysproc.c --- a/sys/src/nix/port/sysproc.c Fri Jan 27 18:54:26 2012 +0100 +++ b/sys/src/nix/port/sysproc.c Fri Jan 27 21:45:14 2012 +0000 @@ -1185,13 +1185,59 @@ sleep(&phore, semawoke, &phore); poperror(); } + semdequeue(s, &phore); + coherence(); /* not strictly necessary due to lock in semdequeue */ + if(!phore.waiting) + semwakeup(s, addr, 1); + if(!acquired) + nexterror(); + return 1; +} + +/* Acquire semaphore or time-out */ +static int +tsemacquire(Segment* s, int* addr, ulong ms) +{ + int acquired; + Sema phore; + int timedout; + ulong t; + + if(canacquire(addr)) + return 1; + if(ms == 0) + return 0; + + acquired = 0; + timedout = 0; + semqueue(s, addr, &phore); + for(;;){ + phore.waiting = 1; + coherence(); + if(canacquire(addr)){ + acquired = 1; + break; + } + if(waserror()) + break; + t = m->ticks; + tsleep(&phore, semawoke, &phore, ms); + if(TK2MS(m->ticks-t) >= ms) { + timedout = 1; + poperror(); + break; + } + ms -= TK2MS(m->ticks-t); + poperror(); + } semdequeue(s, &phore); coherence(); /* not strictly necessary due to lock in semdequeue */ if(!phore.waiting) semwakeup(s, addr, 1); + if(timedout) + return 0; if(!acquired) nexterror(); - return 1; } @@ -1220,6 +1266,30 @@ } void +systsemacquire(Ar0* ar0, va_list list) +{ + Segment *s; + int *addr, ms; + + /* + * int semacquire(long* addr, int block); + * should be (and will be implemented below as) perhaps + * int semacquire(int* addr, int block); + */ + addr = va_arg(list, int*); + addr = validaddr(addr, sizeof(int), 1); + evenaddr(PTR2UINT(addr)); + ms = va_arg(list, int); + + if((s = seg(up, PTR2UINT(addr), 0)) == nil) + error(Ebadarg); + if(*addr < 0) + error(Ebadarg); + + ar0->i = tsemacquire(s, addr, ms); +} + +void syssemrelease(Ar0* ar0, va_list list) { Segment *s; diff -r 65307256b525 -r 35f5add268d3 sys/src/nix/port/systab.c --- a/sys/src/nix/port/systab.c Fri Jan 27 18:54:26 2012 +0100 +++ b/sys/src/nix/port/systab.c Fri Jan 27 21:45:14 2012 +0000 @@ -64,6 +64,7 @@ extern void sysziopread(Ar0*, va_list); extern void sysziopwrite(Ar0*, va_list); extern void sysziofree(Ar0*, va_list); +extern void systsemacquire(Ar0*, va_list); struct { char* n; void (*f)(Ar0*, va_list); @@ -127,6 +128,7 @@ [ZIOPREAD] { "Ziopread", sysziopread, { .l = -1 } }, [ZIOPWRITE] { "Ziopwrite", sysziopwrite, { .l = -1 } }, [ZIOFREE] { "Ziofree", sysziofree, { .i = -1 } }, + [TSEMACQUIRE] { "Tsemacquire", systsemacquire, { .i = -1 } }, }; int nsyscall = nelem(systab);