From: NIIBE Y. <gn...@m1...> - 2002-05-22 02:27:34
|
Here's experimental patch to support user space atomicity emulation (this is for 2.4.18). Please see this: http://sources.redhat.com/ml/libc-hacker/2002-05/msg00029.html It explains how gUSA works. I believe that this does _not_ impact performance. Comments are welcome. 2002-05-22 NIIBE Yutaka <gn...@m1...> gUSA ("g" User Space Atomicity) support. * arch/sh/kernel/signal.c (handle_signal): Added gUSA handling. * arch/sh/kernel/entry.S (reschedule): Added gUSA handling. Index: arch/sh/kernel/entry.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/entry.S,v retrieving revision 1.1.1.1.2.4 diff -u -3 -p -r1.1.1.1.2.4 entry.S --- arch/sh/kernel/entry.S 10 May 2002 17:58:54 -0000 1.1.1.1.2.4 +++ arch/sh/kernel/entry.S 22 May 2002 02:15:26 -0000 @@ -94,6 +94,7 @@ OFF_R5 = 20 /* New ABI: ar OFF_R6 = 24 /* New ABI: arg2 */ OFF_R7 = 28 /* New ABI: arg3 */ OFF_SP = (15*4) +OFF_PC = (16*4) OFF_SR = (16*4+8) OFF_TRA = (16*4+6*4) @@ -455,12 +456,24 @@ __INV_IMASK: .align 2 reschedule: - mova SYMBOL_NAME(ret_from_syscall), r0 - mov.l 1f, r1 - jmp @r1 + ! gUSA handling + mov.l @(OFF_SP,r15), r1 ! get user space stack pointer + cmp/pz r1 + bt/s 1f + mov.l 2f, r4 + mov #OFF_PC, r0 + mov.l @(r0,r15), r2 ! get user space PC (program counter) + mov.l @(OFF_R0,r15), r3 ! end point + cmp/hs r3, r2 ! r2 >= r3? + bt 1f + add r2, r1 ! reentrance point #2 + mov.l r1, @(r0,r15) ! reset PC to reentrance point #2 + ! +1: mova SYMBOL_NAME(ret_from_syscall), r0 + jmp @r4 lds r0, pr .align 2 -1: .long SYMBOL_NAME(schedule) +2: .long SYMBOL_NAME(schedule) ret_from_irq: ret_from_exception: Index: arch/sh/kernel/signal.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/signal.c,v retrieving revision 1.1.1.1.2.1 diff -u -3 -p -r1.1.1.1.2.1 signal.c --- arch/sh/kernel/signal.c 29 Mar 2002 00:01:07 -0000 1.1.1.1.2.1 +++ arch/sh/kernel/signal.c 22 May 2002 02:15:26 -0000 @@ -533,6 +533,17 @@ handle_signal(unsigned long sig, struct case -ERESTARTNOINTR: regs->pc -= 2; } + } else { + /* gUSA handling */ + if (regs->regs[15] >= 0x80000000) { + int offset = (int)regs->regs[15]; + + /* Reset stack pointer: clear critical region mark */ + regs->regs[15] = regs->regs[1]; + if (regs->pc < regs->regs[0]) + /* Go to reentrance point #1 */ + regs->pc = regs->regs[0] + offset - 2; + } } /* Set up the stack frame */ |