diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2010-05-18 22:56:14 -0500 |
---|---|---|
committer | Patrick Williams <iawillia@us.ibm.com> | 2010-05-18 22:56:14 -0500 |
commit | 78f5edabe6fd21f55ddff82f978a1b5d46d62ffa (patch) | |
tree | 1cb033e2447c993c7aada1ff8b6147ed0134f2bb | |
parent | cf138201c24fdc83ee7835b65cce67e7d7a85e70 (diff) | |
download | talos-hostboot-78f5edabe6fd21f55ddff82f978a1b5d46d62ffa.tar.gz talos-hostboot-78f5edabe6fd21f55ddff82f978a1b5d46d62ffa.zip |
Add thread safe guard variable code.
-rw-r--r-- | src/kernel/kernel.C | 2 | ||||
-rw-r--r-- | src/libc++/builtins.C | 39 |
2 files changed, 27 insertions, 14 deletions
diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C index fede83f02..476c5ba35 100644 --- a/src/kernel/kernel.C +++ b/src/kernel/kernel.C @@ -3,7 +3,7 @@ int main() { - printk("Welcome to the kernel!\n"); + printk("Booting Chenoo kernel...\n"); while(1); return 0; diff --git a/src/libc++/builtins.C b/src/libc++/builtins.C index ed373c8cc..70c9fcc35 100644 --- a/src/libc++/builtins.C +++ b/src/libc++/builtins.C @@ -2,25 +2,38 @@ extern "C" int __cxa_guard_acquire(volatile uint64_t* gv) { - // 0 .. uninitialized - // 1 .. locked - // 2 .. unlocked, initialized - if (0 == *gv) - { - *gv = 1; - return 1; - } - else if (1 == *gv) + // 0 -> uninitialized + // 1 -> locked + // 2 -> unlocked and initialized + + register volatile void* guard = gv; + register uint32_t c = 0; + + asm volatile( + "__cxa_guard_acquire_begin:" + "lwarx %0,0,%1;" // Load guard with reserve + "cmpi 0,%0,0;" // Compare with 0 + "bne+ __cxa_guard_acquire_finish;" // != 0, goto "finished" + "li %0, 1;" // Set to 1. + "stwcx. %0,0,%1;" // Store against reserve + "bne- __cxa_guard_acquire_begin;" // goto begin if failed store. + "li %0, 3;" // Set to 3 -> success in lock + "__cxa_guard_acquire_finish:" + : "+r" (c) : "r" (guard): "memory","cc" + ); + while (2 > c) { - while(1 == *gv); + asm volatile("lwz %0, 0(%1);" : "=r" (c) : "r" (guard)); } - - return 0; + return (3 == c ? 1 : 0); // 3 means success in lock, return 1 (obtained) + // 2 means initialized, return 0 } extern "C" void __cxa_guard_release(volatile uint64_t* gv) { - *gv = 2; + register volatile void* guard = gv; + register uint32_t c = 2; + asm volatile("stw %0, 0(%1)" :: "r"(c) , "r" (guard): "memory"); return; } |