use pause() and monmwait() with mcslocks. Reference: /n/atom/patch/applied/mcsmwait Date: Mon Aug 17 05:51:48 CES 2015 Signed-off-by: quanstro@quanstro.net --- /sys/src/nix/k10/l64v.s Mon Aug 17 05:49:29 2015 +++ /sys/src/nix/k10/l64v.s Mon Aug 17 05:49:30 2015 @@ -286,6 +286,19 @@ SUBL $1, AX RET +TEXT ainc64(SB), 1, $-4 /* u64int ainc(u64int*) */ + MOVQ $1, AX + LOCK; XADDQ AX, (RARG) + ADDQ $1, AX + RET + +TEXT aadd64(SB), 1, $-4 /* u64int aadd64(u64int*, u64int) */ + MOVQ v+8(FP), AX + MOVQ AX, BX + LOCK; XADDQ AX, (RARG) + ADDQ BX, AX + RET + TEXT tas32(SB), 1, $-4 MOVL $0xdeaddead, AX XCHGL AX, (RARG) /* */ @@ -357,19 +370,19 @@ /* * uintptr monmwait(void*, uintptr) */ -TEXT k10monmwait64(SB),1,$16 +TEXT k10monmwait64(SB),1,$-4 MOVQ val+8(FP), BX _mmstart: - CMPQ (BP), BX /* changed yet? */ + CMPQ (RARG), BX /* changed yet? */ JNE _mmdone - MOVQ BP, AX /* linear address to monitor */ + MOVQ RARG, AX /* linear address to monitor */ XORQ CX, CX /* extensions */ XORQ DX, DX /* hints */ MONITOR - CMPQ (BP), BX /* changed yet? */ + CMPQ (RARG), BX /* changed yet? */ JNE _mmdone /*XORQ CX, CX*/ /* extensions (different from monitor) */ @@ -377,22 +390,22 @@ MWAIT /* questionable: pop out on irq */ _mmdone: - MOVQ (BP), AX + MOVQ (RARG), AX RET -TEXT k10monmwait32(SB),1,$16 +TEXT k10monmwait32(SB),1,$-4 MOVQ val+8(FP), BX _mmstart32: - CMPL (BP), BX /* changed yet? */ + CMPL (RARG), BX /* changed yet? */ JNE _mmdone32 - MOVQ BP, AX /* linear address to monitor */ + MOVQ RARG, AX /* linear address to monitor */ XORQ CX, CX /* extensions */ XORQ DX, DX /* hints */ MONITOR - CMPL (BP), BX /* changed yet? */ + CMPL (RARG), BX /* changed yet? */ JNE _mmdone32 /*XORQ CX, CX*/ /* extensions (different from monitor) */ @@ -400,7 +413,7 @@ MWAIT /* questionable: pop out on irq */ _mmdone32: - MOVL (BP), AX + MOVL (RARG), AX RET TEXT mul64fract(SB), 1, $-4 --- /sys/src/nix/k10/fns.h Mon Aug 17 05:49:32 2015 +++ /sys/src/nix/k10/fns.h Mon Aug 17 05:49:33 2015 @@ -156,7 +156,7 @@ u32int nopmonmwait32(u32int*, u32int); u32int k10monmwait32(u32int*, u32int); -#define monmwaitp(v, o) monmwait64(v, o); +#define monmwaitp(v, o) ((void*)monmwait64((u64int*)(v), (u64int)(o))) u64int (*monmwait64)(u64int*, u64int); u64int nopmonmwait64(u64int*, u64int); u64int k10monmwait64(u64int*, u64int); --- /sys/src/nix/port/mcslock.c Mon Aug 17 05:49:35 2015 +++ /sys/src/nix/port/mcslock.c Mon Aug 17 05:49:36 2015 @@ -22,7 +22,7 @@ sfence(); /* ensure reader sees updated value */ pred->next = ql; while(monmwait(&ql->locked, 1) == 1) - {} + pause(); } } @@ -42,7 +42,7 @@ if(ql->next != nil || !casp(&lk->head, ql, nil)){ /* successor, wait for list to catch up */ while(ql->next == nil) - {} + monmwaitp(&ql->next, nil); ql->next->locked = 0; sfence(); }