diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-29 20:26:49 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2012-07-29 20:26:49 +0200 |
commit | 49ac0b93d3a4652e0bda07d7654c9ffb7c3fb004 (patch) | |
tree | ade14ef73f153a107fe17b9258f6859977d1c096 /sys | |
parent | 780d393e4b15751df69a1af8f84705270621be25 (diff) |
add tsemacquire syscall for go
Diffstat (limited to 'sys')
-rw-r--r-- | sys/include/libc.h | 1 | ||||
-rw-r--r-- | sys/src/9/port/sysproc.c | 63 | ||||
-rw-r--r-- | sys/src/9/port/systab.h | 3 | ||||
-rw-r--r-- | sys/src/libc/9syscall/sys.h | 1 |
4 files changed, 68 insertions, 0 deletions
diff --git a/sys/include/libc.h b/sys/include/libc.h index 2c4f3b428..041066dd7 100644 --- a/sys/include/libc.h +++ b/sys/include/libc.h @@ -670,6 +670,7 @@ extern int semacquire(long*, int); 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 --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c index 93785ceb8..5844ff549 100644 --- a/sys/src/9/port/sysproc.c +++ b/sys/src/9/port/sysproc.c @@ -1034,6 +1034,50 @@ semacquire(Segment *s, long *addr, int block) return 1; } +/* Acquire semaphore or time-out */ +static int +tsemacquire(Segment *s, long *addr, ulong ms) +{ + int acquired, timedout; + ulong t, elms; + Sema phore; + + if(canacquire(addr)) + return 1; + if(ms == 0) + return 0; + acquired = 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); + elms = TK2MS(m->ticks - t); + poperror(); + if(elms >= ms){ + timedout = 1; + break; + } + ms -= elms; + } + 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; +} + long syssemacquire(ulong *arg) { @@ -1054,6 +1098,25 @@ syssemacquire(ulong *arg) } long +systsemacquire(ulong *arg) +{ + long *addr; + ulong ms; + Segment *s; + + validaddr(arg[0], sizeof(long), 1); + evenaddr(arg[0]); + addr = (long*)arg[0]; + ms = arg[1]; + + if((s = seg(up, (ulong)addr, 0)) == nil) + error(Ebadarg); + if(*addr < 0) + error(Ebadarg); + return tsemacquire(s, addr, ms); +} + +long syssemrelease(ulong *arg) { long *addr, delta; diff --git a/sys/src/9/port/systab.h b/sys/src/9/port/systab.h index 3cf5beef7..c80b55508 100644 --- a/sys/src/9/port/systab.h +++ b/sys/src/9/port/systab.h @@ -52,6 +52,7 @@ Syscall sysmount; Syscall sysawait; Syscall syspread; Syscall syspwrite; +Syscall systsemacquire; Syscall sysdeath; Syscall *systab[]={ @@ -105,6 +106,7 @@ Syscall *systab[]={ [AWAIT] sysawait, [PREAD] syspread, [PWRITE] syspwrite, + [TSEMACQUIRE] systsemacquire, }; char *sysctab[]={ @@ -158,6 +160,7 @@ char *sysctab[]={ [AWAIT] "Await", [PREAD] "Pread", [PWRITE] "Pwrite", + [TSEMACQUIRE] "Tsemacquire", }; int nsyscall = (sizeof systab/sizeof systab[0]); diff --git a/sys/src/libc/9syscall/sys.h b/sys/src/libc/9syscall/sys.h index 105baf89c..fcc274799 100644 --- a/sys/src/libc/9syscall/sys.h +++ b/sys/src/libc/9syscall/sys.h @@ -48,3 +48,4 @@ #define AWAIT 47 #define PREAD 50 #define PWRITE 51 +#define TSEMACQUIRE 52 |