Code drop from //branches/cupcake/...@124589
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 @@
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 @@
/*****************************************************************************/
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
//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 @@
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 @@
// ---------------------------------------------------------------------------
-class MemoryHeapPmem;
+MemoryHeapPmem::MemoryPmem::MemoryPmem(const sp<MemoryHeapPmem>& 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<MemoryHeapPmem>& heap, ssize_t offset, size_t size);
virtual ~SubRegionMemory();
@@ -50,15 +61,14 @@
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 @@
{
if (offset) *offset = mOffset;
if (size) *size = mSize;
- return mClientHeap;
+ return getHeap();
}
SubRegionMemory::~SubRegionMemory()
@@ -98,8 +108,9 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 * 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 @@
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 @@
}
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_swap(int _new, volatile int *ptr);
int __atomic_dec(volatile int *ptr);
-#endif // !defined(__arm__)
+#endif // !defined(HAVE_FUTEX_WRAPPERS)
// lock states