git: 9front

Download patch

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
--