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> 2994b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate#include <cutils/log.h> 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/KeyedVector.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/threads.h> 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Atomic.h> 33c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian#include <binder/Parcel.h> 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/CallStack.h> 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define VERBOSE 0 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass HeapCache : public IBinder::DeathRecipient 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project HeapCache(); 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~HeapCache(); 465728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual void binderDied(const wp<IBinder>& who); 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 495728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan sp<IMemoryHeap> find_heap(const sp<IBinder>& binder); 505728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 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 615728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 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; 855728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan virtual uint32_t getOffset() const; 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project friend class IMemory; 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project friend class HeapCache; 905728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // for debugging in this module 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline sp<IMemoryHeap> find_heap(const sp<IBinder>& binder) { 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return gHeapCache->find_heap(binder); 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline void free_heap(const sp<IBinder>& binder) { 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gHeapCache->free_heap(binder); 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline sp<IMemoryHeap> get_heap(const sp<IBinder>& binder) { 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return gHeapCache->get_heap(binder); 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static inline void dump_heaps() { 1025728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan gHeapCache->dump_heaps(); 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void assertMapped() const; 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void assertReallyMapped() const; 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable volatile int32_t mHeapId; 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable void* mBase; 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable size_t mSize; 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable uint32_t mFlags; 1125728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mutable uint32_t mOffset; 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable bool mRealHeap; 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable Mutex mLock; 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------------- 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectenum { 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project GET_MEMORY = IBinder::FIRST_CALL_TRANSACTION 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass BpMemory : public BpInterface<IMemory> 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemory(const sp<IBinder>& impl); 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual ~BpMemory(); 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const; 1295728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectprivate: 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable sp<IMemoryHeap> mHeap; 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable ssize_t mOffset; 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mutable size_t mSize; 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* IMemory::fastPointer(const sp<IBinder>& binder, ssize_t offset) const 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap = BpMemoryHeap::get_heap(binder); 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* const base = realHeap->base(); 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (base == MAP_FAILED) 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return static_cast<char*>(base) + offset; 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* IMemory::pointer() const { 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> heap = getMemory(&offset); 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project void* const base = heap!=0 ? heap->base() : MAP_FAILED; 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (base == MAP_FAILED) 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return 0; 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return static_cast<char*>(base) + offset; 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t IMemory::size() const { 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t size; 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project getMemory(NULL, &size); 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return size; 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectssize_t IMemory::offset() const { 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project getMemory(&offset); 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return offset; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemory::BpMemory(const sp<IBinder>& impl) 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IMemory>(impl), mOffset(0), mSize(0) 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemory::~BpMemory() 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> BpMemory::getMemory(ssize_t* offset, size_t* size) const 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeap == 0) { 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemory::getInterfaceDescriptor()); 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (remote()->transact(GET_MEMORY, data, &reply) == NO_ERROR) { 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> heap = reply.readStrongBinder(); 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t o = reply.readInt32(); 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t s = reply.readInt32(); 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap != 0) { 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeap = interface_cast<IMemoryHeap>(heap); 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeap != 0) { 19194b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate size_t heapSize = mHeap->getSize(); 19294b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate if (s <= heapSize 19394b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate && o >= 0 19494b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate && (static_cast<size_t>(o) <= heapSize - s)) { 19594b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate mOffset = o; 19694b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate mSize = s; 19794b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate } else { 19894b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate // Hm. 19994b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate android_errorWriteWithInfoLog(0x534e4554, 20094b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate "26877992", -1, NULL, 0); 20194b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate mOffset = 0; 20294b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate mSize = 0; 20394b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate } 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (offset) *offset = mOffset; 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (size) *size = mSize; 21094b0d4e3ab023cfa03a7a4e85f3e09d3743da715Christopher Tate return (mSize > 0) ? mHeap : 0; 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(Memory, "android.utils.IMemory"); 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21783c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias AgopianBnMemory::BnMemory() { 21883c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 21983c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 2205728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemory::~BnMemory() { 22183c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemory::onTransact( 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case GET_MEMORY: { 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemory, data, reply); 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t offset; 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project size_t size; 231097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen reply->writeStrongBinder( IInterface::asBinder(getMemory(&offset, &size)) ); 232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(offset); 233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(size); 234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/******************************************************************************/ 243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl) 245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IMemoryHeap>(impl), 2465728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mOffset(0), mRealHeap(false) 247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectBpMemoryHeap::~BpMemoryHeap() { 251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId != -1) { 252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(mHeapId); 253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mRealHeap) { 254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // by construction we're the last one 255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase != MAP_FAILED) { 256097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(this); 257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (VERBOSE) { 2596f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGD("UNMAPPING binder=%p, heap=%p, size=%zu, fd=%d", 260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), this, mSize, mHeapId); 261cab25d680e644d962041d05a319e485b96136a5dMathias Agopian CallStack stack(LOG_TAG); 262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project munmap(mBase, mSize); 265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remove from list only if it was mapped before 268097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder = IInterface::asBinder(this); 269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertMapped() const 275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 277097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen sp<IBinder> binder(IInterface::asBinder(const_cast<BpMemoryHeap*>(this))); 278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get())); 279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap->assertReallyMapped(); 280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (heap->mBase != MAP_FAILED) { 281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mBase = heap->mBase; 284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = heap->mSize; 2855728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mOffset = heap->mOffset; 286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write( dup( heap->mHeapId ), &mHeapId ); 287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // something went wrong 290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap(binder); 291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid BpMemoryHeap::assertReallyMapped() const 296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // remote call without mLock held, worse case scenario, we end up 300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // calling transact() from multiple threads, but that's not a problem, 301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // only mmap below must be in the critical section. 3025728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor()); 305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = remote()->transact(HEAP_ID, data, &reply); 306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int parcel_fd = reply.readFileDescriptor(); 307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t size = reply.readInt32(); 308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t flags = reply.readInt32(); 3095728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan uint32_t offset = reply.readInt32(); 310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3116f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%zd, err=%d (%s)", 312097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen IInterface::asBinder(this).get(), 313097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen parcel_fd, size, err, strerror(-err)); 314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mLock); 316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mHeapId == -1) { 3176b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal int fd = dup( parcel_fd ); 3186b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)", 3196b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal parcel_fd, size, err, strerror(errno)); 3206b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal 3216b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal int access = PROT_READ; 3226b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal if (!(flags & READ_ONLY)) { 3236b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal access |= PROT_WRITE; 3246b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal } 3256b0b06348d4cc8eb0087d95826dbeba9a72565d8John Eckerdal 326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mRealHeap = true; 3275728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mBase = mmap(0, size, access, MAP_SHARED, fd, offset); 328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (mBase == MAP_FAILED) { 3296f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)", 330097ca275f4717a2c47a5d49f302ed2b72c8a1370Marco Nelissen IInterface::asBinder(this).get(), size, fd, strerror(errno)); 331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project close(fd); 332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mSize = size; 334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mFlags = flags; 3355728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan mOffset = offset; 336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_write(fd, &mHeapId); 337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectint BpMemoryHeap::getHeapID() const { 343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mHeapId; 345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid* BpMemoryHeap::getBase() const { 348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mBase; 350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsize_t BpMemoryHeap::getSize() const { 353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mSize; 355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectuint32_t BpMemoryHeap::getFlags() const { 358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project assertMapped(); 359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return mFlags; 360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3625728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanuint32_t BpMemoryHeap::getOffset() const { 3635728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan assertMapped(); 3645728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan return mOffset; 3655728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan} 3665728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan 367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(MemoryHeap, "android.utils.IMemoryHeap"); 370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 3715728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemoryHeap::BnMemoryHeap() { 37283c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 37383c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 3745728a92e29c1c9729017a82c5d0bc18fc1069923Anu SundararajanBnMemoryHeap::~BnMemoryHeap() { 37583c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian} 37683c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian 377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnMemoryHeap::onTransact( 37883c0446f27b9542d6c2e724817b2b2d8d1f55085Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case HEAP_ID: { 382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IMemoryHeap, data, reply); 383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeFileDescriptor(getHeapID()); 384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getSize()); 385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(getFlags()); 3865728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan reply->writeInt32(getOffset()); 387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*****************************************************************************/ 395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::HeapCache() 397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : DeathRecipient() 398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectHeapCache::~HeapCache() 402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::binderDied(const wp<IBinder>& binder) 406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 4079d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("binderDied binder=%p", binder.unsafe_get()); 4085728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan free_heap(binder); 409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4115728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajansp<IMemoryHeap> HeapCache::find_heap(const sp<IBinder>& binder) 412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info = mHeapCache.editValueAt(i); 4179d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(VERBOSE, 4186f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross "found binder=%p, heap=%p, size=%zu, fd=%d, count=%d", 419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.get(), info.heap.get(), 420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project android_atomic_inc(&info.count); 424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t info; 427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.heap = interface_cast<IMemoryHeap>(binder); 428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count = 1; 4299d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block //ALOGD("adding binder=%p, heap=%p, count=%d", 430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // binder.get(), info.heap.get(), info.count); 431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.add(binder, info); 432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return info.heap; 433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid HeapCache::free_heap(const sp<IBinder>& binder) { 437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project free_heap( wp<IBinder>(binder) ); 438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4405728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanvoid HeapCache::free_heap(const wp<IBinder>& binder) 441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> rel; 443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) { 447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project heap_info_t& info(mHeapCache.editValueAt(i)); 448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t c = android_atomic_dec(&info.count); 449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (c == 1) { 4509d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD_IF(VERBOSE, 4516f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross "removing binder=%p, heap=%p, size=%zu, fd=%d, count=%d", 452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project binder.unsafe_get(), info.heap.get(), 453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mSize, 454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId, 455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project info.count); 456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project rel = mHeapCache.valueAt(i).heap; 457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.removeItemsAt(i); 458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 460e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("free_heap binder=%p not found!!!", binder.unsafe_get()); 461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IMemoryHeap> HeapCache::get_heap(const sp<IBinder>& binder) 466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IMemoryHeap> realHeap; 468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ssize_t i = mHeapCache.indexOfKey(binder); 470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (i>=0) realHeap = mHeapCache.valueAt(i).heap; 471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project else realHeap = interface_cast<IMemoryHeap>(binder); 472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return realHeap; 473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 4755728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajanvoid HeapCache::dump_heaps() 476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Mutex::Autolock _l(mHeapCacheLock); 478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int c = mHeapCache.size(); 479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (int i=0 ; i<c ; i++) { 480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const heap_info_t& info = mHeapCache.valueAt(i); 481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get())); 4826f4f3ab36c5ed1df84eb3a9f7475f0ac42952f58Colin Cross ALOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%zu)", 483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project mHeapCache.keyAt(i).unsafe_get(), 4845728a92e29c1c9729017a82c5d0bc18fc1069923Anu Sundararajan info.heap.get(), info.count, 485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project h->mHeapId, h->mBase, h->mSize); 486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// --------------------------------------------------------------------------- 491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 492