Skip to content

Commit 6c1d8fd

Browse files
committed
Plan 9 from Bell Labs 2012-06-30
1 parent 2734f4a commit 6c1d8fd

File tree

6 files changed

+98
-10
lines changed

6 files changed

+98
-10
lines changed

Diff for: sys/include/libc.h

+1
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ extern int semacquire(long*, int);
677677
extern long semrelease(long*, long);
678678
extern int sleep(long);
679679
extern int stat(char*, uchar*, int);
680+
extern int tsemacquire(long*, ulong);
680681
extern Waitmsg* wait(void);
681682
extern int waitpid(void);
682683
extern long write(int, void*, long);

Diff for: sys/man/2/semacquire

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.TH SEMACQUIRE 2
22
.SH NAME
3-
semacquire, semrelease \- user level semaphores
3+
semacquire, tsemacquire, semrelease - user level semaphores
44
.SH SYNOPSIS
55
.B #include <u.h>
66
.br
@@ -10,10 +10,14 @@ semacquire, semrelease \- user level semaphores
1010
int semacquire(long *addr, int block);
1111
.PP
1212
.B
13+
int tsemacquire(long *addr, ulong ms);
14+
.PP
15+
.B
1316
long semrelease(long *addr, long count);
1417
.SH DESCRIPTION
15-
.I Semacquire
16-
and
18+
.IR Semacquire ,
19+
.IR tsemacquire ,
20+
and
1721
.I semrelease
1822
facilitate scheduling between processes sharing memory.
1923
Processes arrange to share memory by using
@@ -22,7 +26,7 @@ with the
2226
.B RFMEM
2327
flag
2428
(see
25-
.IR fork (2)),
29+
.IR fork (2)),
2630
.IR segattach (2),
2731
or
2832
.IR thread (2).
@@ -32,21 +36,30 @@ The semaphore's value is the integer pointed at by
3236
.I Semacquire
3337
atomically waits until the semaphore has a positive value
3438
and then decrements that value.
35-
It returns 1 if the semaphore was acquired and \-1 on error
36-
(e.g., if it was interrupted).
3739
If
3840
.I block
3941
is zero
4042
and the semaphore is not immediately available,
4143
.I semacquire
4244
returns 0 instead of waiting.
45+
.I Tsemacquire
46+
only waits
47+
.I ms
48+
milliseconds for the semaphore to attain a positive value
49+
and, if available in that time, decrements that value.
50+
It returns 0 otherwise.
51+
Both functions return 1 if the semaphore was acquired
52+
and -1 on error
53+
(e.g., if they were interrupted).
4354
.I Semrelease
44-
adds
55+
adds
4556
.I count
4657
to the semaphore's value
4758
and returns the new value.
4859
.PP
4960
.I Semacquire
61+
(and analogously for
62+
.IR tsemacquire )
5063
and
5164
.I semrelease
5265
can be thought of as efficient, correct replacements for:
@@ -74,7 +87,8 @@ semrelease(long *addr, int count)
7487
.PP
7588
Like
7689
.IR rendezvous (2),
77-
.I semacquire
90+
.IR semacquire ,
91+
.IR tsemacquire ,
7892
and
7993
.I semrelease
8094
are not typically used directly.
@@ -86,8 +100,9 @@ locks, rendezvous points, and channels
86100
and
87101
.IR thread (2)).
88102
Also like
89-
.I rendezvous ,
90-
.I semacquire
103+
.IR rendezvous ,
104+
.IR semacquire ,
105+
.IR tsemacquire ,
91106
and
92107
.I semrelease
93108
cannot be used to coordinate between threads

Diff for: sys/src/9/port/syscallfmt.c

+5
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ syscallfmt(int syscallno, ulong pc, va_list list)
231231
i[0] = va_arg(list, int);
232232
fmtprint(&fmt, "%#p %d", v, i[0]);
233233
break;
234+
case TSEMACQUIRE:
235+
v = va_arg(list, long*);
236+
l = va_arg(list, ulong);
237+
fmtprint(&fmt, "%#p %ld", v, l);
238+
break;
234239
case SEEK:
235240
v = va_arg(list, vlong*);
236241
i[0] = va_arg(list, int);

Diff for: sys/src/9/port/sysproc.c

+63
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,50 @@ semacquire(Segment *s, long *addr, int block)
10311031
return 1;
10321032
}
10331033

1034+
/* Acquire semaphore or time-out */
1035+
static int
1036+
tsemacquire(Segment *s, long *addr, ulong ms)
1037+
{
1038+
int acquired, timedout;
1039+
ulong t;
1040+
Sema phore;
1041+
1042+
if(canacquire(addr))
1043+
return 1;
1044+
if(ms == 0)
1045+
return 0;
1046+
acquired = timedout = 0;
1047+
semqueue(s, addr, &phore);
1048+
for(;;){
1049+
phore.waiting = 1;
1050+
coherence();
1051+
if(canacquire(addr)){
1052+
acquired = 1;
1053+
break;
1054+
}
1055+
if(waserror())
1056+
break;
1057+
t = m->ticks;
1058+
tsleep(&phore, semawoke, &phore, ms);
1059+
if(TK2MS(m->ticks - t) >= ms){
1060+
timedout = 1;
1061+
poperror();
1062+
break;
1063+
}
1064+
ms -= TK2MS(m->ticks - t);
1065+
poperror();
1066+
}
1067+
semdequeue(s, &phore);
1068+
coherence(); /* not strictly necessary due to lock in semdequeue */
1069+
if(!phore.waiting)
1070+
semwakeup(s, addr, 1);
1071+
if(timedout)
1072+
return 0;
1073+
if(!acquired)
1074+
nexterror();
1075+
return 1;
1076+
}
1077+
10341078
long
10351079
syssemacquire(ulong *arg)
10361080
{
@@ -1050,6 +1094,25 @@ syssemacquire(ulong *arg)
10501094
return semacquire(s, addr, block);
10511095
}
10521096

1097+
long
1098+
systsemacquire(ulong *arg)
1099+
{
1100+
long *addr;
1101+
ulong ms;
1102+
Segment *s;
1103+
1104+
validaddr(arg[0], sizeof(long), 1);
1105+
evenaddr(arg[0]);
1106+
addr = (long*)arg[0];
1107+
ms = arg[1];
1108+
1109+
if((s = seg(up, (ulong)addr, 0)) == nil)
1110+
error(Ebadarg);
1111+
if(*addr < 0)
1112+
error(Ebadarg);
1113+
return tsemacquire(s, addr, ms);
1114+
}
1115+
10531116
long
10541117
syssemrelease(ulong *arg)
10551118
{

Diff for: sys/src/9/port/systab.h

+3
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Syscall sysmount;
5252
Syscall sysawait;
5353
Syscall syspread;
5454
Syscall syspwrite;
55+
Syscall systsemacquire;
5556
Syscall sysdeath;
5657

5758
Syscall *systab[]={
@@ -105,6 +106,7 @@ Syscall *systab[]={
105106
[AWAIT] sysawait,
106107
[PREAD] syspread,
107108
[PWRITE] syspwrite,
109+
[TSEMACQUIRE] systsemacquire,
108110
};
109111

110112
char *sysctab[]={
@@ -158,6 +160,7 @@ char *sysctab[]={
158160
[AWAIT] "Await",
159161
[PREAD] "Pread",
160162
[PWRITE] "Pwrite",
163+
[TSEMACQUIRE] "Tsemacquire",
161164
};
162165

163166
int nsyscall = (sizeof systab/sizeof systab[0]);

Diff for: sys/src/libc/9syscall/sys.h

+1
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,4 @@
4848
#define AWAIT 47
4949
#define PREAD 50
5050
#define PWRITE 51
51+
#define TSEMACQUIRE 52

0 commit comments

Comments
 (0)