⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heap.c

📁 DirectFB-1.0.1可用于linux的嵌入式GUI
💻 C
📖 第 1 页 / 共 3 页
字号:
                    prev->prev->next = next;                    if (next != NULL)                         next->prev = prev->prev;                    heap->heapinfo[block].busy.type = 0;                    heap->heapinfo[block].busy.info.size = 1;                    /* Keep the statistics accurate.  */                    heap->chunks_used++;                    heap->bytes_used += BLOCKSIZE;                    heap->chunks_free -= BLOCKSIZE >> type;                    heap->bytes_free -= BLOCKSIZE;                    _fusion_shfree( heap, ADDRESS (block) );               }               else if (heap->heapinfo[block].busy.info.frag.nfree != 0) {                    /* If some fragments of this block are free, link this                       fragment into the fragment list after the first free                       fragment of this block. */                    next = (struct list *) ptr;                    next->next = prev->next;                    next->prev = prev;                    prev->next = next;                    if (next->next != NULL)                         next->next->prev = next;                    heap->heapinfo[block].busy.info.frag.nfree++;               }               else {                    /* No fragments of this block are free, so link this                       fragment into the fragment list and announce that                       it is the first free fragment of this block. */                    prev = (struct list *) ptr;                    heap->heapinfo[block].busy.info.frag.nfree = 1;                    heap->heapinfo[block].busy.info.frag.first = (unsigned long int)                                                                   ((unsigned long int) ((char *) ptr - (char *) NULL)                                                                    % BLOCKSIZE >> type);                    prev->next = heap->fraghead[type].next;                    prev->prev = &heap->fraghead[type];                    prev->prev->next = prev;                    if (prev->next != NULL)                         prev->next->prev = prev;               }               break;     }}/**********************************************************************************************************************/DirectResult__shmalloc_init_heap( FusionSHM  *shm,                      const char *filename,                      void       *addr_base,                      int         space,                      int        *ret_fd,                      int        *ret_size ){     DirectResult     ret;     int              size;     FusionSHMShared *shared;     int              heapsize = (space + BLOCKSIZE-1) / BLOCKSIZE;     int              fd       = -1;     shmalloc_heap   *heap     = NULL;     struct group    *pGroupInfo;     D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, '%s', %p, %p )\n",                 __FUNCTION__, shm, filename, addr_base, ret_fd );     D_MAGIC_ASSERT( shm, FusionSHM );     D_ASSERT( filename != NULL );     D_ASSERT( addr_base != NULL );     D_ASSERT( ret_fd != NULL );     D_ASSERT( ret_size != NULL );     shared = shm->shared;     D_MAGIC_ASSERT( shared, FusionSHMShared );     D_ASSERT( shared->tmpfs[0] != 0 );     size = BLOCKALIGN(sizeof(shmalloc_heap)) + BLOCKALIGN( heapsize * sizeof(shmalloc_info) );     D_DEBUG_AT( Fusion_SHMHeap, "  -> opening shared memory file '%s'...\n", filename );     /* open the virtual file */     fd = open( filename, O_RDWR | O_CREAT | O_TRUNC, 0660 );     if (fd < 0) {          ret = errno2result(errno);          D_PERROR( "Fusion/SHM: Could not open shared memory file '%s'!\n", filename );          goto error;     }     if (fusion_config->shmfile_group) {          // obtain the group id #          pGroupInfo = getgrnam(fusion_config->shmfile_group);          // chgrp the SH_FILE dev entry          if (fchown(fd, -1, pGroupInfo->gr_gid) != 0) {               D_WARN("Fusion/SHM: changing permissions on /dev/shm/fusion.# failed... continuing on.");          }     }     fchmod( fd, 0660 );     ftruncate( fd, size );     D_DEBUG_AT( Fusion_SHMHeap, "  -> mmaping shared memory file... (%d bytes)\n", size );     /* map it shared */     heap = mmap( addr_base, size + space, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0 );     if (heap == MAP_FAILED) {          ret = errno2result(errno);          D_PERROR( "Fusion/SHM: Could not mmap shared memory file '%s'!\n", filename );          goto error;     }     close( fd );     fd = -1;     if (heap != addr_base) {          D_ERROR( "Fusion/SHM: mmap() returned address (%p) differs from requested (%p)\n", heap, addr_base );          ret = DFB_FUSION;          goto error;     }     D_DEBUG_AT( Fusion_SHMHeap, "  -> done.\n" );     heap->size     = size;     heap->heapsize = heapsize;     heap->heapinfo = (void*) heap + BLOCKALIGN(sizeof(shmalloc_heap));     heap->heapbase = (char*) heap->heapinfo;     D_MAGIC_SET( heap, shmalloc_heap );     *ret_fd   = fd;     *ret_size = size;     return DFB_OK;error:     if (heap)          munmap( heap, size );     if (fd != -1) {          close( fd );          unlink( filename );     }     return ret;}DirectResult__shmalloc_join_heap( FusionSHM  *shm,                      const char *filename,                      void       *addr_base,                      int         size,                      int        *ret_fd ){     DirectResult     ret;     FusionSHMShared *shared;     int              fd   = -1;     shmalloc_heap   *heap = NULL;     D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, '%s', %p, %d, %p )\n",                 __FUNCTION__, shm, filename, addr_base, size, ret_fd );     D_MAGIC_ASSERT( shm, FusionSHM );     D_ASSERT( filename != NULL );     D_ASSERT( addr_base != NULL );     D_ASSERT( size >= sizeof(shmalloc_heap) );     D_ASSERT( ret_fd != NULL );     shared = shm->shared;     D_MAGIC_ASSERT( shared, FusionSHMShared );     D_ASSERT( shared->tmpfs[0] != 0 );     D_DEBUG_AT( Fusion_SHMHeap, "  -> opening shared memory file '%s'...\n", filename );     /* open the virtual file */     fd = open( filename, O_RDWR );     if (fd < 0) {          ret = errno2result(errno);          D_PERROR( "Fusion/SHM: Could not open shared memory file '%s'!\n", filename );          goto error;     }     D_DEBUG_AT( Fusion_SHMHeap, "  -> mmaping shared memory file... (%d bytes)\n", size );     /* map it shared */     heap = mmap( addr_base, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0 );     if (heap == MAP_FAILED) {          ret = errno2result(errno);          D_PERROR( "Fusion/SHM: Could not mmap shared memory file '%s'!\n", filename );          goto error;     }     close( fd );     fd = -1;     if (heap != addr_base) {          D_ERROR( "Fusion/SHM: mmap() returned address (%p) differs from requested (%p)\n", heap, addr_base );          ret = DFB_FUSION;          goto error;     }     D_MAGIC_ASSERT( heap, shmalloc_heap );     D_DEBUG_AT( Fusion_SHMHeap, "  -> done.\n" );     *ret_fd = fd;     return DFB_OK;error:     if (heap)          munmap( heap, size );     if (fd != -1)          close( fd );     return ret;}void *__shmalloc_brk( shmalloc_heap *heap, int increment ){     FusionSHMShared     *shm;     FusionWorld         *world;     FusionSHMPool       *pool;     FusionSHMPoolShared *shared;     D_DEBUG_AT( Fusion_SHMHeap, "%s( %p, %d )\n", __FUNCTION__, heap, increment );     D_MAGIC_ASSERT( heap, shmalloc_heap );     shared = heap->pool;     D_MAGIC_ASSERT( shared, FusionSHMPoolShared );     shm = shared->shm;     D_MAGIC_ASSERT( shm, FusionSHMShared );     world = _fusion_world( shm->world );     D_MAGIC_ASSERT( world, FusionWorld );     pool = &world->shm.pools[shared->index];     D_MAGIC_ASSERT( pool, FusionSHMPool );     if (increment) {          int new_size = heap->size + increment;          if (new_size > shared->max_size) {               D_WARN( "maximum shared memory file size (%dk) exceeded (%dk by %dk) in '%s'!",                       shared->max_size >> 10, new_size >> 10, increment >> 10, pool->filename );               fusion_dbg_print_memleaks( shared );               return NULL;          }          if (truncate( pool->filename, new_size ) < 0) {               D_PERROR( "Fusion/SHM: truncating shared memory file '%s' from %dkb to %dkb failed!\n",                         pool->filename, heap->size >> 10, new_size >> 10 );               return NULL;          }          heap->size = new_size;     }     return shared->addr_base + heap->size - increment;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -