Add missing SMP barriers to libstdc++
Change-Id: I20a8dcd2e3316ac60237e800c682cacc8e59e187
This commit is contained in:
parent
519763265e
commit
d466780c7c
2 changed files with 27 additions and 7 deletions
|
@ -1,4 +1,15 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
# Common C++ flags to build this library.
|
||||
# Note that we need to access private Bionic headers
|
||||
# and define ANDROID_SMP accordingly.
|
||||
libstdc++_cflags := -Ibionic/libc/private
|
||||
ifeq ($(TARGET_CPU_SMP),true)
|
||||
libstdc++_cflags += -DANDROID_SMP=1
|
||||
else
|
||||
libstdc++_cflags += -DANDROID_SMP=0
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
|
@ -9,6 +20,8 @@ LOCAL_SRC_FILES:= \
|
|||
|
||||
LOCAL_MODULE:= libstdc++
|
||||
|
||||
LOCAL_CFLAGS := $(libstdc++_cflags)
|
||||
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
@ -21,6 +34,8 @@ LOCAL_SRC_FILES:= \
|
|||
src/pure_virtual.cpp \
|
||||
src/typeinfo.cpp
|
||||
|
||||
LOCAL_CFLAGS := $(libstdc++_cflags)
|
||||
|
||||
LOCAL_MODULE:= libstdc++
|
||||
|
||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||
|
|
|
@ -10,10 +10,8 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <sys/atomics.h>
|
||||
|
||||
extern "C" int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
|
||||
extern "C" int __futex_wake(volatile void *ftx, int count);
|
||||
|
||||
#include <bionic_futex.h>
|
||||
#include <bionic_atomic_inline.h>
|
||||
|
||||
extern "C" int __cxa_guard_acquire(int volatile * gv)
|
||||
{
|
||||
|
@ -22,13 +20,17 @@ extern "C" int __cxa_guard_acquire(int volatile * gv)
|
|||
// 6 untouched, wait and return 0
|
||||
// 1 untouched, return 0
|
||||
retry:
|
||||
if (__atomic_cmpxchg(0, 0x2, gv) == 0)
|
||||
if (__atomic_cmpxchg(0, 0x2, gv) == 0) {
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 1;
|
||||
|
||||
}
|
||||
__atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter
|
||||
__futex_wait(gv, 0x6, NULL);
|
||||
|
||||
if(*gv != 1) // __cxa_guard_abort was called, let every thread try since there is no return code for this condition
|
||||
goto retry;
|
||||
|
||||
ANDROID_MEMBAR_FULL();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -36,8 +38,10 @@ extern "C" void __cxa_guard_release(int volatile * gv)
|
|||
{
|
||||
// 2 -> 1
|
||||
// 6 -> 1, and wake
|
||||
if (__atomic_cmpxchg(0x2, 0x1, gv) == 0)
|
||||
ANDROID_MEMBAR_FULL();
|
||||
if (__atomic_cmpxchg(0x2, 0x1, gv) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
*gv = 0x1;
|
||||
__futex_wake(gv, 0x7fffffff);
|
||||
|
@ -45,6 +49,7 @@ extern "C" void __cxa_guard_release(int volatile * gv)
|
|||
|
||||
extern "C" void __cxa_guard_abort(int volatile * gv)
|
||||
{
|
||||
ANDROID_MEMBAR_FULL();
|
||||
*gv = 0;
|
||||
__futex_wake(gv, 0x7fffffff);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue