clean up exit. to clean up printing, it's important to first make the console synchronous again. that way we don't drop messages as we lose the ability to run the console print process. since we are synchronous and not depending on interrupts, all the spl manipulation and delays can be removed. active.exiting does not need to be protected by a lock. in fact, active.machs is the only element that needs lock protection. cleanup related to this should go back into the nix kernel. finally, it's important to park the APs carefully. first put them in a delay loop with interrupts turned off. then use launchhalt() to turn them off, or whatever the architecture allows. in our case we send an INIT IPI to all-but-self. (our case being amd64.) Reference: /n/atom/patch/applied2013/fshalt Date: Wed Sep 4 18:57:01 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/fs/amd64/fns.h Wed Sep 4 18:50:47 2013 +++ /sys/src/fs/amd64/fns.h Wed Sep 4 18:50:48 2013 @@ -21,6 +21,7 @@ u64int getcr3(void); u64int getcr4(void); void halt(void); +void halthi(void); void hardhalt(void); void i8042a20(void); void i8042reset(void); --- /sys/src/fs/amd64/l64v.s Wed Sep 4 18:50:49 2013 +++ /sys/src/fs/amd64/l64v.s Wed Sep 4 18:50:49 2013 @@ -356,6 +356,10 @@ HLT RET +TEXT halthi(SB), 1, $-4 + HLT + RET + TEXT _monitor(SB), 1, $-4 /* void monitor(void*); */ MOVQ RARG, AX /* linear address to monitor */ XORQ CX, CX /* no optional extensions yet */ --- /sys/src/fs/port/devcons.c Wed Sep 4 18:50:50 2013 +++ /sys/src/fs/port/devcons.c Wed Sep 4 18:50:51 2013 @@ -12,6 +12,7 @@ uint n; uint seq; uint init; + uint bufprint; } printq; static @@ -73,6 +74,27 @@ early = 0; } +void +bufprint(int on) +{ + ilock(&printq); + switch(on<<1 | printq.bufprint){ + case 1<<1 | 0: + case 1<<1 | 1: + printq.bufprint = 1; + break; + case 0<<1 | 0: + break; + case 0<<1 | 1: + printq.bufprint = 0; + waveprint("%.*s", printq.n, (char*)printq.buf); + printq.n = 0; + printq.seq++; + break; + } + iunlock(&printq); +} + /* * Print a string on the console. */ @@ -81,7 +103,7 @@ { uint t; - if(early || predawn){ + if(early || printq.bufprint==0){ waveprint("%.*s", n, s); return; } @@ -252,7 +274,7 @@ va_end(arg); buf[n] = '\n'; putstrn(buf, n+1); - if(!predawn){ + if(printq.bufprint){ spllo(); prflush(); } @@ -267,10 +289,11 @@ { int i, lo; - if(predawn) - return; - ilock(&printq); + if(printq.bufprint == 0){ + iunlock(&printq); + return; + } i = printq.seq; iunlock(&printq); --- /sys/src/fs/port/main.c Wed Sep 4 18:50:51 2013 +++ /sys/src/fs/port/main.c Wed Sep 4 18:50:52 2013 @@ -76,7 +76,7 @@ clockinit(); print("Plan 9 fileserver\n"); - print("\t%d-bit, %d-byte blocks\n", sizeof(Off)*8-1, RBUFSIZE); + print("\t%d-bit, %d-byte blocks, %s\n", sizeof(Off)*8-1, RBUFSIZE, Archname); profinit(); @@ -111,6 +111,7 @@ userinit(touser, 0, "ini"); predawn = 0; + bufprint(1); wakeup(&dawnrend); launchinit(); schedinit(); @@ -292,35 +293,34 @@ void exit(void) { + bufprint(0); + active.exiting = 1; + if(m->machno == 0) doexits(); - u = 0; - lock(&active); - active.machs &= ~(1<machno); - active.exiting = 1; - unlock(&active); - if(!predawn) - spllo(); + u = nil; + splhi(); print("cpu %d exiting\n", m->machno); + + ilock(&active); + active.machs &= ~(1<machno); + iunlock(&active); + while(active.machs) delay(1); while(m->machno != 0) - delay(1); + halthi(); + + launchhalt(); print("halted at %T.\npress a key to reboot sooner than %d mins.\n", time(), Keydelay/60); - delay(500); /* time to drain print q */ - splhi(); /* reboot after delay (for debugging) or at key press */ rawchar(Keydelay); - spllo(); - delay(500); /* time to drain echo q */ print("rebooting...\n"); - delay(500); /* time to drain print q */ - splhi(); consreset(); firmware(); }