kernel: new system calls semacquire, semrelease [rsc] --rw-rw-r-- M 1061556 glenda sys 19699 Mar 23 11:05 sys/include/libc.h /n/sourcesdump/2006/0323/plan9/sys/include/libc.h:659,664 - /n/sourcesdump/2006/0324/plan9/sys/include/libc.h:659,666 extern int segdetach(void*); extern int segflush(void*, ulong); extern int segfree(void*, ulong); + extern int semacquire(long*, int); + extern long semrelease(long*, long); extern int sleep(long); extern int stat(char*, uchar*, int); extern Waitmsg* wait(void); [rsc] --rw-rw-r-- M 1061556 rsc sys 1865 Mar 23 12:25 sys/man/2/semacquire [rsc] --rw-rw-r-- M 1061556 glenda sys 3626 Mar 23 11:04 sys/src/9/alphapc/fns.h /n/sourcesdump/2006/0323/plan9/sys/src/9/alphapc/fns.h:12,18 - /n/sourcesdump/2006/0324/plan9/sys/src/9/alphapc/fns.h:12,18 int cistrncmp(char*, char*, int); void cpuidprint(void); void cserve(ulong, ulong); - #define cycles(x) + #define cycles(x) do{}while(0) void timeradd(Timer *); void timerdel(Timer *); int dmacount(int); [rsc] --rw-rw-r-- M 1061556 glenda sys 9367 Mar 23 11:04 sys/src/9/alphapc/l.s /n/sourcesdump/2006/0323/plan9/sys/src/9/alphapc/l.s:193,198 - /n/sourcesdump/2006/0324/plan9/sys/src/9/alphapc/l.s:193,212 BEQ R0, inc1 /* write failed, retry */ RET + TEXT cmpswap(SB), $-8 + MOVQ R0, R1 /* p */ + MOVL old+4(FP), R2 + MOVL new+8(FP), R3 + MOVLL (R1), R0 + CMPEQ R0, R2, R4 + BEQ R4, fail /* if R0 != [sic] R2, goto fail */ + MOVQ R3, R0 + MOVLC R0, (R1) + RET + fail: + MOVL $0, R0 + RET + TEXT fpenab(SB), $-8 MOVQ R0, R16 CALL_PAL $PALwrfen [rsc] --rw-rw-r-- M 1061556 glenda sys 13748 Mar 23 11:02 sys/src/9/alphapc/main.c /n/sourcesdump/2006/0323/plan9/sys/src/9/alphapc/main.c:73,78 - /n/sourcesdump/2006/0324/plan9/sys/src/9/alphapc/main.c:73,80 print("dumpopts: read %s=%s\n", confname[i], confval[i]); } + extern void (*i8237alloc)(void); + void main(void) { /n/sourcesdump/2006/0323/plan9/sys/src/9/alphapc/main.c:87,92 - /n/sourcesdump/2006/0324/plan9/sys/src/9/alphapc/main.c:89,96 archinit(); xinit(); memholes(); + if(i8237alloc != nil) + i8237alloc(); mmuinit(); if(arch->coreinit) arch->coreinit(); [rsc] --rw-rw-r-- M 1061556 glenda bitsy 5829 Mar 23 11:03 sys/src/9/bitsy/dat.h /n/sourcesdump/2006/0323/plan9/sys/src/9/bitsy/dat.h:32,41 - /n/sourcesdump/2006/0324/plan9/sys/src/9/bitsy/dat.h:32,37 */ #define AOUT_MAGIC (E_MAGIC) - enum { - Lockcycles = 0, /* Don't measure lock latencies */ - }; - struct Lock { ulong key; /n/sourcesdump/2006/0323/plan9/sys/src/9/bitsy/dat.h:44,50 - /n/sourcesdump/2006/0324/plan9/sys/src/9/bitsy/dat.h:40,45 Proc *p; Mach *m; ushort isilock; - uvlong lockcycles; /* Measure lock latencies */ }; struct Label [rsc] --rw-rw-r-- M 1061556 glenda bitsy 3063 Mar 23 11:04 sys/src/9/bitsy/fns.h /n/sourcesdump/2006/0323/plan9/sys/src/9/bitsy/fns.h:12,19 - /n/sourcesdump/2006/0324/plan9/sys/src/9/bitsy/fns.h:12,20 int cistrncmp(char*, char*, int); void clockinit(void); ulong clockpower(int); + int cmpswap(long*, long, long); #define coherence() - #define cycles(x) + #define cycles(x) do{}while(0) #define dcflush(a, b) void delay(int); void µcpower(int); [rsc] --rw-rw-r-- M 1061556 glenda bitsy 8951 Mar 23 11:04 sys/src/9/bitsy/main.c /n/sourcesdump/2006/0323/plan9/sys/src/9/bitsy/main.c:522,533 - /n/sourcesdump/2006/0324/plan9/sys/src/9/bitsy/main.c:522,533 long _xdec(long *p) { - int x; + int s; long v; - x = splhi(); + s = splhi(); v = --*p; - splx(x); + splx(s); return v; } /n/sourcesdump/2006/0323/plan9/sys/src/9/bitsy/main.c:534,542 - /n/sourcesdump/2006/0324/plan9/sys/src/9/bitsy/main.c:534,555 void _xinc(long *p) { - int x; + int s; - x = splhi(); + s = splhi(); ++*p; - splx(x); + splx(s); } + + int + cmpswap(long *addr, long old, long new) + { + int r, s; + + s = splhi(); + if(r = (*addr==old)) + *addr = new; + splx(s); + return r; + } + [rsc] --rw-rw-r-- M 1061556 glenda sys 2767 Mar 23 11:03 sys/src/9/mtx/fns.h /n/sourcesdump/2006/0323/plan9/sys/src/9/mtx/fns.h:5,13 - /n/sourcesdump/2006/0324/plan9/sys/src/9/mtx/fns.h:5,14 void clockinit(void); void clockintr(Ureg*); void clockintrsched(void); + int cmpswap(long*, long, long); #define coherence() eieio() void cpuidprint(void); - #define cycles(x) + #define cycles(x) do{}while(0) void dcflush(void*, ulong); void delay(int); void dumpregs(Ureg*); [rsc] --rw-rw-r-- M 1061556 glenda sys 11000 Mar 23 11:04 sys/src/9/mtx/l.s /n/sourcesdump/2006/0323/plan9/sys/src/9/mtx/l.s:301,306 - /n/sourcesdump/2006/0324/plan9/sys/src/9/mtx/l.s:301,322 BNE xdecloop RETURN + TEXT cmpswap(SB),$0 /* int cmpswap(long*, long, long) */ + MOVW R3, R4 /* addr */ + MOVW old+4(FP), R5 + MOVW new+8(FP), R6 + DCBF (R4) /* fix for 603x bug? */ + LWAR (R4), R3 + CMP R3, R5 + BNE fail + STWCCC R6, (R4) + BNE fail + MOVW $1, R3 + RETURN + fail: + MOVW $0, R3 + RETURN + TEXT getpvr(SB), $0 MOVW SPR(PVR), R3 RETURN [rsc] --rw-rw-r-- M 1061556 glenda sys 19249 Mar 23 11:03 sys/src/9/pc/devarch.c /n/sourcesdump/2006/0323/plan9/sys/src/9/pc/devarch.c:497,502 - /n/sourcesdump/2006/0324/plan9/sys/src/9/pc/devarch.c:497,518 } /* + * 386 has no compare-and-swap instruction. + * Run it with interrupts turned off instead. + */ + static int + cmpswap386(long *addr, long old, long new) + { + int r, s; + + s = splhi(); + if(r = (*addr == old)) + *addr = new; + splx(s); + return r; + } + + /* * On a uniprocessor, you'd think that coherence could be nop, * but it can't. We still need a barrier when using coherence() in * device drivers. /n/sourcesdump/2006/0323/plan9/sys/src/9/pc/devarch.c:506,511 - /n/sourcesdump/2006/0324/plan9/sys/src/9/pc/devarch.c:522,529 */ void (*coherence)(void) = nop; + int (*cmpswap)(long*, long, long) = cmpswap386; + PCArch* arch; extern PCArch* knownarch[]; /n/sourcesdump/2006/0323/plan9/sys/src/9/pc/devarch.c:787,792 - /n/sourcesdump/2006/0324/plan9/sys/src/9/pc/devarch.c:805,817 n += snprint(buf+n, sizeof buf-n, "nop\n"); else n += snprint(buf+n, sizeof buf-n, "0x%p\n", coherence); + n += snprint(buf+n, sizeof buf-n, "cmpswap "); + if(cmpswap == cmpswap386) + n += snprint(buf+n, sizeof buf-n, "cmpswap386\n"); + else if(cmpswap == cmpswap486) + n += snprint(buf+n, sizeof buf-n, "cmpswap486\n"); + else + n += snprint(buf+n, sizeof buf-n, "0x%p\n", cmpswap); n += snprint(buf+n, sizeof buf-n, "i8253set %s\n", doi8253set ? "on" : "off"); buf[n] = 0; return readstr(offset, a, nn, buf); /n/sourcesdump/2006/0323/plan9/sys/src/9/pc/devarch.c:896,901 - /n/sourcesdump/2006/0324/plan9/sys/src/9/pc/devarch.c:921,929 */ if(X86FAMILY(m->cpuidax) == 3) conf.copymode = 1; + + if(X86FAMILY(m->cpuidax) >= 4) + cmpswap = cmpswap486; if(X86FAMILY(m->cpuidax) >= 5) coherence = mb586; [rsc] --rw-rw-r-- M 1061556 glenda sys 4531 Mar 23 11:05 sys/src/9/pc/fns.h /n/sourcesdump/2006/0323/plan9/sys/src/9/pc/fns.h:5,10 - /n/sourcesdump/2006/0324/plan9/sys/src/9/pc/fns.h:5,12 void archinit(void); void bootargs(void*); void clockintr(Ureg*, void*); + int (*cmpswap)(long*, long, long); + int cmpswap486(long*, long, long); void (*coherence)(void); void cpuid(char*, int*, int*); int cpuidentify(void); [rsc] --rw-rw-r-- M 1061556 glenda sys 28552 Mar 23 11:05 sys/src/9/pc/l.s /n/sourcesdump/2006/0323/plan9/sys/src/9/pc/l.s:839,844 - /n/sourcesdump/2006/0324/plan9/sys/src/9/pc/l.s:839,857 XCHGW AX, (BX) RET + TEXT cmpswap486(SB), $0 + MOVL addr+0(FP), BX + MOVL old+4(FP), AX + MOVL new+8(FP), CX + LOCK + BYTE $0x0F; BYTE $0xB1; BYTE $0x0B /* CMPXCHGL CX, (BX) */ + JNZ didnt + MOVL $1, AX + RET + didnt: + XORL AX,AX + RET + TEXT mul64fract(SB), $0 /* * Multiply two 64-bit number s and keep the middle 64 bits from the 128-bit result [rsc] --rw-rw-r-- M 1061556 glenda sys 22669 Mar 23 11:04 sys/src/9/port/portdat.h /n/sourcesdump/2006/0323/plan9/sys/src/9/port/portdat.h:40,45 - /n/sourcesdump/2006/0324/plan9/sys/src/9/port/portdat.h:40,46 typedef struct Sargs Sargs; typedef struct Schedq Schedq; typedef struct Segment Segment; + typedef struct Sema Sema; typedef struct Timer Timer; typedef struct Timers Timers; typedef struct Uart Uart; /n/sourcesdump/2006/0323/plan9/sys/src/9/port/portdat.h:389,394 - /n/sourcesdump/2006/0324/plan9/sys/src/9/port/portdat.h:390,404 void (*pgfree)(Page*); }; + struct Sema + { + Rendez; + long *addr; + int waiting; + Sema *next; + Sema *prev; + }; + struct Segment { Ref; /n/sourcesdump/2006/0323/plan9/sys/src/9/port/portdat.h:407,412 - /n/sourcesdump/2006/0324/plan9/sys/src/9/port/portdat.h:417,424 Pte **map; int mapsize; Pte *ssegmap[SSEGMAPSIZE]; + Lock semalock; + Sema sema; ulong mark; /* portcountrefs */ }; [rsc] --rw-rw-r-- M 1061556 glenda sys 13992 Mar 23 11:06 sys/src/9/port/segment.c /n/sourcesdump/2006/0323/plan9/sys/src/9/port/segment.c:70,75 - /n/sourcesdump/2006/0324/plan9/sys/src/9/port/segment.c:70,77 s->base = base; s->top = base+(size*BY2PG); s->size = size; + s->sema.prev = &s->sema; + s->sema.next = &s->sema; mapsize = ROUND(size, PTEPERTAB)/PTEPERTAB; if(mapsize > nelem(s->ssegmap)){ /n/sourcesdump/2006/0323/plan9/sys/src/9/port/segment.c:789,791 - /n/sourcesdump/2006/0324/plan9/sys/src/9/port/segment.c:791,794 s->profile[pc>>LRESPROF] += TK2MS(1); } } + [rsc] --rw-rw-r-- M 1061556 rsc sys 2424 Mar 23 11:03 sys/src/9/port/semaphore.p [rsc] --rw-rw-r-- M 1061556 glenda sys 21535 Mar 23 11:03 sys/src/9/port/sysproc.c [diffs elided - too long] [diff -c /n/sourcesdump/2006/0323/plan9/sys/src/9/port/sysproc.c /n/sourcesdump/2006/0324/plan9/sys/src/9/port/sysproc.c] [rsc] --rw-rw-r-- M 1061556 glenda sys 927 Mar 23 11:05 sys/src/libc/9syscall/sys.h /n/sourcesdump/2006/0323/plan9/sys/src/libc/9syscall/sys.h:35,40 - /n/sourcesdump/2006/0324/plan9/sys/src/libc/9syscall/sys.h:35,42 #define RENDEZVOUS 34 #define UNMOUNT 35 #define _WAIT 36 + #define SEMACQUIRE 37 + #define SEMRELEASE 38 #define SEEK 39 #define FVERSION 40 #define ERRSTR 41 /n/sourcesdump/2006/0323/plan9/sys/src/libc/9syscall/sys.h:44,48 - /n/sourcesdump/2006/0324/plan9/sys/src/libc/9syscall/sys.h:46,50 #define FWSTAT 45 #define MOUNT 46 #define AWAIT 47 - #define PREAD 50 - #define PWRITE 51 + #define PREAD 50 + #define PWRITE 51 [rsc] --rw-rw-r-- M 1061556 rsc sys 1865 Mar 23 12:25 sys/man/2/semacquire