diff options
Diffstat (limited to 'libs/utils')
-rw-r--r-- | libs/utils/Android.mk | 8 | ||||
-rw-r--r-- | libs/utils/CallStack.cpp | 58 | ||||
-rw-r--r-- | libs/utils/IPCThreadState.cpp | 27 | ||||
-rw-r--r-- | libs/utils/LogSocket.cpp | 2 | ||||
-rw-r--r-- | libs/utils/MemoryDealer.cpp | 22 | ||||
-rw-r--r-- | libs/utils/MemoryHeapPmem.cpp | 54 | ||||
-rw-r--r-- | libs/utils/ResourceTypes.cpp | 41 | ||||
-rw-r--r-- | libs/utils/futex_synchro.c | 6 |
8 files changed, 142 insertions, 76 deletions
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk index 4a68dc1..cdb8ca2 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 4968666..26fb22a 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, "<unknown>"); - 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 ca49d9a..04ae142 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 e64f794..55c1b99 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 e6d1d18..cf8201b 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 1e5a1cc..eba2b30 100644 --- a/libs/utils/MemoryHeapPmem.cpp +++ b/libs/utils/MemoryHeapPmem.cpp @@ -38,9 +38,20 @@ namespace android { // --------------------------------------------------------------------------- -class MemoryHeapPmem; +MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& heap) + : BnMemory(), mClientHeap(heap) +{ +} + +MemoryHeapPmem::MemoryPmem::~MemoryPmem() { + if (mClientHeap != NULL) { + mClientHeap->remove(this); + } +} -class SubRegionMemory : public BnMemory { +// --------------------------------------------------------------------------- + +class SubRegionMemory : public MemoryHeapPmem::MemoryPmem { public: SubRegionMemory(const sp<MemoryHeapPmem>& heap, ssize_t offset, size_t size); virtual ~SubRegionMemory(); @@ -50,15 +61,14 @@ private: void revoke(); size_t mSize; ssize_t mOffset; - sp<MemoryHeapPmem> mClientHeap; }; SubRegionMemory::SubRegionMemory(const sp<MemoryHeapPmem>& 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<IMemoryHeap> 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<MemoryHeapPmem>& 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<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size) { - sp<SubRegionMemory> memory; - if (heapID() > 0) - memory = new SubRegionMemory(this, offset, size); - + sp<MemoryPmem> memory = createMemory(offset, size); if (memory != 0) { Mutex::Autolock _l(mLock); mAllocations.add(memory); @@ -168,6 +176,15 @@ sp<IMemory> MemoryHeapPmem::mapMemory(size_t offset, size_t size) return memory; } +sp<MemoryHeapPmem::MemoryPmem> MemoryHeapPmem::createMemory( + size_t offset, size_t size) +{ + sp<SubRegionMemory> 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<SubRegionMemory> > allocations; + SortedVector< wp<MemoryPmem> > allocations; { // scope for lock Mutex::Autolock _l(mLock); allocations = mAllocations; - mAllocations.clear(); } ssize_t count = allocations.size(); for (ssize_t i=0 ; i<count ; i++) { - sp<SubRegionMemory> memory(allocations[i].promote()); + sp<MemoryPmem> memory(allocations[i].promote()); if (memory != 0) memory->revoke(); } } +void MemoryHeapPmem::remove(const wp<MemoryPmem>& memory) +{ + Mutex::Autolock _l(mLock); + mAllocations.remove(memory); +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index a5fe9fb..5a09fb4 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; configIndex<NTC; configIndex++) { const ResTable_type* type = typeConfigs->configs[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 c13760d..ba19520 100644 --- a/libs/utils/futex_synchro.c +++ b/libs/utils/futex_synchro.c @@ -25,8 +25,8 @@ #include <private/utils/futex_synchro.h> -// 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 <sys/syscall.h> 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 |