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++调用接口分析,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。