# HG changeset patch # User Ron Minnich # Date 1320089335 25200 # Node ID 03c575d34cbb4bbd08337d6f2b5f8af3d861953a # Parent 8a9762a01ea03157402a65091b6a107273ff41fa Another go at a portable mwait. It's 4pm and time for the kernel on top of your television to explode. But as of 6PM GMT it seems to work. mwait(void *): spin on the value of the data pointed to until it is non-zero. sys/src/nix/k10/acore.c: use mwait sys/src/nix/k10/archk10.c: if MONITOR enabled, use the k10 version sys/src/nix/k10/fns.h: prototypes sys/src/nix/k10/l64v.s: Assembly function which combines monitor and mwait sys/src/nix/port/portfns.h: prototypes sys/src/nix/port/taslock.c: portable version Tested for both the portable and k10-specific versions and it works. R=nixiedev CC=nix-dev http://codereview.appspot.com/5314066 diff -r 8a9762a01ea0 -r 03c575d34cbb sys/src/nix/k10/acore.c --- a/sys/src/nix/k10/acore.c Thu Oct 27 13:31:14 2011 -0700 +++ b/sys/src/nix/k10/acore.c Mon Oct 31 12:28:55 2011 -0700 @@ -66,8 +66,7 @@ snprint((char*)mp->icc->data, ICCLNSZ, "<%d>", i); mfence(); mp->icc->fn = testiccfn; - while(mp->icc->fn != nil) - ; + mwait(&mp->icc->fn); } } @@ -103,8 +102,7 @@ for(;;){ acstackok(); m->load = 0; - while(*m->icc->fn == nil) - ; + mwait(&m->icc->fn); if(m->icc->flushtlb) acmmuswitch(); DBG("acsched: cpu%d: fn %#p\n", m->machno, m->icc->fn); @@ -217,8 +215,8 @@ ready(m->proc); m->load = 0; - while(*m->icc->fn == nil) - ; + mwait(&m->icc->fn); + m->load = 100; if(m->icc->flushtlb) diff -r 8a9762a01ea0 -r 03c575d34cbb sys/src/nix/k10/archk10.c --- a/sys/src/nix/k10/archk10.c Thu Oct 27 13:31:14 2011 -0700 +++ b/sys/src/nix/k10/archk10.c Mon Oct 31 12:28:55 2011 -0700 @@ -31,7 +31,7 @@ /* is mnonitor supported? */ if (m->cpuinfo[1][2] & 8) { cpuid(5, 0, &m->monitorsize); - iprint("Monitor supported; size %d", m->monitorsize); + mwait = k10mwait; } return 1; diff -r 8a9762a01ea0 -r 03c575d34cbb sys/src/nix/k10/fns.h --- a/sys/src/nix/k10/fns.h Thu Oct 27 13:31:14 2011 -0700 +++ b/sys/src/nix/k10/fns.h Mon Oct 31 12:28:55 2011 -0700 @@ -95,9 +95,7 @@ int mmukmapsync(uvlong); uintmem mmuphysaddr(uintptr); int mmuwalk(PTE*, uintptr, int, PTE**, PTE (*)(usize)); -void monitor(void*); int multiboot(u32int, u32int, int); -void mwait(u32int); void ndnr(void); uchar nvramread(int); void nvramwrite(int, uchar); @@ -225,6 +223,7 @@ * archk10.c */ extern void millidelay(int); +void k10mwait(void *); /* * i8259.c diff -r 8a9762a01ea0 -r 03c575d34cbb sys/src/nix/k10/l64v.s --- a/sys/src/nix/k10/l64v.s Thu Oct 27 13:31:14 2011 -0700 +++ b/sys/src/nix/k10/l64v.s Mon Oct 31 12:28:55 2011 -0700 @@ -369,18 +369,38 @@ HLT RET -TEXT monitor(SB), 1, $-4 /* void monitor(void*); */ +TEXT _monitor(SB), 1, $-4 /* void monitor(void*); */ MOVQ RARG, AX /* linear address to monitor */ XORQ CX, CX /* no optional extensions yet */ XORQ DX, DX /* no optional hints yet */ BYTE $0x0f; BYTE $0x01; BYTE $0xc8 /* MONITOR */ RET -TEXT mwait(SB), 1, $-4 /* void mwait(u32int); */ +TEXT _mwait(SB), 1, $-4 /* void mwait(u32int); */ MOVLQZX RARG, CX /* optional extensions */ BYTE $0x0f; BYTE $0x01; BYTE $0xc9 /* MWAIT */ RET +TEXT k10mwait+0(SB),0,$16 +k10mwloop: + MOVQ RARG,CX + MOVQ (CX),AX + CMPQ AX,$0 + JNE k10mwdone + MOVQ RARG, AX /* linear address to monitor */ + XORQ CX, CX /* no optional extensions yet */ + XORQ DX, DX /* no optional hints yet */ + BYTE $0x0f; BYTE $0x01; BYTE $0xc8 /* MONITOR */ + MOVQ RARG,CX + MOVQ (CX),AX + CMPQ AX,$0 + JNE k10mwdone + XORQ CX, CX /* optional extensions */ + BYTE $0x0f; BYTE $0x01; BYTE $0xc9 /* MWAIT */ + JMP k10mwloop +k10mwdone: + RET , + TEXT mul64fract(SB), 1, $-4 MOVQ a+8(FP), AX MULQ b+16(FP) /* a*b */ diff -r 8a9762a01ea0 -r 03c575d34cbb sys/src/nix/port/portfns.h --- a/sys/src/nix/port/portfns.h Thu Oct 27 13:31:14 2011 -0700 +++ b/sys/src/nix/port/portfns.h Mon Oct 31 12:28:55 2011 -0700 @@ -191,6 +191,7 @@ ulong ms2tk(ulong); void mul64fract(uvlong*, uvlong, uvlong); void muxclose(Mnt*); +void (*mwait)(void *); Chan* namec(char*, int, int, int); void nameerror(char*, char*); Chan* newchan(void); @@ -237,6 +238,7 @@ void* phystag(uintmem); void pio(Segment*, uintptr, ulong, Page**); #define poperror() up->nerrlab-- +void portmwait(void *); int postnote(Proc*, int, char*, int); int pprint(char*, ...); int preempted(void); diff -r 8a9762a01ea0 -r 03c575d34cbb sys/src/nix/port/taslock.c --- a/sys/src/nix/port/taslock.c Thu Oct 27 13:31:14 2011 -0700 +++ b/sys/src/nix/port/taslock.c Mon Oct 31 12:28:55 2011 -0700 @@ -237,3 +237,12 @@ up->lastilock = nil; splx(pl); } + +void +portmwait(void *value) +{ + while (*(void**)value == nil) + ; +} + +void (*mwait)(void *) = portmwait;