blob: 304afb808c3cf3ae37c22976905d9d462925cbc0 [file] [log] [blame]
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08001/*
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
14extern "C" int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
15extern "C" int __futex_wake(volatile void *ftx, int count);
16
17
18extern "C" int __cxa_guard_acquire(int volatile * gv)
19{
20 // 0 -> 2, return 1
21 // 2 -> 6, wait and return 0
22 // 6 untouched, wait and return 0
23 // 1 untouched, return 0
24retry:
25 if (__atomic_cmpxchg(0, 0x2, gv) == 0)
26 return 1;
27
28 __atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter
29 __futex_wait(gv, 0x6, NULL);
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 return 0;
33}
34
35extern "C" void __cxa_guard_release(int volatile * gv)
36{
37 // 2 -> 1
38 // 6 -> 1, and wake
39 if (__atomic_cmpxchg(0x2, 0x1, gv) == 0)
40 return;
41
42 *gv = 0x1;
43 __futex_wake(gv, 0x7fffffff);
44}
45
46extern "C" void __cxa_guard_abort(int volatile * gv)
47{
48 *gv = 0;
49 __futex_wake(gv, 0x7fffffff);
50}