首页 > 代码库 > Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
一、Ashmem驱动程序
~/Android/kernel/goldfish
----include
----linux
----ashmem.h
----mm
----ashmem.c
驱动程序详解请看《Android系统源代码情景分析》,作者罗升阳。
二、运行时库cutils的匿名共享内存访问接口
~/Android/system/core
----libcutils
----ashmem-dev.c
详解请看《Android系统源代码情景分析》,作者罗升阳。
三、MemoryHeapBase
1、Server端实现
我们只分析下面3个类
IMemoryHeap--->IMemory.h,IMemory.cpp
BnMemoryHeap--->IMemory.h,IMemory.cpp
MemoryHeapBase--->MemoryHeapBase.h,MemoryHeapBase.cpp
详解请看《Android系统源代码情景分析》,作者罗升阳,这里只列出代码。
IMemoryHeap(IMemory.h)
class IMemoryHeap : public IInterface { public: DECLARE_META_INTERFACE(MemoryHeap); // flags returned by getFlags() enum { READ_ONLY = 0x00000001 }; virtual int getHeapID() const = 0; virtual void* getBase() const = 0; virtual size_t getSize() const = 0; virtual uint32_t getFlags() const = 0; // these are there just for backward source compatibility int32_t heapID() const { return getHeapID(); } void* base() const { return getBase(); } size_t virtualSize() const { return getSize(); } };
BnMemoryHeap(IMemory.cpp)
status_t BnMemoryHeap::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch(code) { case HEAP_ID: { CHECK_INTERFACE(IMemoryHeap, data, reply); reply->writeFileDescriptor(getHeapID()); reply->writeInt32(getSize()); reply->writeInt32(getFlags()); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); } }
MemoryHeapBase(MemoryHeapBase.cpp)
MemoryHeapBase::MemoryHeapBase(size_t size, uint32_t flags, char const * name) : mFD(-1), mSize(0), mBase(MAP_FAILED), mFlags(flags), mDevice(0), mNeedUnmap(false) { const size_t pagesize = getpagesize(); size = ((size + pagesize-1) & ~(pagesize-1)); int fd = ashmem_create_region(name == NULL ? "MemoryHeapBase" : name, size); LOGE_IF(fd<0, "error creating ashmem region: %s", strerror(errno)); if (fd >= 0) { if (mapfd(fd, size) == NO_ERROR) { if (flags & READ_ONLY) { ashmem_set_prot_region(fd, PROT_READ); } } } } ...... status_t MemoryHeapBase::mapfd(int fd, size_t size, uint32_t offset) { ..... if ((mFlags & DONT_MAP_LOCALLY) == 0) { void* base = (uint8_t*)mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, offset); ...... mBase = base; mNeedUnmap = true; } else { ..... } mFD = fd; mSize = size; return NO_ERROR; } ......... int MemoryHeapBase::getHeapID() const { return mFD; } void* MemoryHeapBase::getBase() const { return mBase; } size_t MemoryHeapBase::getSize() const { return mSize; } uint32_t MemoryHeapBase::getFlags() const { return mFlags; }
2、Client端实现
我们只分析下面2个类
IMemoryHeap--->IMemory.h,IMemory.cpp
BpMemoryHeap--->IMemory.cpp
详解请看《Android系统源代码情景分析》,作者罗升阳。
BpMemoryHeap(IMemory.cpp)
BpMemoryHeap::BpMemoryHeap(const sp<IBinder>& impl) : BpInterface<IMemoryHeap>(impl), mHeapId(-1), mBase(MAP_FAILED), mSize(0), mFlags(0), mRealHeap(false) { } ....... void BpMemoryHeap::assertMapped() const { if (mHeapId == -1) { sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder()); sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get())); heap->assertReallyMapped(); if (heap->mBase != MAP_FAILED) { Mutex::Autolock _l(mLock); if (mHeapId == -1) { mBase = heap->mBase; mSize = heap->mSize; android_atomic_write( dup( heap->mHeapId ), &mHeapId ); } } else { // something went wrong free_heap(binder); } } } void BpMemoryHeap::assertReallyMapped() const { if (mHeapId == -1) { // remote call without mLock held, worse case scenario, we end up // calling transact() from multiple threads, but that's not a problem, // only mmap below must be in the critical section. Parcel data, reply; data.writeInterfaceToken(IMemoryHeap::getInterfaceDescriptor()); status_t err = remote()->transact(HEAP_ID, data, &reply); int parcel_fd = reply.readFileDescriptor(); ssize_t size = reply.readInt32(); uint32_t flags = reply.readInt32(); ......... int fd = dup( parcel_fd ); ........ int access = PROT_READ; if (!(flags & READ_ONLY)) { access |= PROT_WRITE; } Mutex::Autolock _l(mLock); if (mHeapId == -1) { mRealHeap = true; mBase = mmap(0, size, access, MAP_SHARED, fd, 0); if (mBase == MAP_FAILED) { LOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)", asBinder().get(), size, fd, strerror(errno)); close(fd); } else { mSize = size; mFlags = flags; android_atomic_write(fd, &mHeapId); } } } } int BpMemoryHeap::getHeapID() const { assertMapped(); return mHeapId; } void* BpMemoryHeap::getBase() const { assertMapped(); return mBase; } size_t BpMemoryHeap::getSize() const { assertMapped(); return mSize; } uint32_t BpMemoryHeap::getFlags() const { assertMapped(); return mFlags; }
四、MemoryBase
1、Server端实现
我们只分析下面3个类
IMemory--->IMemory.h,IMemory.cpp
BnMemory--->IMemory.h,IMemory.cpp
MemoryBase--->MemoryBase.h,MemoryBase.cpp
详解请看《Android系统源代码情景分析》,作者罗升阳。
2、Client端实现
我们只分析下面2个类
IMemory--->IMemory.h,IMemory.cpp
BpMemory--->IMemory.cpp
详解请看《Android系统源代码情景分析》,作者罗升阳。
五、应用实例
~/Android/external/ashmem
----common
----ISharedBuffer.h
----ISharedBuffer.cpp
----server
----SharedBufferServer.cpp
----Android.mk
----client
----SharedBufferClient.cpp
----Android.mk
1、Server端实现
想象上面的图。
我们只分析下面3个类
ISharedBuffer--->ISharedBuffer.h,ISharedBuffer.cpp
BnSharedBuffer--->ISharedBuffer.h,ISharedBuffer.cpp
SharedBufferService--->SharedBufferServer.cpp
详解请看《Android系统源代码情景分析》,作者罗升阳。
2、Client端实现
想象上面的图。我们只分析下面2个类
ISharedBuffer--->ISharedBuffer.h,ISharedBuffer.cpp
BpSharedBuffer--->ISharedBuffer.cpp
详解请看《Android系统源代码情景分析》,作者罗升阳。
3、实现代码
SharedBufferServer.cppclass SharedBufferService : public BnSharedBuffer { public: SharedBufferService() { sp<MemoryHeapBase> heap = new MemoryHeapBase(SHARED_BUFFER_SIZE, 0, "SharedBuffer"); if(heap != NULL) { mMemory = new MemoryBase(heap, 0, SHARED_BUFFER_SIZE); int32_t* data = http://www.mamicode.com/(int32_t*)mMemory->pointer();>
未完。