ref: 704adceab89cf760c9c67a6deec5eee154770fa2
parent: 1973cdfb35be56f0a8e3a338a4311e1897434caf
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Jul 29 16:26:49 EDT 2012
add tsemacquire syscall for go
--- a/sys/include/libc.h
+++ b/sys/include/libc.h
@@ -670,6 +670,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);
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -1034,6 +1034,50 @@
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)
{@@ -1051,6 +1095,25 @@
if(*addr < 0)
error(Ebadarg);
return semacquire(s, addr, block);
+}
+
+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
--- a/sys/src/9/port/systab.h
+++ b/sys/src/9/port/systab.h
@@ -52,6 +52,7 @@
Syscall sysawait;
Syscall syspread;
Syscall syspwrite;
+Syscall systsemacquire;
Syscall sysdeath;
Syscall *systab[]={@@ -105,6 +106,7 @@
[AWAIT] sysawait,
[PREAD] syspread,
[PWRITE] syspwrite,
+ [TSEMACQUIRE] systsemacquire,
};
char *sysctab[]={@@ -158,6 +160,7 @@
[AWAIT] "Await",
[PREAD] "Pread",
[PWRITE] "Pwrite",
+ [TSEMACQUIRE] "Tsemacquire",
};
int nsyscall = (sizeof systab/sizeof systab[0]);
--- 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
--
⑨