From d466780c7cedb41edcf13f28ad900556c6aaa5b2 Mon Sep 17 00:00:00 2001 From: David 'Digit' Turner Date: Fri, 11 Jun 2010 13:18:41 -0700 Subject: Add missing SMP barriers to libstdc++ Change-Id: I20a8dcd2e3316ac60237e800c682cacc8e59e187 --- libstdc++/Android.mk | 15 +++++++++++++++ libstdc++/src/one_time_construction.cpp | 19 ++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) (limited to 'libstdc++') diff --git a/libstdc++/Android.mk b/libstdc++/Android.mk index df97c9f..8bc181f 100644 --- a/libstdc++/Android.mk +++ b/libstdc++/Android.mk @@ -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 diff --git a/libstdc++/src/one_time_construction.cpp b/libstdc++/src/one_time_construction.cpp index 304afb8..2a44c79 100644 --- a/libstdc++/src/one_time_construction.cpp +++ b/libstdc++/src/one_time_construction.cpp @@ -10,10 +10,8 @@ #include #include - -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 +#include 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); } -- cgit v1.1