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

时间: 2024-12-22 11:44:50

Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析的相关文章

Android系统匿名共享内存(Anonymous Shared Memory)Java调用接口分析

一.Ashmem驱动程序 ~/Android/kernel/goldfish ----include ----linux ----ashmem.h ----mm ----ashmem.c 驱动程序具体解释请看<Android系统源码情景分析>.作者罗升阳. 二.执行时库cutils的匿名共享内存訪问接口 ~/Android/system/core ----libcutils ----ashmem-dev.c 具体解释请看<Android系统源码情景分析>,作者罗升阳. 三.Memo

Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6664554 在上一文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划中, 我们简要介绍了Android系统的匿名共享内存机制,其中,简要提到了它具有辅助内存管理系统来有效地管理内存的特点,但是没有进一步去了解它是如何实 现的.在本文中,我们将通过分析Android系统的匿名共享内存

Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析

文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6666491 在前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析中,我们系统地介绍了Android系统匿名共享内存的实现原理,其中着重介绍了它是如何辅助内存管理系统来有效地管理内存的,在再前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Share

cuda编程:关于共享内存(shared memory)和存储体(bank)的事实和疑惑

关于共享内存(shared memory)和存储体(bank)的事实和疑惑 主要是在研究访问共享内存会产生bank conflict时,自己产生的疑惑.对于这点疑惑,网上都没有相关描述, 不管是国内还是国外的网上资料.貌似大家都是当作一个事实,一个公理,而没有对其仔细研究.还是我自己才学疏浅,不知道某些知识. 比如下面这篇讲解bank conflict的文章. http://cuda-programming.blogspot.com/2013/02/bank-conflicts-in-share

CUDA学习(五)之使用共享内存(shared memory)进行归约求和

共享内存(shared memory)是位于SM上的on-chip(片上)一块内存,每个SM都有,就是内存比较小,早期的GPU只有16K(16384),现在生产的GPU一般都是48K(49152). 共享内存由于是片上内存,因而带宽高,延迟小(较全局内存而言),合理使用共享内存对程序效率具有很大提升. 下面是使用共享内存对一个数组进行求和,使用全局内存进行归约求和可以浏览https://www.cnblogs.com/xiaoxiaoyibu/p/11397205.html #pragma on

CUDA学习(六)之使用共享内存(shared memory)进行归约求和(M个包含N个线程的线程块)

在https://www.cnblogs.com/xiaoxiaoyibu/p/11402607.html中介绍了使用一个包含N个线程的线程块和共享内存进行数组归约求和, 基本思路: 定义M个包含N个线程的线程块时(NThreadX = ((NX + ThreadX - 1) / ThreadX)),全局线程索引需使用tid = blockIdx.x * blockDim.x + threadIdx.x,而在每个线程块中局部线程索引是i = threadIdx.x, 每个线程块只计算一部分求和,

Fresco内存机制(Ashmem匿名共享内存)

Fresco的内存机制 Fresco是Facebook出品的高性能图片加载库,采用了Ashmem匿名共享内存机制, 来解决图片加载中的OOM问题.这里不对Fresco做深入分析,只关注Fresco在Android Bitmap的管理上采用了哪些黑科技. Android的内存区域 Java Heap(Dalvik Heap),这部分的内存区域是由Dalvik虚拟机管理,通过Java中 new 关键字来申请一块新内存.这块区域的内存是由GC直接管理,能够自动回收内存.这块内存的大小会受到系统限制,当

Android漫游记(1)---内存映射镜像(memory maps)

Android系统内核基于Linux2.6+内核,因此,其在进程内存管理方面的很多机制和Linux是很相像的.首先,让我们来看一个典型的Android进程的内存镜像(App进程和Native本地进程略有差别,但原理是一样的): 和Linux一样,Android提供了基于/proc的"伪文件"系统来作为查看用户进程内存映像的接口(cat /proc/pid/maps).可以说,这是Android系统内核层开放给用户层关于进程内存信息的一扇窗户.通过它,我们可以查看到当前进程空间的内存映射

查看Android 系统单个进程内存、CPU使用情况的几种方法

一.利用Android API函数查看 1.1 ActivityManager查看可用内存. ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo(); am.getMemoryInfo(outInfo); outInfo.availMem即为可用空闲内存. 1.2.Android.os.Debug查询PSS,VSS,USS等单个进程使用内存信息 MemoryInfo[] memoryInfoArray = am.