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) { 2476f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGD("UNMAPPING binder=%p, heap=%p, size=%zu, fd=%d", 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), this, mSize, mHeapId); 249cab25d680e644d962041d05a319e485b96136a5dMathias Agopian CallStack stack(LOG_TAG); 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project munmap(mBase, mSize); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remove from list only if it was mapped before 256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder(); 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertMapped() const 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder()); 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get())); 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap->assertReallyMapped(); 268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap->mBase != MAP_FAILED) { 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBase = heap->mBase; 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = heap->mSize; 2735728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mOffset = heap->mOffset; 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write( dup( heap->mHeapId ), &mHeapId ); 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something went wrong 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertReallyMapped() const 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remote call without mLock held, worse case scenario, we end up 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // calling transact() from multiple threads, but that's not a problem, 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // only mmap below must be in the critical section. 2905728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor()); 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = remote()->transact(HEAP_ID, data, &reply); 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int parcel_fd = reply.readFileDescriptor(); 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t size = reply.readInt32(); 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = reply.readInt32(); 2975728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan uint32_t offset = reply.readInt32(); 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 2996f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%zd, err=%d (%s)", 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project asBinder().get(), parcel_fd, size, err, strerror(-err)); 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int fd = dup( parcel_fd ); 3036f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)", 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project parcel_fd, size, err, strerror(errno)); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int access = PROT_READ; 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (!(flags & READ_ONLY)) { 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project access |= PROT_WRITE; 309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRealHeap = true; 3145728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mBase = mmap(0, size, access, MAP_SHARED, fd, offset); 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase == MAP_FAILED) { 3166f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)", 317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project asBinder().get(), size, fd, strerror(errno)); 318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(fd); 319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = size; 321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlags = flags; 3225728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mOffset = offset; 323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write(fd, &mHeapId); 324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint BpMemoryHeap::getHeapID() const { 330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHeapId; 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpMemoryHeap::getBase() const { 335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mBase; 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t BpMemoryHeap::getSize() const { 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSize; 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t BpMemoryHeap::getFlags() const { 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlags; 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3495728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanuint32_t BpMemoryHeap::getOffset() const { 3505728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan assertMapped(); 3515728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan return mOffset; 3525728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan} 3535728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap"); 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3585728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemoryHeap::BnMemoryHeap() { 35983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 36083c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 3615728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemoryHeap::~BnMemoryHeap() { 36283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 36383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemoryHeap::onTransact( 36583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case HEAP_ID: { 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemoryHeap, data, reply); 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeFileDescriptor(getHeapID()); 371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getSize()); 372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getFlags()); 3735728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan reply->writeInt32(getOffset()); 374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 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 : DeathRecipient() 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::~HeapCache() 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::binderDied(const wp<IBinder>& binder) 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 3949d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("binderDied binder=%p", binder.unsafe_get()); 3955728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan free_heap(binder); 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3985728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajansp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info = mHeapCache.editValueAt(i); 4049d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(VERBOSE, 4056f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross "found binder=%p, heap=%p, size=%zu, fd=%d, count=%d", 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), info.heap.get(), 407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&info.count); 411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t info; 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.heap = interface_cast<IMemoryHeap>(binder); 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count = 1; 4169d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("adding binder=%p, heap=%p, count=%d", 417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // binder.get(), info.heap.get(), info.count); 418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.add(binder, info); 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::free_heap(const sp<IBinder>& binder) { 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap( wp<IBinder>(binder) ); 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4275728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanvoid HeapCache::free_heap(const wp<IBinder>& binder) 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> rel; 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info(mHeapCache.editValueAt(i)); 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t c = android_atomic_dec(&info.count); 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (c == 1) { 4379d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(VERBOSE, 4386f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross "removing binder=%p, heap=%p, size=%zu, fd=%d, count=%d", 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.unsafe_get(), info.heap.get(), 440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rel = mHeapCache.valueAt(i).heap; 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.removeItemsAt(i); 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 447e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("free_heap binder=%p not found!!!", binder.unsafe_get()); 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder) 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap; 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) realHeap = mHeapCache.valueAt(i).heap; 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else realHeap = interface_cast<IMemoryHeap>(binder); 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return realHeap; 460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4625728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanvoid HeapCache::dump_heaps() 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int c = mHeapCache.size(); 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<c ; i++) { 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const heap_info_t& info = mHeapCache.valueAt(i); 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get())); 4696f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%zu)", 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.keyAt(i).unsafe_get(), 4715728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan info.heap.get(), info.count, 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project h->mHeapId, h->mBase, h->mSize); 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 479