Code drop from //branches/cupcake/...@124589

This commit is contained in:
The Android Open Source Project 2008-12-17 18:05:43 -08:00 committed by Alex Ray
parent d245d1d097
commit 7810449ca1
13 changed files with 221 additions and 92 deletions

View File

@ -20,6 +20,7 @@
#include <utils/Errors.h>
#include <utils/Parcel.h>
#include <utils/ProcessState.h>
#include <utils/Vector.h>
#ifdef HAVE_WIN32_PROC
typedef int uid_t;
@ -92,6 +93,8 @@ private:
void* cookie);
const sp<ProcessState> mProcess;
Vector<BBinder*> mPendingStrongDerefs;
Vector<RefBase::weakref_type*> mPendingWeakDerefs;
Parcel mIn;
Parcel mOut;

View File

@ -23,7 +23,7 @@
#include <utils/MemoryDealer.h>
#include <utils/MemoryHeapBase.h>
#include <utils/IMemory.h>
#include <utils/Vector.h>
#include <utils/SortedVector.h>
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<MemoryHeapPmem>& heap);
~MemoryPmem();
protected:
const sp<MemoryHeapPmem>& getHeap() const { return mClientHeap; }
private:
friend class MemoryHeapPmem;
virtual void revoke() = 0;
sp<MemoryHeapPmem> mClientHeap;
};
MemoryHeapPmem(const sp<MemoryHeapBase>& 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<MemoryPmem> createMemory(size_t offset, size_t size);
void remove(const wp<MemoryPmem>& memory);
private:
sp<MemoryHeapBase> mParentHeap;
mutable Mutex mLock;
Vector< wp<SubRegionMemory> > mAllocations;
SortedVector< wp<MemoryPmem> > mAllocations;
};

View File

@ -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) {

View File

@ -17,10 +17,11 @@
#ifndef ANDROID_TIME_H
#define ANDROID_TIME_H
#include <time.h>
#include <cutils/tztime.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <utils/String8.h>
#include <utils/String16.h>
@ -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();

View File

@ -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;

View File

@ -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+=

View File

@ -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");

View File

@ -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:

View File

@ -16,7 +16,7 @@
#ifndef HAVE_WINSOCK
#define SOCKETLOG
//#define SOCKETLOG
#endif
#ifdef SOCKETLOG

View File

@ -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

View File

@ -38,9 +38,20 @@ namespace android {
// ---------------------------------------------------------------------------
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 @@ 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

View File

@ -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;
}

View File

@ -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