📄 pool.c
字号:
fusion_shm_pool_deallocate( FusionSHMPoolShared *pool, void *data, bool lock ){ DirectResult ret; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p )\n", __FUNCTION__, pool, data ); D_MAGIC_ASSERT( pool, FusionSHMPoolShared ); D_ASSERT( data != NULL ); D_ASSERT( data >= pool->addr_base ); D_ASSERT( data < pool->addr_base + pool->max_size ); if (lock) { ret = fusion_skirmish_prevail( &pool->lock ); if (ret) return ret; } __shmalloc_brk( pool->heap, 0 ); _fusion_shfree( pool->heap, data ); if (lock) fusion_skirmish_dismiss( &pool->lock ); return DFB_OK;}/**********************************************************************************************************************/static DirectResultinit_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared, const char *name, unsigned int max_size, bool debug ){ DirectResult ret; int fd; int size; FusionWorld *world; FusionSHMPoolNew pool_new = {0}; FusionSHMPoolAttach pool_attach = {0}; FusionEntryInfo info; char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32]; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p, '%s', %d, %sdebug )\n", __FUNCTION__, shm, pool, shared, name, max_size, debug ? "" : "non-" ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( shm->shared, FusionSHMShared ); D_ASSERT( name != NULL ); D_ASSERT( max_size > sizeof(shmalloc_heap) ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); /* Fill out information for new pool. */ pool_new.max_size = max_size; pool_new.max_size += BLOCKALIGN(sizeof(shmalloc_heap)) + BLOCKALIGN( (max_size + BLOCKSIZE-1) / BLOCKSIZE * sizeof(shmalloc_info) ); /* Create the new pool. */ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_NEW, &pool_new )) { if (errno == EINTR) continue; D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_NEW failed!\n" ); return DFB_FUSION; } /* Set the pool info. */ info.type = FT_SHMPOOL; info.id = pool_new.pool_id; snprintf( info.name, sizeof(info.name), "%s", name ); ioctl( world->fusion_fd, FUSION_ENTRY_SET_INFO, &info ); /* Set pool to attach to. */ pool_attach.pool_id = pool_new.pool_id; /* Attach to the pool. */ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) { if (errno == EINTR) continue; D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" ); while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" ); break; } } return DFB_FUSION; } /* Generate filename. */ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs, fusion_world_index( shm->world ), pool_new.pool_id ); /* Initialize the heap. */ ret = __shmalloc_init_heap( shm, buf, pool_new.addr_base, max_size, &fd, &size ); if (ret) { while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" ); break; } } return ret; } /* Initialize local data. */ pool->attached = true; pool->shm = shm; pool->shared = shared; pool->pool_id = pool_new.pool_id; pool->fd = fd; pool->filename = D_STRDUP( buf ); /* Initialize shared data. */ shared->active = true; shared->debug = debug; shared->shm = shm->shared; shared->max_size = pool_new.max_size; shared->pool_id = pool_new.pool_id; shared->addr_base = pool_new.addr_base; shared->heap = pool_new.addr_base; shared->heap->pool = shared; fusion_skirmish_init( &shared->lock, name, world ); D_MAGIC_SET( pool, FusionSHMPool ); D_MAGIC_SET( shared, FusionSHMPoolShared ); shared->name = SHSTRDUP( shared, name ); return DFB_OK;}static DirectResultjoin_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ){ DirectResult ret; int fd; FusionWorld *world; FusionSHMPoolAttach pool_attach = {0}; char buf[FUSION_SHM_TMPFS_PATH_NAME_LEN + 32]; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( shm->shared, FusionSHMShared ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared );#if !DIRECT_BUILD_DEBUGS if (shared->debug) { D_ERROR( "Fusion/SHM: Can't join debug enabled pool with pure-release library!\n" ); return DFB_UNSUPPORTED; }#endif world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); /* Set pool to attach to. */ pool_attach.pool_id = shared->pool_id; /* Attach to the pool. */ while (ioctl( world->fusion_fd, FUSION_SHMPOOL_ATTACH, &pool_attach )) { if (errno == EINTR) continue; D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_ATTACH failed!\n" ); return DFB_FUSION; } /* Generate filename. */ snprintf( buf, sizeof(buf), "%s/fusion.%d.%d", shm->shared->tmpfs, fusion_world_index( shm->world ), shared->pool_id ); /* Join the heap. */ ret = __shmalloc_join_heap( shm, buf, pool_attach.addr_base, shared->max_size, &fd ); if (ret) { while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" ); break; } } return ret; } /* Initialize local data. */ pool->attached = true; pool->shm = shm; pool->shared = shared; pool->pool_id = shared->pool_id; pool->fd = fd; pool->filename = D_STRDUP( buf ); D_MAGIC_SET( pool, FusionSHMPool ); return DFB_OK;}static voidleave_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ){ FusionWorld *world; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPool ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DETACH, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DETACH failed!\n" ); break; } } if (munmap( shared->addr_base, shared->max_size )) D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename ); if (close( pool->fd )) D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename ); pool->attached = false; D_FREE( pool->filename ); D_MAGIC_CLEAR( pool );}static voidshutdown_pool( FusionSHM *shm, FusionSHMPool *pool, FusionSHMPoolShared *shared ){ FusionWorld *world; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %p, %p )\n", __FUNCTION__, shm, pool, shared ); D_MAGIC_ASSERT( shm, FusionSHM ); D_MAGIC_ASSERT( pool, FusionSHMPool ); D_MAGIC_ASSERT( shared, FusionSHMPoolShared ); world = shm->world; D_MAGIC_ASSERT( world, FusionWorld ); SHFREE( shared, shared->name ); fusion_dbg_print_memleaks( shared ); while (ioctl( world->fusion_fd, FUSION_SHMPOOL_DESTROY, &shared->pool_id )) { if (errno != EINTR) { D_PERROR( "Fusion/SHM: FUSION_SHMPOOL_DESTROY failed!\n" ); break; } } if (munmap( shared->addr_base, shared->max_size )) D_PERROR( "Fusion/SHM: Could not munmap shared memory file '%s'!\n", pool->filename ); if (close( pool->fd )) D_PERROR( "Fusion/SHM: Could not close shared memory file '%s'!\n", pool->filename ); if (unlink( pool->filename )) D_PERROR( "Fusion/SHM: Could not unlink shared memory file '%s'!\n", pool->filename ); shared->active = false; pool->attached = false; D_FREE( pool->filename ); D_MAGIC_CLEAR( pool ); fusion_skirmish_destroy( &shared->lock ); D_MAGIC_CLEAR( shared );}/**********************************************************************************************************************/void_fusion_shmpool_process( FusionWorld *world, int pool_id, FusionSHMPoolMessage *msg ){ int i; DirectResult ret; FusionSHM *shm; FusionSHMShared *shared; D_DEBUG_AT( Fusion_SHMPool, "%s( %p, %d, %p )\n", __FUNCTION__, world, pool_id, msg ); D_MAGIC_ASSERT( world, FusionWorld ); shm = &world->shm; D_MAGIC_ASSERT( shm, FusionSHM ); shared = shm->shared; D_MAGIC_ASSERT( shared, FusionSHMShared ); ret = fusion_skirmish_prevail( &shared->lock ); if (ret) return; for (i=0; i<FUSION_SHM_MAX_POOLS; i++) { if (shm->pools[i].attached) { D_MAGIC_ASSERT( &shm->pools[i], FusionSHMPool ); if (shm->pools[i].pool_id == pool_id) { switch (msg->type) { case FSMT_REMAP: break; case FSMT_UNMAP: D_UNIMPLEMENTED(); break; } break; } } } fusion_skirmish_dismiss( &shared->lock );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -