1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "IMemory" 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdint.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h> 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <fcntl.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/types.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/mman.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/IMemory.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/KeyedVector.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Atomic.h> 32c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/Parcel.h> 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/CallStack.h> 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define VERBOSE 0 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass HeapCache : public IBinder::DeathRecipient 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HeapCache(); 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~HeapCache(); 455728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual void binderDied(const wp<IBinder>& who); 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 485728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 495728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan void free_heap(const sp<IBinder>& binder); 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> get_heap(const sp<IBinder>& binder); 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void dump_heaps(); 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // For IMemory.cpp 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct heap_info_t { 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> heap; 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t count; 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 605728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan void free_heap(const wp<IBinder>& binder); 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex mHeapCacheLock; 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project KeyedVector< wp<IBinder>, heap_info_t > mHeapCache; 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic sp<HeapCache> gHeapCache = new HeapCache(); 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectenum { 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HEAP_ID = IBinder::FIRST_CALL_TRANSACTION 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass BpMemoryHeap : public BpInterface<IMemoryHeap> 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemoryHeap(const sp<IBinder>& impl); 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~BpMemoryHeap(); 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual int getHeapID() const; 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual void* getBase() const; 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual size_t getSize() const; 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual uint32_t getFlags() const; 845728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan virtual uint32_t getOffset() const; 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project friend class IMemory; 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project friend class HeapCache; 895728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // for debugging in this module 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) { 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return gHeapCache->find_heap(binder); 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline void free_heap(const sp<IBinder>& binder) { 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gHeapCache->free_heap(binder); 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) { 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return gHeapCache->get_heap(binder); 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline void dump_heaps() { 1015728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan gHeapCache->dump_heaps(); 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void assertMapped() const; 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void assertReallyMapped() const; 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable volatile int32_t mHeapId; 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable void* mBase; 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable size_t mSize; 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable uint32_t mFlags; 1115728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mutable uint32_t mOffset; 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable bool mRealHeap; 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable Mutex mLock; 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectenum { 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass BpMemory : public BpInterface<IMemory> 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemory(const sp<IBinder>& impl); 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~BpMemory(); 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const; 1285728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable sp<IMemoryHeap> mHeap; 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable ssize_t mOffset; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable size_t mSize; 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder); 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* const base = realHeap->base(); 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (base == MAP_FAILED) 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return static_cast<char*>(base) + offset; 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* IMemory::pointer() const { 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> heap = getMemory(&offset); 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* const base = heap!=0 ? heap->base() : MAP_FAILED; 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (base == MAP_FAILED) 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return static_cast<char*>(base) + offset; 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t IMemory::size() const { 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t size; 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project getMemory(NULL, &size); 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return size; 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t IMemory::offset() const { 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project getMemory(&offset); 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return offset; 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemory::BpMemory(const sp<IBinder>& impl) 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IMemory>(impl), mOffset(0), mSize(0) 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemory::~BpMemory() 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeap == 0) { 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemory::getInterfaceDescriptor()); 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) { 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> heap = reply.readStrongBinder(); 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t o = reply.readInt32(); 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t s = reply.readInt32(); 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap != 0) { 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeap = interface_cast<IMemoryHeap>(heap); 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeap != 0) { 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mOffset = o; 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = s; 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (offset) *offset = mOffset; 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (size) *size = mSize; 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHeap; 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory"); 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 20583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias AgopianBnMemory::BnMemory() { 20683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 20783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 2085728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemory::~BnMemory() { 20983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemory::onTransact( 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case GET_MEMORY: { 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemory, data, reply); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t size; 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() ); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(offset); 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(size); 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl) 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IMemoryHeap>(impl), 2345728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mOffset(0), mRealHeap(false) 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemoryHeap::~BpMemoryHeap() { 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId != -1) { 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(mHeapId); 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mRealHeap) { 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // by construction we're the last one 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase != MAP_FAILED) { 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (VERBOSE) { 2479d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d", 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), this, mSize, mHeapId); 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CallStack stack; 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project stack.update(); 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project stack.dump("callstack"); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project munmap(mBase, mSize); 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remove from list only if it was mapped before 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertMapped() const 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder()); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get())); 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap->assertReallyMapped(); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap->mBase != MAP_FAILED) { 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBase = heap->mBase; 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = heap->mSize; 2755728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mOffset = heap->mOffset; 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write( dup( heap->mHeapId ), &mHeapId ); 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something went wrong 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertReallyMapped() const 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remote call without mLock held, worse case scenario, we end up 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // calling transact() from multiple threads, but that's not a problem, 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // only mmap below must be in the critical section. 2925728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor()); 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = remote()->transact(HEAP_ID, data, &reply); 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int parcel_fd = reply.readFileDescriptor(); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t size = reply.readInt32(); 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = reply.readInt32(); 2995728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan uint32_t offset = reply.readInt32(); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 301e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)", 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project asBinder().get(), parcel_fd, size, err, strerror(-err)); 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int fd = dup( parcel_fd ); 305e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)", 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel_fd, size, err, strerror(errno)); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int access = PROT_READ; 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!(flags & READ_ONLY)) { 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project access |= PROT_WRITE; 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRealHeap = true; 3165728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mBase = mmap(0, size, access, MAP_SHARED, fd, offset); 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase == MAP_FAILED) { 318e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)", 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project asBinder().get(), size, fd, strerror(errno)); 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(fd); 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = size; 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlags = flags; 3245728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mOffset = offset; 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write(fd, &mHeapId); 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint BpMemoryHeap::getHeapID() const { 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHeapId; 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpMemoryHeap::getBase() const { 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mBase; 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t BpMemoryHeap::getSize() const { 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSize; 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t BpMemoryHeap::getFlags() const { 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlags; 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3515728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanuint32_t BpMemoryHeap::getOffset() const { 3525728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan assertMapped(); 3535728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan return mOffset; 3545728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan} 3555728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap"); 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3605728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemoryHeap::BnMemoryHeap() { 36183c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 36283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 3635728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemoryHeap::~BnMemoryHeap() { 36483c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 36583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemoryHeap::onTransact( 36783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case HEAP_ID: { 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemoryHeap, data, reply); 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeFileDescriptor(getHeapID()); 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getSize()); 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getFlags()); 3755728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan reply->writeInt32(getOffset()); 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*****************************************************************************/ 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::HeapCache() 386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : DeathRecipient() 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::~HeapCache() 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::binderDied(const wp<IBinder>& binder) 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3969d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("binderDied binder=%p", binder.unsafe_get()); 3975728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan free_heap(binder); 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4005728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajansp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info = mHeapCache.editValueAt(i); 4069d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(VERBOSE, 4075728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan "found binder=%p, heap=%p, size=%d, fd=%d, count=%d", 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), info.heap.get(), 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&info.count); 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t info; 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.heap = interface_cast<IMemoryHeap>(binder); 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count = 1; 4189d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("adding binder=%p, heap=%p, count=%d", 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // binder.get(), info.heap.get(), info.count); 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.add(binder, info); 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::free_heap(const sp<IBinder>& binder) { 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap( wp<IBinder>(binder) ); 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4295728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanvoid HeapCache::free_heap(const wp<IBinder>& binder) 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> rel; 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info(mHeapCache.editValueAt(i)); 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t c = android_atomic_dec(&info.count); 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (c == 1) { 4399d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(VERBOSE, 4405728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d", 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.unsafe_get(), info.heap.get(), 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rel = mHeapCache.valueAt(i).heap; 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.removeItemsAt(i); 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 449e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("free_heap binder=%p not found!!!", binder.unsafe_get()); 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder) 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap; 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) realHeap = mHeapCache.valueAt(i).heap; 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else realHeap = interface_cast<IMemoryHeap>(binder); 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return realHeap; 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4645728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanvoid HeapCache::dump_heaps() 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int c = mHeapCache.size(); 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<c ; i++) { 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const heap_info_t& info = mHeapCache.valueAt(i); 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get())); 4719d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)", 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.keyAt(i).unsafe_get(), 4735728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan info.heap.get(), info.count, 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project h->mHeapId, h->mBase, h->mSize); 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 481