summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-07-29 20:26:49 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-07-29 20:26:49 +0200
commit49ac0b93d3a4652e0bda07d7654c9ffb7c3fb004 (patch)
treeade14ef73f153a107fe17b9258f6859977d1c096 /sys
parent780d393e4b15751df69a1af8f84705270621be25 (diff)
add tsemacquire syscall for go
Diffstat (limited to 'sys')
-rw-r--r--sys/include/libc.h1
-rw-r--r--sys/src/9/port/sysproc.c63
-rw-r--r--sys/src/9/port/systab.h3
-rw-r--r--sys/src/libc/9syscall/sys.h1
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