From 7810449ca1c0bbb7429188df96eab2dca8fbddca Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 17 Dec 2008 18:05:43 -0800 Subject: [PATCH] Code drop from //branches/cupcake/...@124589 --- include/utils/IPCThreadState.h | 3 ++ include/utils/MemoryHeapPmem.h | 25 ++++++++++++--- include/utils/ResourceTypes.h | 49 ++++++++++++++++++++++------ include/utils/TimeUtils.h | 5 +-- include/utils/string_array.h | 13 ++++++++ libs/utils/Android.mk | 8 +++++ libs/utils/CallStack.cpp | 58 +++++++++++++++++----------------- libs/utils/IPCThreadState.cpp | 27 ++++++++++++++-- libs/utils/LogSocket.cpp | 2 +- libs/utils/MemoryDealer.cpp | 22 +++++++------ libs/utils/MemoryHeapPmem.cpp | 54 +++++++++++++++++++++---------- libs/utils/ResourceTypes.cpp | 41 +++++++++++++++--------- libs/utils/futex_synchro.c | 6 ++-- 13 files changed, 221 insertions(+), 92 deletions(-) diff --git a/include/utils/IPCThreadState.h b/include/utils/IPCThreadState.h index 47043b817..0490fd3ec 100644 --- a/include/utils/IPCThreadState.h +++ b/include/utils/IPCThreadState.h @@ -20,6 +20,7 @@ #include #include #include +#include #ifdef HAVE_WIN32_PROC typedef int uid_t; @@ -92,6 +93,8 @@ private: void* cookie); const sp mProcess; + Vector mPendingStrongDerefs; + Vector mPendingWeakDerefs; Parcel mIn; Parcel mOut; diff --git a/include/utils/MemoryHeapPmem.h b/include/utils/MemoryHeapPmem.h index b694b202a..60335adae 100644 --- a/include/utils/MemoryHeapPmem.h +++ b/include/utils/MemoryHeapPmem.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include namespace android { @@ -31,11 +31,21 @@ class MemoryHeapBase; // --------------------------------------------------------------------------- -class SubRegionMemory; - class MemoryHeapPmem : public HeapInterface, public MemoryHeapBase { public: + class MemoryPmem : public BnMemory { + public: + MemoryPmem(const sp& heap); + ~MemoryPmem(); + protected: + const sp& getHeap() const { return mClientHeap; } + private: + friend class MemoryHeapPmem; + virtual void revoke() = 0; + sp mClientHeap; + }; + MemoryHeapPmem(const sp& pmemHeap, uint32_t flags = IMemoryHeap::MAP_ONCE); ~MemoryHeapPmem(); @@ -51,11 +61,16 @@ public: /* revoke all allocations made by this heap */ virtual void revoke(); - + +private: + /* use this to create your own IMemory for mapMemory */ + virtual sp createMemory(size_t offset, size_t size); + void remove(const wp& memory); + private: sp mParentHeap; mutable Mutex mLock; - Vector< wp > mAllocations; + SortedVector< wp > mAllocations; }; diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index 31b9aa84b..2d56e3e26 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -140,8 +140,6 @@ struct Res_png_9patch void serialize(void* outData); // Deserialize/Unmarshall the patch data static Res_png_9patch* deserialize(const void* data); - // Deserialize/Unmarshall the patch data into a newly malloc-ed block - static void deserialize(const void* data, Res_png_9patch* outData); // Compute the size of the serialized data structure size_t serializedSize(); }; @@ -860,6 +858,7 @@ struct ResTable_config KEYSHIDDEN_ANY = 0x0000, KEYSHIDDEN_NO = 0x0001, KEYSHIDDEN_YES = 0x0002, + KEYSHIDDEN_SOFT = 0x0003, }; union { @@ -989,11 +988,20 @@ struct ResTable_config return diffs; } - // Return true if 'this' is more specific than 'o'. + // Return true if 'this' is more specific than 'o'. Optionally, if + // 'requested' is null, then they will also be compared against the + // requested configuration and true will only be returned if 'this' + // is a better candidate than 'o' for the configuration. This assumes that + // match() has already been used to remove any configurations that don't + // match the requested configuration at all; if they are not first filtered, + // non-matching results can be considered better than matching ones. inline bool isBetterThan(const ResTable_config& o, const ResTable_config* requested = NULL) const { + // The order of the following tests defines the importance of one + // configuration parameter over another. Those tests first are more + // important, trumping any values in those following them. if (imsi != 0 && (!requested || requested->imsi != 0)) { - if (mcc != 0 && (!requested || requested->mcc!= 0)) { + if (mcc != 0 && (!requested || requested->mcc != 0)) { if (o.mcc == 0) { return true; } @@ -1034,9 +1042,24 @@ struct ResTable_config } } if (input != 0 && (!requested || requested->input != 0)) { - if ((inputFlags&MASK_KEYSHIDDEN) != 0 && (!requested - || (requested->inputFlags&MASK_KEYSHIDDEN) != 0)) { - if ((o.inputFlags&MASK_KEYSHIDDEN) == 0) { + const int keysHidden = inputFlags&MASK_KEYSHIDDEN; + const int reqKeysHidden = requested + ? requested->inputFlags&MASK_KEYSHIDDEN : 0; + if (keysHidden != 0 && reqKeysHidden != 0) { + const int oKeysHidden = o.inputFlags&MASK_KEYSHIDDEN; + //LOGI("isBetterThan keysHidden: cur=%d, given=%d, config=%d\n", + // keysHidden, oKeysHidden, reqKeysHidden); + if (oKeysHidden == 0) { + //LOGI("Better because 0!"); + return true; + } + // For compatibility, we count KEYSHIDDEN_NO as being + // the same as KEYSHIDDEN_SOFT. Here we disambiguate these + // may making an exact match more specific. + if (keysHidden == reqKeysHidden && oKeysHidden != reqKeysHidden) { + // The current configuration is an exact match, and + // the given one is not, so the current one is better. + //LOGI("Better because other not same!"); return true; } } @@ -1078,7 +1101,8 @@ struct ResTable_config return false; } - // Return true if 'this' matches the parameters in 'settings'. + // Return true if 'this' can be considered a match for the parameters in + // 'settings'. inline bool match(const ResTable_config& settings) const { if (imsi != 0) { if (settings.mcc != 0 && mcc != 0 @@ -1121,7 +1145,14 @@ struct ResTable_config const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN; if (setKeysHidden != 0 && keysHidden != 0 && keysHidden != setKeysHidden) { - return false; + // For compatibility, we count a request for KEYSHIDDEN_NO as also + // matching the more recent KEYSHIDDEN_SOFT. Basically + // KEYSHIDDEN_NO means there is some kind of keyboard available. + //LOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden); + if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) { + //LOGI("No match!"); + return false; + } } if (settings.keyboard != 0 && keyboard != 0 && keyboard != settings.keyboard) { diff --git a/include/utils/TimeUtils.h b/include/utils/TimeUtils.h index 30e533036..b19e02126 100644 --- a/include/utils/TimeUtils.h +++ b/include/utils/TimeUtils.h @@ -17,10 +17,11 @@ #ifndef ANDROID_TIME_H #define ANDROID_TIME_H +#include +#include #include #include #include -#include #include #include @@ -58,7 +59,7 @@ public: Time(); void switchTimezone(const char *timezone); - String8 format(const char *format) const; + String8 format(const char *format, const struct strftime_locale *locale) const; void format2445(short* buf, bool hasTime) const; String8 toString() const; void setToNow(); diff --git a/include/utils/string_array.h b/include/utils/string_array.h index ede0644cb..064dda224 100644 --- a/include/utils/string_array.h +++ b/include/utils/string_array.h @@ -111,6 +111,19 @@ public: return mArray[idx]; } + // + // Set entry N to specified string. + // [should use operator[] here] + // + void setEntry(int idx, const char* str) { + if (idx < 0 || idx >= mCurrent) + return; + delete[] mArray[idx]; + int len = strlen(str); + mArray[idx] = new char[len+1]; + memcpy(mArray[idx], str, len+1); + } + private: int mMax; int mCurrent; diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk index 4a68dc1f7..cdb8ca2d7 100644 --- a/libs/utils/Android.mk +++ b/libs/utils/Android.mk @@ -139,6 +139,14 @@ LOCAL_SHARED_LIBRARIES := \ liblog \ libcutils +ifneq ($(TARGET_SIMULATOR),true) +ifeq ($(TARGET_OS)-$(TARGET_ARCH),linux-x86) +# This is needed on x86 to bring in dl_iterate_phdr for CallStack.cpp +LOCAL_SHARED_LIBRARIES += \ + libdl +endif # linux-x86 +endif # sim + LOCAL_MODULE:= libutils #LOCAL_CFLAGS+= diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp index 496866673..26fb22abc 100644 --- a/libs/utils/CallStack.cpp +++ b/libs/utils/CallStack.cpp @@ -79,35 +79,35 @@ int backtrace(const void** addrs, size_t ignore, size_t size) /*****************************************************************************/ static -const char *lookup_symbol(const void* addr, uint32_t *offset, char* name, size_t bufSize) +const char *lookup_symbol(const void* addr, void **offset, char* name, size_t bufSize) { #if HAVE_DLADDR - Dl_info info; - if (dladdr(addr, &info)) { - *offset = (uint32_t)info.dli_saddr; - return info.dli_sname; - } + Dl_info info; + if (dladdr(addr, &info)) { + *offset = info.dli_saddr; + return info.dli_sname; + } #endif - return NULL; + return NULL; } static int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize) { - size_t out_len = 0; + size_t out_len = 0; #if HAVE_CXXABI - int status = 0; - char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status); - if (status == 0) { - // OK - if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len); - else out_len = 0; - free(demangled); - } else { - out_len = 0; - } + int status = 0; + char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status); + if (status == 0) { + // OK + if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len); + else out_len = 0; + free(demangled); + } else { + out_len = 0; + } #endif - return out_len; + return out_len; } /*****************************************************************************/ @@ -115,12 +115,12 @@ int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size class MapInfo { struct mapinfo { struct mapinfo *next; - unsigned start; - unsigned end; + uint64_t start; + uint64_t end; char name[]; }; - const char *map_to_name(unsigned pc, const char* def) { + const char *map_to_name(uint64_t pc, const char* def) { mapinfo* mi = getMapInfoList(); while(mi) { if ((pc >= mi->start) && (pc < mi->end)) @@ -139,8 +139,8 @@ class MapInfo { if (line[20] != 'x') return 0; mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47)); if (mi == 0) return 0; - mi->start = strtoul(line, 0, 16); - mi->end = strtoul(line + 9, 0, 16); + mi->start = strtoull(line, 0, 16); + mi->end = strtoull(line + 9, 0, 16); mi->next = 0; strcpy(mi->name, line + 49); return mi; @@ -184,7 +184,7 @@ public: } static const char *mapAddressToName(const void* pc, const char* def) { - return sMapInfo.map_to_name((unsigned)pc, def); + return sMapInfo.map_to_name((uint64_t)pc, def); } }; @@ -278,7 +278,7 @@ String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const char tmp[256]; char tmp1[32]; char tmp2[32]; - uint32_t offs; + void *offs; const void* ip = mStack[level]; if (!ip) return res; @@ -291,14 +291,14 @@ String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const if (name) { if (linux_gcc_demangler(name, tmp, 256) != 0) name = tmp; - snprintf(tmp1, 32, "0x%08x: <", (size_t)ip); - snprintf(tmp2, 32, ">+0x%08x", offs); + snprintf(tmp1, 32, "0x%p: <", ip); + snprintf(tmp2, 32, ">+0x%p", offs); res.append(tmp1); res.append(name); res.append(tmp2); } else { name = MapInfo::mapAddressToName(ip, ""); - snprintf(tmp, 256, "pc %08x %s", (size_t)ip, name); + snprintf(tmp, 256, "pc %p %s", ip, name); res.append(tmp); } res.append("\n"); diff --git a/libs/utils/IPCThreadState.cpp b/libs/utils/IPCThreadState.cpp index ca49d9a5b..04ae1424e 100644 --- a/libs/utils/IPCThreadState.cpp +++ b/libs/utils/IPCThreadState.cpp @@ -391,6 +391,29 @@ void IPCThreadState::joinThreadPool(bool isMain) status_t result; do { int32_t cmd; + + // When we've cleared the incoming command queue, process any pending derefs + if (mIn.dataPosition() >= mIn.dataSize()) { + size_t numPending = mPendingWeakDerefs.size(); + if (numPending > 0) { + for (size_t i = 0; i < numPending; i++) { + RefBase::weakref_type* refs = mPendingWeakDerefs[i]; + refs->decWeak(mProcess.get()); + } + mPendingWeakDerefs.clear(); + } + + numPending = mPendingStrongDerefs.size(); + if (numPending > 0) { + for (size_t i = 0; i < numPending; i++) { + BBinder* obj = mPendingStrongDerefs[i]; + obj->decStrong(mProcess.get()); + } + mPendingStrongDerefs.clear(); + } + } + + // now get the next command to be processed, waiting if necessary result = talkWithDriver(); if (result >= NO_ERROR) { size_t IN = mIn.dataAvail(); @@ -832,7 +855,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj); obj->printRefs(); } - obj->decStrong(mProcess.get()); + mPendingStrongDerefs.push(obj); break; case BR_INCREFS: @@ -853,7 +876,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd) //LOG_ASSERT(refs->refBase() == obj, // "BR_DECREFS: object %p does not match cookie %p (expected %p)", // refs, obj, refs->refBase()); - refs->decWeak(mProcess.get()); + mPendingWeakDerefs.push(refs); break; case BR_ATTEMPT_ACQUIRE: diff --git a/libs/utils/LogSocket.cpp b/libs/utils/LogSocket.cpp index e64f794a8..55c1b99af 100644 --- a/libs/utils/LogSocket.cpp +++ b/libs/utils/LogSocket.cpp @@ -16,7 +16,7 @@ #ifndef HAVE_WINSOCK -#define SOCKETLOG +//#define SOCKETLOG #endif #ifdef SOCKETLOG diff --git a/libs/utils/MemoryDealer.cpp b/libs/utils/MemoryDealer.cpp index e6d1d180f..cf8201b85 100644 --- a/libs/utils/MemoryDealer.cpp +++ b/libs/utils/MemoryDealer.cpp @@ -387,21 +387,23 @@ SimpleMemory::~SimpleMemory() start = (start + pagesize-1) & ~(pagesize-1); end &= ~(pagesize-1); - void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start); - size_t size = end-start; + if (start < end) { + void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + start); + size_t size = end-start; #ifndef NDEBUG - memset(start_ptr, 0xdf, size); + memset(start_ptr, 0xdf, size); #endif - -// MADV_REMOVE is not defined on Dapper based Goobuntu + + // MADV_REMOVE is not defined on Dapper based Goobuntu #ifdef MADV_REMOVE - if (size) { - int err = madvise(start_ptr, size, MADV_REMOVE); - LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s", - start_ptr, size, err<0 ? strerror(errno) : "Ok"); - } + if (size) { + int err = madvise(start_ptr, size, MADV_REMOVE); + LOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s", + start_ptr, size, err<0 ? strerror(errno) : "Ok"); + } #endif + } } }; // namespace android diff --git a/libs/utils/MemoryHeapPmem.cpp b/libs/utils/MemoryHeapPmem.cpp index 1e5a1cc96..eba2b3055 100644 --- a/libs/utils/MemoryHeapPmem.cpp +++ b/libs/utils/MemoryHeapPmem.cpp @@ -38,9 +38,20 @@ namespace android { // --------------------------------------------------------------------------- -class MemoryHeapPmem; +MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp& heap) + : BnMemory(), mClientHeap(heap) +{ +} -class SubRegionMemory : public BnMemory { +MemoryHeapPmem::MemoryPmem::~MemoryPmem() { + if (mClientHeap != NULL) { + mClientHeap->remove(this); + } +} + +// --------------------------------------------------------------------------- + +class SubRegionMemory : public MemoryHeapPmem::MemoryPmem { public: SubRegionMemory(const sp& heap, ssize_t offset, size_t size); virtual ~SubRegionMemory(); @@ -50,15 +61,14 @@ private: void revoke(); size_t mSize; ssize_t mOffset; - sp mClientHeap; }; SubRegionMemory::SubRegionMemory(const sp& heap, ssize_t offset, size_t size) - : mSize(size), mOffset(offset), mClientHeap(heap) + : MemoryHeapPmem::MemoryPmem(heap), mSize(size), mOffset(offset) { #ifndef NDEBUG - void* const start_ptr = (void*)(intptr_t(mClientHeap->base()) + offset); + void* const start_ptr = (void*)(intptr_t(getHeap()->base()) + offset); memset(start_ptr, 0xda, size); #endif @@ -80,7 +90,7 @@ sp SubRegionMemory::getMemory(ssize_t* offset, size_t* size) const { if (offset) *offset = mOffset; if (size) *size = mSize; - return mClientHeap; + return getHeap(); } SubRegionMemory::~SubRegionMemory() @@ -98,8 +108,9 @@ void SubRegionMemory::revoke() // promote() it. #if HAVE_ANDROID_OS - if (mClientHeap != NULL) { - int our_fd = mClientHeap->heapID(); + if (mSize != NULL) { + const sp& heap(getHeap()); + int our_fd = heap->heapID(); struct pmem_region sub; sub.offset = mOffset; sub.len = mSize; @@ -107,7 +118,7 @@ void SubRegionMemory::revoke() LOGE_IF(err<0, "PMEM_UNMAP failed (%s), " "mFD=%d, sub.offset=%lu, sub.size=%lu", strerror(errno), our_fd, sub.offset, sub.len); - mClientHeap.clear(); + mSize = 0; } #endif } @@ -157,10 +168,7 @@ MemoryHeapPmem::~MemoryHeapPmem() sp MemoryHeapPmem::mapMemory(size_t offset, size_t size) { - sp memory; - if (heapID() > 0) - memory = new SubRegionMemory(this, offset, size); - + sp memory = createMemory(offset, size); if (memory != 0) { Mutex::Autolock _l(mLock); mAllocations.add(memory); @@ -168,6 +176,15 @@ sp MemoryHeapPmem::mapMemory(size_t offset, size_t size) return memory; } +sp MemoryHeapPmem::createMemory( + size_t offset, size_t size) +{ + sp memory; + if (heapID() > 0) + memory = new SubRegionMemory(this, offset, size); + return memory; +} + status_t MemoryHeapPmem::slap() { #if HAVE_ANDROID_OS @@ -206,21 +223,26 @@ status_t MemoryHeapPmem::unslap() void MemoryHeapPmem::revoke() { - Vector< wp > allocations; + SortedVector< wp > allocations; { // scope for lock Mutex::Autolock _l(mLock); allocations = mAllocations; - mAllocations.clear(); } ssize_t count = allocations.size(); for (ssize_t i=0 ; i memory(allocations[i].promote()); + sp memory(allocations[i].promote()); if (memory != 0) memory->revoke(); } } +void MemoryHeapPmem::remove(const wp& memory) +{ + Mutex::Autolock _l(mLock); + mAllocations.remove(memory); +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index a5fe9fba5..5a09fb44a 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -164,7 +164,11 @@ void Res_png_9patch::fileToDevice() size_t Res_png_9patch::serializedSize() { - return sizeof(Res_png_9patch) + // The size of this struct is 32 bytes on the 32-bit target system + // 4 * int8_t + // 4 * int32_t + // 3 * pointer + return 32 + numXDivs * sizeof(int32_t) + numYDivs * sizeof(int32_t) + numColors * sizeof(uint32_t); @@ -180,8 +184,10 @@ void* Res_png_9patch::serialize() void Res_png_9patch::serialize(void * outData) { char* data = (char*) outData; - memmove(data, this, sizeof(Res_png_9patch)); - data += sizeof(Res_png_9patch); + memmove(data, &wasDeserialized, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors + memmove(data + 12, &paddingLeft, 16); // copy paddingXXXX + data += 32; + memmove(data, this->xDivs, numXDivs * sizeof(int32_t)); data += numXDivs * sizeof(int32_t); memmove(data, this->yDivs, numYDivs * sizeof(int32_t)); @@ -189,27 +195,32 @@ void Res_png_9patch::serialize(void * outData) memmove(data, this->colors, numColors * sizeof(uint32_t)); } -Res_png_9patch* Res_png_9patch::deserialize(const void* inData) -{ - deserialize(inData, (Res_png_9patch*) inData); - return (Res_png_9patch*) inData; -} - -void Res_png_9patch::deserialize(const void* inData, Res_png_9patch* outData) { - Res_png_9patch* patch = (Res_png_9patch*) inData; +static void deserializeInternal(const void* inData, Res_png_9patch* outData) { + char* patch = (char*) inData; if (inData != outData) { - memcpy(outData, inData, patch->serializedSize()); + memmove(&outData->wasDeserialized, patch, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors + memmove(&outData->paddingLeft, patch + 12, 4); // copy wasDeserialized, numXDivs, numYDivs, numColors } outData->wasDeserialized = true; char* data = (char*)outData; data += sizeof(Res_png_9patch); outData->xDivs = (int32_t*) data; - data += patch->numXDivs * sizeof(int32_t); + data += outData->numXDivs * sizeof(int32_t); outData->yDivs = (int32_t*) data; - data += patch->numYDivs * sizeof(int32_t); + data += outData->numYDivs * sizeof(int32_t); outData->colors = (uint32_t*) data; } +Res_png_9patch* Res_png_9patch::deserialize(const void* inData) +{ + if (sizeof(void*) != sizeof(int32_t)) { + LOGE("Cannot deserialize on non 32-bit system\n"); + return NULL; + } + deserializeInternal(inData, (Res_png_9patch*) inData); + return (Res_png_9patch*) inData; +} + // -------------------------------------------------------------------- // -------------------------------------------------------------------- // -------------------------------------------------------------------- @@ -3863,7 +3874,7 @@ void ResTable::print() const } for (size_t configIndex=0; configIndexconfigs[configIndex]; - if ((((int)type)&0x3) != 0) { + if ((((uint64_t)type)&0x3) != 0) { printf(" NON-INTEGER ResTable_type ADDRESS: %p\n", type); continue; } diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c index c13760d77..ba1952033 100644 --- a/libs/utils/futex_synchro.c +++ b/libs/utils/futex_synchro.c @@ -25,8 +25,8 @@ #include -// This futex glue code is need on desktop linux, but is part of klibc on ARM -#if !defined(__arm__) +// This futex glue code is need on desktop linux, but is already part of bionic. +#if !defined(HAVE_FUTEX_WRAPPERS) #include typedef unsigned int u32; @@ -76,7 +76,7 @@ int __atomic_cmpxchg(int old, int _new, volatile int *ptr); int __atomic_swap(int _new, volatile int *ptr); int __atomic_dec(volatile int *ptr); -#endif // !defined(__arm__) +#endif // !defined(HAVE_FUTEX_WRAPPERS) // lock states