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