Home | History | Annotate | Download | only in src
      1 /*
      2  * one_time_construction.cpp
      3  *
      4  * Copyright 2006 The Android Open Source Project
      5  *
      6  * This file contains C++ ABI support functions for one time
      7  * constructors as defined in the "Run-time ABI for the ARM Architecture"
      8  * section 4.4.2
      9  */
     10 
     11 #include <stddef.h>
     12 #include <sys/atomics.h>
     13 #include <bionic_futex.h>
     14 #include <bionic_atomic_inline.h>
     15 
     16 extern "C" int __cxa_guard_acquire(int volatile * gv)
     17 {
     18     // 0 -> 2, return 1
     19     // 2 -> 6, wait and return 0
     20     // 6 untouched, wait and return 0
     21     // 1 untouched, return 0
     22 retry:
     23     if (__atomic_cmpxchg(0, 0x2, gv) == 0) {
     24         ANDROID_MEMBAR_FULL();
     25         return 1;
     26     }
     27     __atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter
     28     __futex_wait(gv, 0x6, NULL);
     29 
     30     if(*gv != 1) // __cxa_guard_abort was called, let every thread try since there is no return code for this condition
     31         goto retry;
     32 
     33     ANDROID_MEMBAR_FULL();
     34     return 0;
     35 }
     36 
     37 extern "C" void __cxa_guard_release(int volatile * gv)
     38 {
     39     // 2 -> 1
     40     // 6 -> 1, and wake
     41     ANDROID_MEMBAR_FULL();
     42     if (__atomic_cmpxchg(0x2, 0x1, gv) == 0) {
     43         return;
     44     }
     45 
     46     *gv = 0x1;
     47     __futex_wake(gv, 0x7fffffff);
     48 }
     49 
     50 extern "C" void __cxa_guard_abort(int volatile * gv)
     51 {
     52     ANDROID_MEMBAR_FULL();
     53     *gv = 0;
     54     __futex_wake(gv, 0x7fffffff);
     55 }
     56