19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "IMemory" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdint.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/mman.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 280795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IMemory.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/KeyedVector.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h> 320795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/Parcel.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/CallStack.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define VERBOSE 0 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass HeapCache : public IBinder::DeathRecipient 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HeapCache(); 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual ~HeapCache(); 45f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void binderDied(const wp<IBinder>& who); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 49f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan void free_heap(const sp<IBinder>& binder); 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> get_heap(const sp<IBinder>& binder); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump_heaps(); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For IMemory.cpp 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct heap_info_t { 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> heap; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t count; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 60f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan void free_heap(const wp<IBinder>& binder); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex mHeapCacheLock; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyedVector< wp<IBinder>, heap_info_t > mHeapCache; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic sp<HeapCache> gHeapCache = new HeapCache(); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/******************************************************************************/ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HEAP_ID = IBinder::FIRST_CALL_TRANSACTION 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass BpMemoryHeap : public BpInterface<IMemoryHeap> 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BpMemoryHeap(const sp<IBinder>& impl); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual ~BpMemoryHeap(); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual int getHeapID() const; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual void* getBase() const; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual size_t getSize() const; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual uint32_t getFlags() const; 84f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan virtual uint32_t getOffset() const; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project friend class IMemory; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project friend class HeapCache; 89f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for debugging in this module 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) { 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gHeapCache->find_heap(binder); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static inline void free_heap(const sp<IBinder>& binder) { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gHeapCache->free_heap(binder); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return gHeapCache->get_heap(binder); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static inline void dump_heaps() { 101f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan gHeapCache->dump_heaps(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void assertMapped() const; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void assertReallyMapped() const; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable volatile int32_t mHeapId; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable void* mBase; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable size_t mSize; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable uint32_t mFlags; 111f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan mutable uint32_t mOffset; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable bool mRealHeap; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable Mutex mLock; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------------- 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectenum { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass BpMemory : public BpInterface<IMemory> 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BpMemory(const sp<IBinder>& impl); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual ~BpMemory(); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const; 128f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable sp<IMemoryHeap> mHeap; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable ssize_t mOffset; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable size_t mSize; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/******************************************************************************/ 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* const base = realHeap->base(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (base == MAP_FAILED) 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return static_cast<char*>(base) + offset; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* IMemory::pointer() const { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t offset; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> heap = getMemory(&offset); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void* const base = heap!=0 ? heap->base() : MAP_FAILED; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (base == MAP_FAILED) 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return static_cast<char*>(base) + offset; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t IMemory::size() const { 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getMemory(NULL, &size); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return size; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectssize_t IMemory::offset() const { 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t offset; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getMemory(&offset); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return offset; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/******************************************************************************/ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpMemory::BpMemory(const sp<IBinder>& impl) 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : BpInterface<IMemory>(impl), mOffset(0), mSize(0) 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpMemory::~BpMemory() 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeap == 0) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel data, reply; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data.writeInterfaceToken(IMemory::getInterfaceDescriptor()); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> heap = reply.readStrongBinder(); 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t o = reply.readInt32(); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t s = reply.readInt32(); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heap != 0) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeap = interface_cast<IMemoryHeap>(heap); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeap != 0) { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mOffset = o; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = s; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (offset) *offset = mOffset; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (size) *size = mSize; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeap; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectIMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory"); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 205aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias AgopianBnMemory::BnMemory() { 206aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian} 207aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian 208f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu SundararajanBnMemory::~BnMemory() { 209aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian} 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BnMemory::onTransact( 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(code) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case GET_MEMORY: { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CHECK_INTERFACE(IMemory, data, reply); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t offset; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t size; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() ); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply->writeInt32(offset); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply->writeInt32(size); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/******************************************************************************/ 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl) 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : BpInterface<IMemoryHeap>(impl), 234f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mOffset(0), mRealHeap(false) 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectBpMemoryHeap::~BpMemoryHeap() { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeapId != -1) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(mHeapId); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRealHeap) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // by construction we're the last one 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBase != MAP_FAILED) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (VERBOSE) { 247f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d", 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder.get(), this, mSize, mHeapId); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CallStack stack; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stack.update(); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stack.dump("callstack"); 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project munmap(mBase, mSize); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remove from list only if it was mapped before 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_heap(binder); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpMemoryHeap::assertMapped() const 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeapId == -1) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder()); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get())); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heap->assertReallyMapped(); 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (heap->mBase != MAP_FAILED) { 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mLock); 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeapId == -1) { 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBase = heap->mBase; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = heap->mSize; 275f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan mOffset = heap->mOffset; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_write( dup( heap->mHeapId ), &mHeapId ); 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // something went wrong 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_heap(binder); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid BpMemoryHeap::assertReallyMapped() const 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeapId == -1) { 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // remote call without mLock held, worse case scenario, we end up 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // calling transact() from multiple threads, but that's not a problem, 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // only mmap below must be in the critical section. 292f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Parcel data, reply; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor()); 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t err = remote()->transact(HEAP_ID, data, &reply); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int parcel_fd = reply.readFileDescriptor(); 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t size = reply.readInt32(); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t flags = reply.readInt32(); 299f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan uint32_t offset = reply.readInt32(); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 301aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)", 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asBinder().get(), parcel_fd, size, err, strerror(-err)); 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = dup( parcel_fd ); 305aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian LOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)", 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parcel_fd, size, err, strerror(errno)); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int access = PROT_READ; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(flags & READ_ONLY)) { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project access |= PROT_WRITE; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mLock); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHeapId == -1) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRealHeap = true; 316f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan mBase = mmap(0, size, access, MAP_SHARED, fd, offset); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBase == MAP_FAILED) { 318aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)", 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project asBinder().get(), size, fd, strerror(errno)); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(fd); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSize = size; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFlags = flags; 324f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan mOffset = offset; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_write(fd, &mHeapId); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint BpMemoryHeap::getHeapID() const { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertMapped(); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mHeapId; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid* BpMemoryHeap::getBase() const { 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertMapped(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mBase; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t BpMemoryHeap::getSize() const { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertMapped(); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSize; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectuint32_t BpMemoryHeap::getFlags() const { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assertMapped(); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFlags; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 351f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajanuint32_t BpMemoryHeap::getOffset() const { 352f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan assertMapped(); 353f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan return mOffset; 354f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan} 355f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectIMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap"); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 360f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu SundararajanBnMemoryHeap::BnMemoryHeap() { 361aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian} 362aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian 363f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu SundararajanBnMemoryHeap::~BnMemoryHeap() { 364aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian} 365aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t BnMemoryHeap::onTransact( 367aaf834a284a025cedd8ec1cf01d09e1790c1dcf8Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(code) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case HEAP_ID: { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CHECK_INTERFACE(IMemoryHeap, data, reply); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply->writeFileDescriptor(getHeapID()); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply->writeInt32(getSize()); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply->writeInt32(getFlags()); 375f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan reply->writeInt32(getOffset()); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } break; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*****************************************************************************/ 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectHeapCache::HeapCache() 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : DeathRecipient() 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectHeapCache::~HeapCache() 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid HeapCache::binderDied(const wp<IBinder>& binder) 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //LOGD("binderDied binder=%p", binder.unsafe_get()); 397f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan free_heap(binder); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 400f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajansp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heap_info_t& info = mHeapCache.editValueAt(i); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(VERBOSE, 407f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan "found binder=%p, heap=%p, size=%d, fd=%d, count=%d", 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder.get(), info.heap.get(), 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.count); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_inc(&info.count); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return info.heap; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heap_info_t info; 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.heap = interface_cast<IMemoryHeap>(binder); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.count = 1; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //LOGD("adding binder=%p, heap=%p, count=%d", 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // binder.get(), info.heap.get(), info.count); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeapCache.add(binder, info); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return info.heap; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid HeapCache::free_heap(const sp<IBinder>& binder) { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project free_heap( wp<IBinder>(binder) ); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajanvoid HeapCache::free_heap(const wp<IBinder>& binder) 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> rel; 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project heap_info_t& info(mHeapCache.editValueAt(i)); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t c = android_atomic_dec(&info.count); 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == 1) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD_IF(VERBOSE, 440f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d", 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder.unsafe_get(), info.heap.get(), 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.count); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rel = mHeapCache.valueAt(i).heap; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeapCache.removeItemsAt(i); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("free_heap binder=%p not found!!!", binder.unsafe_get()); 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder) 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMemoryHeap> realHeap; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i>=0) realHeap = mHeapCache.valueAt(i).heap; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else realHeap = interface_cast<IMemoryHeap>(binder); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return realHeap; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 464f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajanvoid HeapCache::dump_heaps() 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c = mHeapCache.size(); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0 ; i<c ; i++) { 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const heap_info_t& info = mHeapCache.valueAt(i); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get())); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)", 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHeapCache.keyAt(i).unsafe_get(), 473f24c4cd0f204068a17f61f1c195ccf140c6c1d67Anu Sundararajan info.heap.get(), info.count, 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project h->mHeapId, h->mBase, h->mSize); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 481