Code drop from //branches/cupcake/...@124589
This commit is contained in:
parent
d245d1d097
commit
7810449ca1
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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+=
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
#define SOCKETLOG
|
||||
//#define SOCKETLOG
|
||||
#endif
|
||||
|
||||
#ifdef SOCKETLOG
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue