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)
|
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)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES:= \
|
LOCAL_SRC_FILES:= \
|
||||||
|
@ -9,6 +20,8 @@ LOCAL_SRC_FILES:= \
|
||||||
|
|
||||||
LOCAL_MODULE:= libstdc++
|
LOCAL_MODULE:= libstdc++
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := $(libstdc++_cflags)
|
||||||
|
|
||||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
@ -21,6 +34,8 @@ LOCAL_SRC_FILES:= \
|
||||||
src/pure_virtual.cpp \
|
src/pure_virtual.cpp \
|
||||||
src/typeinfo.cpp
|
src/typeinfo.cpp
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := $(libstdc++_cflags)
|
||||||
|
|
||||||
LOCAL_MODULE:= libstdc++
|
LOCAL_MODULE:= libstdc++
|
||||||
|
|
||||||
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
LOCAL_SYSTEM_SHARED_LIBRARIES := libc
|
||||||
|
|
|
@ -10,10 +10,8 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <sys/atomics.h>
|
#include <sys/atomics.h>
|
||||||
|
#include <bionic_futex.h>
|
||||||
extern "C" int __futex_wait(volatile void *ftx, int val, const struct timespec *timeout);
|
#include <bionic_atomic_inline.h>
|
||||||
extern "C" int __futex_wake(volatile void *ftx, int count);
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" int __cxa_guard_acquire(int volatile * gv)
|
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
|
// 6 untouched, wait and return 0
|
||||||
// 1 untouched, return 0
|
// 1 untouched, return 0
|
||||||
retry:
|
retry:
|
||||||
if (__atomic_cmpxchg(0, 0x2, gv) == 0)
|
if (__atomic_cmpxchg(0, 0x2, gv) == 0) {
|
||||||
|
ANDROID_MEMBAR_FULL();
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
__atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter
|
__atomic_cmpxchg(0x2, 0x6, gv); // Indicate there is a waiter
|
||||||
__futex_wait(gv, 0x6, NULL);
|
__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
|
if(*gv != 1) // __cxa_guard_abort was called, let every thread try since there is no return code for this condition
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
|
ANDROID_MEMBAR_FULL();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +38,10 @@ extern "C" void __cxa_guard_release(int volatile * gv)
|
||||||
{
|
{
|
||||||
// 2 -> 1
|
// 2 -> 1
|
||||||
// 6 -> 1, and wake
|
// 6 -> 1, and wake
|
||||||
if (__atomic_cmpxchg(0x2, 0x1, gv) == 0)
|
ANDROID_MEMBAR_FULL();
|
||||||
|
if (__atomic_cmpxchg(0x2, 0x1, gv) == 0) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
*gv = 0x1;
|
*gv = 0x1;
|
||||||
__futex_wake(gv, 0x7fffffff);
|
__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)
|
extern "C" void __cxa_guard_abort(int volatile * gv)
|
||||||
{
|
{
|
||||||
|
ANDROID_MEMBAR_FULL();
|
||||||
*gv = 0;
|
*gv = 0;
|
||||||
__futex_wake(gv, 0x7fffffff);
|
__futex_wake(gv, 0x7fffffff);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue