IMemory.cpp revision edbf3b6af777b721cd2a1ef461947e51e88241e1
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 28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/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> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/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(); 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual void binderDied(const wp<IBinder>& who); 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void pin_heap(const sp<IBinder>& binder); 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void free_heap(const sp<IBinder>& binder); 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> get_heap(const sp<IBinder>& binder); 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void dump_heaps(); 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // For IMemory.cpp 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project struct heap_info_t { 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> heap; 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t count; 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project }; 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void free_heap(const wp<IBinder>& binder); 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex mHeapCacheLock; 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project KeyedVector< wp<IBinder>, heap_info_t > mHeapCache; 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic sp<HeapCache> gHeapCache = new HeapCache(); 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectenum { 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HEAP_ID = IBinder::FIRST_CALL_TRANSACTION 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass BpMemoryHeap : public BpInterface<IMemoryHeap> 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemoryHeap(const sp<IBinder>& impl); 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~BpMemoryHeap(); 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual int getHeapID() const; 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual void* getBase() const; 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual size_t getSize() const; 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual uint32_t getFlags() 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; 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 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() { 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gHeapCache->dump_heaps(); 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void inline pin_heap() const { 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gHeapCache->pin_heap(const_cast<BpMemoryHeap*>(this)->asBinder()); 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void assertMapped() const; 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void assertReallyMapped() const; 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void pinHeap() const; 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable volatile int32_t mHeapId; 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable void* mBase; 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable size_t mSize; 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable uint32_t mFlags; 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable bool mRealHeap; 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable Mutex mLock; 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectenum { 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass BpMemory : public BpInterface<IMemory> 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemory(const sp<IBinder>& impl); 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~BpMemory(); 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const; 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable sp<IMemoryHeap> mHeap; 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable ssize_t mOffset; 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable size_t mSize; 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder); 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* const base = realHeap->base(); 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (base == MAP_FAILED) 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return static_cast<char*>(base) + offset; 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* IMemory::pointer() const { 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> heap = getMemory(&offset); 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* const base = heap!=0 ? heap->base() : MAP_FAILED; 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (base == MAP_FAILED) 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return static_cast<char*>(base) + offset; 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t IMemory::size() const { 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t size; 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project getMemory(NULL, &size); 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return size; 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t IMemory::offset() const { 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project getMemory(&offset); 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return offset; 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemory::BpMemory(const sp<IBinder>& impl) 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IMemory>(impl), mOffset(0), mSize(0) 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemory::~BpMemory() 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeap == 0) { 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemory::getInterfaceDescriptor()); 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) { 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> heap = reply.readStrongBinder(); 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t o = reply.readInt32(); 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t s = reply.readInt32(); 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap != 0) { 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeap = interface_cast<IMemoryHeap>(heap); 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeap != 0) { 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mOffset = o; 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = s; 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (offset) *offset = mOffset; 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (size) *size = mSize; 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHeap; 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory"); 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define CHECK_INTERFACE(interface, data, reply) \ 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("Call incorrectly routed to " #interface); \ 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; \ 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } } while (0) 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemory::onTransact( 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case GET_MEMORY: { 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemory, data, reply); 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t size; 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() ); 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(offset); 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(size); 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl) 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IMemoryHeap>(impl), 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false) 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemoryHeap::~BpMemoryHeap() { 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId != -1) { 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(mHeapId); 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mRealHeap) { 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // by construction we're the last one 246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase != MAP_FAILED) { 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (VERBOSE) { 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d", 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), this, mSize, mHeapId); 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CallStack stack; 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project stack.update(); 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project stack.dump("callstack"); 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project munmap(mBase, mSize); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remove from list only if it was mapped before 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertMapped() const 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder()); 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get())); 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap->assertReallyMapped(); 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap->mBase != MAP_FAILED) { 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBase = heap->mBase; 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = heap->mSize; 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write( dup( heap->mHeapId ), &mHeapId ); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something went wrong 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertReallyMapped() const 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remote call without mLock held, worse case scenario, we end up 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // calling transact() from multiple threads, but that's not a problem, 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // only mmap below must be in the critical section. 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor()); 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = remote()->transact(HEAP_ID, data, &reply); 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int parcel_fd = reply.readFileDescriptor(); 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t size = reply.readInt32(); 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = reply.readInt32(); 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%d, err=%d (%s)", 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project asBinder().get(), parcel_fd, size, err, strerror(-err)); 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int fd = dup( parcel_fd ); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE_IF(fd==-1, "cannot dup fd=%d, size=%d, err=%d (%s)", 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel_fd, size, err, strerror(errno)); 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int access = PROT_READ; 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!(flags & READ_ONLY)) { 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project access |= PROT_WRITE; 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRealHeap = true; 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBase = mmap(0, size, access, MAP_SHARED, fd, 0); 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase == MAP_FAILED) { 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("cannot map BpMemoryHeap (binder=%p), size=%d, fd=%d (%s)", 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project asBinder().get(), size, fd, strerror(errno)); 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(fd); 322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (flags & MAP_ONCE) { 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("pinning heap (binder=%p, size=%d, fd=%d", 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // asBinder().get(), size, fd); 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project pin_heap(); 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = size; 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlags = flags; 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write(fd, &mHeapId); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint BpMemoryHeap::getHeapID() const { 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHeapId; 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpMemoryHeap::getBase() const { 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mBase; 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t BpMemoryHeap::getSize() const { 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSize; 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t BpMemoryHeap::getFlags() const { 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlags; 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 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 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemoryHeap::onTransact( 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case HEAP_ID: { 365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemoryHeap, data, reply); 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeFileDescriptor(getHeapID()); 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getSize()); 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getFlags()); 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*****************************************************************************/ 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::HeapCache() 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : DeathRecipient() 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::~HeapCache() 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::binderDied(const wp<IBinder>& binder) 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("binderDied binder=%p", binder.unsafe_get()); 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info = mHeapCache.editValueAt(i); 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(VERBOSE, 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "found binder=%p, heap=%p, size=%d, fd=%d, count=%d", 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), info.heap.get(), 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&info.count); 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t info; 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.heap = interface_cast<IMemoryHeap>(binder); 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count = 1; 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //LOGD("adding binder=%p, heap=%p, count=%d", 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // binder.get(), info.heap.get(), info.count); 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.add(binder, info); 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::pin_heap(const sp<IBinder>& binder) 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info(mHeapCache.editValueAt(i)); 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&info.count); 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder->linkToDeath(this); 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("pin_heap binder=%p not found!!!", binder.get()); 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::free_heap(const sp<IBinder>& binder) { 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap( wp<IBinder>(binder) ); 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::free_heap(const wp<IBinder>& binder) 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> rel; 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info(mHeapCache.editValueAt(i)); 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t c = android_atomic_dec(&info.count); 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (c == 1) { 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD_IF(VERBOSE, 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d", 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.unsafe_get(), info.heap.get(), 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rel = mHeapCache.valueAt(i).heap; 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.removeItemsAt(i); 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGE("free_heap binder=%p not found!!!", binder.unsafe_get()); 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder) 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap; 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) realHeap = mHeapCache.valueAt(i).heap; 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else realHeap = interface_cast<IMemoryHeap>(binder); 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return realHeap; 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::dump_heaps() 471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int c = mHeapCache.size(); 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<c ; i++) { 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const heap_info_t& info = mHeapCache.valueAt(i); 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get())); 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)", 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.keyAt(i).unsafe_get(), 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.heap.get(), info.count, 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project h->mHeapId, h->mBase, h->mSize); 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 487