one_time_construction.cpp revision d466780c7cedb41edcf13f28ad900556c6aaa5b2
11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * one_time_construction.cpp 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright 2006 The Android Open Source Project 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This file contains C++ ABI support functions for one time 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * constructors as defined in the "Run-time ABI for the ARM Architecture" 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * section 4.4.2 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stddef.h> 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/atomics.h> 13d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner#include <bionic_futex.h> 14d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner#include <bionic_atomic_inline.h> 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern "C" int __cxa_guard_acquire(int volatile * gv) 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // 0 -> 2, return 1 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // 2 -> 6, wait and return 0 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // 6 untouched, wait and return 0 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // 1 untouched, return 0 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectretry: 23d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner if (__atomic_cmpxchg(0, 0x2, gv) == 0) { 24d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner ANDROID_MEMBAR_FULL(); 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 1; 26d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner } 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __futex_wait(gv, 0x6, NULL); 29d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(*gv != 1) // __cxa_guard_abort was called, let every thread try since there is no return code for this condition 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project goto retry; 32d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner 33d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner ANDROID_MEMBAR_FULL(); 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return 0; 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern "C" void __cxa_guard_release(int volatile * gv) 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // 2 -> 1 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project // 6 -> 1, and wake 41d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner ANDROID_MEMBAR_FULL(); 42d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner if (__atomic_cmpxchg(0x2, 0x1, gv) == 0) { 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return; 44d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner } 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gv = 0x1; 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __futex_wake(gv, 0x7fffffff); 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectextern "C" void __cxa_guard_abort(int volatile * gv) 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 52d466780c7cedb41edcf13f28ad900556c6aaa5b2David 'Digit' Turner ANDROID_MEMBAR_FULL(); 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *gv = 0; 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project __futex_wake(gv, 0x7fffffff); 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 56