summaryrefslogtreecommitdiffstats
path: root/src/libc++
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2010-05-18 22:56:14 -0500
committerPatrick Williams <iawillia@us.ibm.com>2010-05-18 22:56:14 -0500
commit78f5edabe6fd21f55ddff82f978a1b5d46d62ffa (patch)
tree1cb033e2447c993c7aada1ff8b6147ed0134f2bb /src/libc++
parentcf138201c24fdc83ee7835b65cce67e7d7a85e70 (diff)
downloadtalos-hostboot-78f5edabe6fd21f55ddff82f978a1b5d46d62ffa.tar.gz
talos-hostboot-78f5edabe6fd21f55ddff82f978a1b5d46d62ffa.zip
Add thread safe guard variable code.
Diffstat (limited to 'src/libc++')
-rw-r--r--src/libc++/builtins.C39
1 files changed, 26 insertions, 13 deletions
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;
}
OpenPOWER on IntegriCloud