From ccdca2cd6b84f290b0cf8709b11353e58cafdba9 Mon Sep 17 00:00:00 2001 From: Akshat Kumar Date: Fri, 4 May 2012 03:48:34 -0700 Subject: [PATCH] pkg/runtime: Plan 9 signal handling in Go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds proper note handling for Plan 9, and fixes the issue of properly killing go procs. Without this change, the first go proc that dies (using runtime·exit()) would kill all the running go procs. Proper signal handling is needed. R=golang-dev, ality, rminnich, rsc CC=golang-dev, john, mirtchovski https://golang.org/cl/5617048 --- src/pkg/runtime/os_plan9.h | 10 +++ src/pkg/runtime/sys_plan9_386.s | 10 +++ src/pkg/runtime/thread_plan9.c | 145 ++++++++++++++++++++++++++++---- 3 files changed, 147 insertions(+), 18 deletions(-) diff --git a/src/pkg/runtime/os_plan9.h b/src/pkg/runtime/os_plan9.h index cc6343c8ec..cc14cc8c5e 100644 --- a/src/pkg/runtime/os_plan9.h +++ b/src/pkg/runtime/os_plan9.h @@ -14,6 +14,9 @@ int32 runtime·sleep(int32 ms); int32 runtime·rfork(int32 flags, void *stk, M *m, G *g, void (*fn)(void)); int32 runtime·plan9_semacquire(uint32 *addr, int32 block); int32 runtime·plan9_semrelease(uint32 *addr, int32 count); +int32 runtime·notify(void (*fn)(void*, byte*)); +int32 runtime·noted(int32); +void runtime·gonote(void*, byte*); /* open */ enum @@ -45,6 +48,13 @@ enum RFNOMNT = (1<<14) }; +/* notify */ +enum +{ + NCONT = 0, + NDFLT = 1 +}; + typedef struct Tos Tos; typedef intptr Plink; diff --git a/src/pkg/runtime/sys_plan9_386.s b/src/pkg/runtime/sys_plan9_386.s index 94c36aa410..f3e56d689b 100644 --- a/src/pkg/runtime/sys_plan9_386.s +++ b/src/pkg/runtime/sys_plan9_386.s @@ -48,6 +48,16 @@ TEXT runtime·plan9_semacquire(SB),7,$0 MOVL $37, AX INT $64 RET + +TEXT runtime·notify(SB),7,$0 + MOVL $28, AX + INT $64 + RET + +TEXT runtime·noted(SB),7,$0 + MOVL $29, AX + INT $64 + RET TEXT runtime·plan9_semrelease(SB),7,$0 MOVL $38, AX diff --git a/src/pkg/runtime/thread_plan9.c b/src/pkg/runtime/thread_plan9.c index 3b0dca69f0..e951e31c09 100644 --- a/src/pkg/runtime/thread_plan9.c +++ b/src/pkg/runtime/thread_plan9.c @@ -7,6 +7,9 @@ #include "arch_GOARCH.h" int8 *goos = "plan9"; +int8 *runtime·exitstatus; + +int32 runtime·postnote(int32, int8*); void runtime·minit(void) @@ -36,10 +39,30 @@ getproccount(void) return ncpu > 0 ? ncpu : 1; } +static int32 +getpid(void) +{ + byte b[20], *c; + int32 fd, n; + + runtime·memclr(b, sizeof(b)); + fd = runtime·open((byte*)"#c/pid", 0); + if(fd >= 0) { + runtime·read(fd, b, sizeof(b)); + runtime·close(fd); + } + c = b; + while(*c == ' ' || *c == '\t') + c++; + return runtime·atoi(c); +} + void runtime·osinit(void) { runtime·ncpu = getproccount(); + m->procid = getpid(); + runtime·notify(runtime·gonote); } void @@ -109,36 +132,122 @@ time·now(int64 sec, int32 nsec) FLUSH(&nsec); } -extern Tos *_tos; void -runtime·exit(int32) +runtime·itoa(int32 n, byte *p, uint32 len) { - int32 fd; + byte *q, c; + uint32 i; + + if(len <= 1) + return; + + runtime·memclr(p, len); + q = p; + + if(n==0) { + *q++ = '0'; + USED(q); + return; + } + if(n < 0) { + *q++ = '-'; + p++; + n = -n; + } + for(i=0; n > 0 && i < len; i++) { + *q++ = '0' + (n%10); + n = n/10; + } + for(q--; q >= p; ) { + c = *p; + *p++ = *q; + *q-- = c; + } +} + +void +goexitsall(void) +{ + M *m; + int32 pid; + + pid = getpid(); + for(m=runtime·atomicloadp(&runtime·allm); m; m=m->alllink) + if(m->procid != pid) + runtime·postnote(m->procid, "gointr"); +} + +void +runtime·gonote(void*, byte *s) +{ + uint8 buf[128]; + int32 l; + + l = runtime·findnull(s); + if(l > 4 && runtime·mcmp(s, (byte*)"sys:", 4) == 0) { + runtime·memclr(buf, sizeof buf); + runtime·memmove((void*)buf, (void*)s, runtime·findnull(s)); + runtime·exitstatus = (int8*)buf; + goexitsall(); + runtime·noted(NDFLT); + } + + if(runtime·exitstatus) + runtime·exits(runtime·exitstatus); + + if(runtime·strcmp(s, (byte*)"gointr") == 0) + runtime·noted(NCONT); + + runtime·noted(NDFLT); +} + +int32 +runtime·postnote(int32 pid, int8* msg) +{ + int32 fd, len; uint8 buf[128]; uint8 tmp[16]; uint8 *p, *q; - int32 pid; runtime·memclr(buf, sizeof buf); - runtime·memclr(tmp, sizeof tmp); - pid = _tos->pid; - /* build path string /proc/pid/notepg */ - for(q=tmp; pid > 0;) { - *q++ = '0' + (pid%10); - pid = pid/10; - } + /* build path string /proc/pid/note */ + q = tmp; p = buf; + runtime·itoa(pid, tmp, sizeof tmp); runtime·memmove((void*)p, (void*)"/proc/", 6); - p += 6; - for(q--; q >= tmp;) - *p++ = *q--; - runtime·memmove((void*)p, (void*)"/notepg", 7); + for(p += 6; *p++ = *q++; ); + p--; + runtime·memmove((void*)p, (void*)"/note", 5); - /* post interrupt note */ fd = runtime·open(buf, OWRITE); - runtime·write(fd, "interrupt", 9); - runtime·exits(nil); + if(fd < 0) + return -1; + + len = runtime·findnull((byte*)msg); + if(runtime·write(fd, msg, len) != len) { + runtime·close(fd); + return -1; + } + runtime·close(fd); + return 0; +} + +void +runtime·exit(int32 e) +{ + byte tmp[16]; + + if(e == 0) + runtime·exitstatus = ""; + else { + /* build error string */ + runtime·itoa(e, tmp, sizeof tmp); + runtime·exitstatus = (int8*)tmp; + } + + goexitsall(); + runtime·exits(runtime·exitstatus); } void