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.cpp

class 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 = (int32_t*)mMemory->pointer();
			if(data != NULL)
			{
				*data = 0;
			}
		}
	}

	virtual ~SharedBufferService()
	{
		mMemory = NULL;
	}

public:
	static void instantiate()
	{
		defaultServiceManager()->addService(String16(SHARED_BUFFER_SERVICE), new SharedBufferService());
	}

	virtual sp<IMemory> getBuffer()
	{
		return mMemory;
	}

private:
	sp<MemoryBase> mMemory;
};

int main(int argc, char** argv)
{
	SharedBufferService::instantiate();

	ProcessState::self()->startThreadPool();
	IPCThreadState::self()->joinThreadPool();  

	return 0;
}

未完。

Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析,布布扣,bubuko.com

时间: 06-15