文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>android的ashmem和pmem确实通过BpMemoryHeap和mm..

android的ashmem和pmem确实通过BpMemoryHeap和mm..

时间:2010-11-05  来源:gliethttp

《关于AudioFlinger中ashmem匿名共享内存的理解》 binder驱动binder_transaction         case BINDER_TYPE_FD: {             int target_fd;             struct file *file;
            if (reply) {                 if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {                     binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",                         proc->pid, thread->pid, fp->handle);                     return_error = BR_FAILED_REPLY;                     goto err_fd_not_allowed;                 }             } else if (!target_node->accept_fds) {                 binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",                     proc->pid, thread->pid, fp->handle);                 return_error = BR_FAILED_REPLY;                 goto err_fd_not_allowed;             }
            file = fget(fp->handle);             if (file == NULL) {                 binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",                     proc->pid, thread->pid, fp->handle);                 return_error = BR_FAILED_REPLY;                 goto err_fget_failed;             }             target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);             if (target_fd < 0) {                 fput(file);                 return_error = BR_FAILED_REPLY;                 goto err_get_unused_fd_failed;             }             task_fd_install(target_proc, target_fd, file);             binder_debug(BINDER_DEBUG_TRANSACTION,                      "        fd %ld -> %d\n", fp->handle, target_fd);             /* TODO: fput? */             fp->handle = target_fd;         } break;
以上的file = fget(fp->handle)和task_get_unused_fd_flags共同完成dup包含操作集fops的file,然后assertReallyMapped将再次执行mmap,映射ashmem或pmem申请到的同一块物理内存. BpMemoryHeap::assertReallyMapped remote()->transact(HEAP_ID, data, &reply); 会被binder另一端的onTransact函数接收并处理 BnMemoryHeap::onTransact 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);     } }
status_t Parcel::writeFileDescriptor(int fd) {     flat_binder_object obj;     obj.type = BINDER_TYPE_FD;     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;     obj.handle = fd;     obj.cookie = (void*)0;     return writeObject(obj, true); }

void* BpMemoryHeap::getBase() const {     assertMapped();     return mBase; }
BpMemoryHeap::assertMapped 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(); // 这会做实际的map工作         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(); // 在驱动binder_transaction中BINDER_TYPE_FD // 然后remote的file结构体,在kernel中被执行file = fget(fp->handle);获取设备描述符号         ssize_t size = reply.readInt32();         uint32_t flags = reply.readInt32();
        LOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",                 asBinder().get(), parcel_fd, size, err, strerror(-err));
        int fd = dup( parcel_fd );         LOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",                 parcel_fd, size, err, strerror(errno));
        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);             }         }     } }

BootAnimation::BootAnimation() : Thread(false) {     mSession = new SurfaceComposerClient(); // 与SurfaceFlinger创建一个Connection,也叫session }

SurfaceComposerClient::SurfaceComposerClient() sp<ISurfaceComposer> sm(getComposerService()); // 就是binder获取"SurfaceFlinger"系统服务,即SurfaceFlinger::instantiate()添加的service _init(sm, sm->createConnection());
SurfaceFlinger::createConnection() ==> sp<Client> client = new Client(token, this); ==> sp<BClient> bclient =         new BClient(this, token, client->getControlBlockMemory());
frameworks/base/libs/surfaceflinger/SurfaceFlinger.cpp Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)     : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger) {     const int pgsize = getpagesize();     const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
    mCblkHeap = new MemoryHeapBase(cblksize, 0,             "SurfaceFlinger Client control-block");
    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());     if (ctrlblk) { // construct the shared structure in-place.         new(ctrlblk) SharedClient;     } }

首先在上面通过createConnection()创建一个client,然后才能创建SurfaceFlinger::createSurface
SurfaceComposerClient::createSurface
相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载