diff --git a/src/pkg/runtime/386/asm.s b/src/pkg/runtime/386/asm.s index a7265b2b2d..67b72f73f3 100644 --- a/src/pkg/runtime/386/asm.s +++ b/src/pkg/runtime/386/asm.s @@ -13,12 +13,9 @@ TEXT _rt0_386(SB),7,$0 MOVL AX, 120(SP) // save argc, argv away MOVL BX, 124(SP) + // set up %gs CALL ldt0setup(SB) - // set up %gs to refer to that ldt entry - MOVL $(7*8+7), AX - MOVW AX, GS - // store through it, to make sure it works MOVL $0x123, 0(GS) MOVL tls0(SB), AX @@ -80,7 +77,7 @@ TEXT mainstart(SB),7,$0 RET TEXT breakpoint(SB),7,$0 - BYTE $0xcc + INT $3 RET /* @@ -280,6 +277,7 @@ TEXT sys·setcallerpc+0(SB),7,$0 TEXT ldt0setup(SB),7,$16 // set up ldt 7 to point at tls0 // ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go. + // the entry number is just a hint. setldt will set up GS with what it used. MOVL $7, 0(SP) LEAL tls0(SB), AX MOVL AX, 4(SP) @@ -297,4 +295,3 @@ TEXT emptyfunc(SB),0,$0 TEXT abort(SB),7,$0 INT $0x3 - diff --git a/src/pkg/runtime/386/closure.c b/src/pkg/runtime/386/closure.c index 1a211bd1f3..763fc45da3 100644 --- a/src/pkg/runtime/386/closure.c +++ b/src/pkg/runtime/386/closure.c @@ -15,6 +15,9 @@ sys·closure(int32 siz, byte *fn, byte *arg0) int32 i, n; int32 pcrel; + if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0) + throw("no closures in native client yet"); + if(siz < 0 || siz%4 != 0) throw("bad closure size"); diff --git a/src/pkg/runtime/darwin/386/sys.s b/src/pkg/runtime/darwin/386/sys.s index 49743359fd..bded7e4211 100644 --- a/src/pkg/runtime/darwin/386/sys.s +++ b/src/pkg/runtime/darwin/386/sys.s @@ -270,6 +270,12 @@ TEXT setldt(SB),7,$32 MOVL AX, 4(SP) MOVL $1, 8(SP) CALL i386_set_ldt(SB) + + // compute segment selector - (entry*8+7) + MOVL entry+0(FP), AX + SHLL $3, AX + ADDL $7, AX + MOVW AX, GS RET TEXT i386_set_ldt(SB),7,$0 diff --git a/src/pkg/runtime/linux/386/sys.s b/src/pkg/runtime/linux/386/sys.s index 7f4787700b..fe07ddd54f 100755 --- a/src/pkg/runtime/linux/386/sys.s +++ b/src/pkg/runtime/linux/386/sys.s @@ -219,5 +219,12 @@ TEXT setldt(SB),7,$32 CMPL AX, $0xfffff001 JLS 2(PC) INT $3 + + // compute segment selector - (entry*8+7) + MOVL entry+0(FP), AX + SHLL $3, AX + ADDL $7, AX + MOVW AX, GS + RET diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c index d0cf2237bd..8f85b5e091 100644 --- a/src/pkg/runtime/mheap.c +++ b/src/pkg/runtime/mheap.c @@ -170,6 +170,8 @@ MHeap_Grow(MHeap *h, uintptr npage) // Ask for a big chunk, to reduce the number of mappings // the operating system needs to track; also amortizes // the overhead of an operating system mapping. + // For Native Client, allocate a multiple of 64kB (16 pages). + npage = (npage+15)&~15; ask = npage<locks < 0) + throw("lock count"); + m->locks++; + if(l->sema == 0) + initsema(&l->sema); + xlock(l->sema>>1); +} + +void +unlock(Lock *l) +{ + m->locks--; + if(m->locks < 0) + throw("lock count"); + xunlock(l->sema>>1); +} + + +// One-time notifications. +// +// Since the lock/unlock implementation already +// takes care of sleeping in the kernel, we just reuse it. +// (But it's a weird use, so it gets its own interface.) +// +// We use a lock to represent the event: +// unlocked == event has happened. +// Thus the lock starts out locked, and to wait for the +// event you try to lock the lock. To signal the event, +// you unlock the lock. +// +// Native Client does not require that the thread acquiring +// a lock be the thread that releases the lock, so this is safe. + +void +noteclear(Note *n) +{ + if(n->lock.sema == 0) + initsema(&n->lock.sema); + xlock(n->lock.sema>>1); +} + +void +notewakeup(Note *n) +{ + if(n->lock.sema == 0) { + printf("notewakeup without noteclear"); + breakpoint(); + } + xunlock(n->lock.sema>>1); +} + +void +notesleep(Note *n) +{ + if(n->lock.sema == 0) { + printf("notesleep without noteclear"); + breakpoint(); + } + xlock(n->lock.sema>>1); + xunlock(n->lock.sema>>1); // Let other sleepers find out too. +} + +void +newosproc(M *m, G *g, void *stk, void (*fn)(void)) +{ + void **vstk; + + // I wish every OS made thread creation this easy. + m->tls[0] = (uint32)g; + m->tls[1] = (uint32)m; + vstk = stk; + *--vstk = nil; + if(thread_create(fn, vstk, m->tls, sizeof m->tls) < 0) { + printf("thread_create failed\n"); + breakpoint(); + } +} + +void +osinit(void) +{ +} + +// Called to initialize a new m (including the bootstrap m). +void +minit(void) +{ +} diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 58839f97f0..34bc262525 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -308,6 +308,7 @@ int32 goidgen; extern int32 gomaxprocs; extern int32 panicking; extern int32 maxround; +int8* goos; /* * common functions and data diff --git a/src/pkg/runtime/symtab.c b/src/pkg/runtime/symtab.c index 97501623d3..a082a7615d 100644 --- a/src/pkg/runtime/symtab.c +++ b/src/pkg/runtime/symtab.c @@ -32,6 +32,15 @@ sys·symdat(Slice *symtab, Slice *pclntab) Slice *a; int32 *v; + // TODO(rsc): Remove once TODO at top of file is done. + if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0) { + symtab = mal(sizeof *a); + pclntab = mal(sizeof *a); + FLUSH(&symtab); + FLUSH(&pclntab); + return; + } + v = SYMCOUNTS; a = mal(sizeof *a); @@ -66,6 +75,10 @@ walksymtab(void (*fn)(Sym*)) byte *p, *ep, *q; Sym s; + // TODO(rsc): Remove once TODO at top of file is done. + if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0) + return; + v = SYMCOUNTS; p = SYMDATA; ep = p + v[0]; @@ -260,6 +273,10 @@ splitpcln(void) Func *f, *ef; int32 *v; + // TODO(rsc): Remove once TODO at top of file is done. + if(goos != nil && strcmp((uint8*)goos, (uint8*)"nacl") == 0) + return; + // pc/ln table bounds v = SYMCOUNTS; p = SYMDATA;