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

📄 ip51_dmc.c

📁 基于51的动态内存管理
💻 C
📖 第 1 页 / 共 2 页
字号:
DM_HEADER   *new_ptr;                    /* New split block pointer   */
unsigned int free_size;                  /* Size of block found       */
STATUS          status;                     /* Completion status         */

    pool =  (DM_PCB *) pool_ptr;
    if (pool == NULL)
        {   
        status =  IP51_INVALID_POOL;
        return(status);
        }
    else if (pool -> dm_id != DM_DYNAMIC_ID)
        {
        status =  IP51_INVALID_POOL;
        return(status);
        }

    /* Initialize the status as successful.  */
    status =  SUCCESS;

    //请求的内存大小最小是内存池的允许的最小值   
    if (size < pool -> dm_min_allocation)
        size =  pool -> dm_min_allocation;
    else

        //保证申请的内存大小是unsigned int 的整数倍
        size =
           ((size + sizeof(unsigned int) - 1)/sizeof(unsigned int)) * sizeof(unsigned int);

    //搜索内存列表检查是否有第一个可以用的内存块来满足要求
    memory_ptr =  pool -> dm_search_ptr;
    do
    {

        //看该块的空闲区是否满足要求
        if (memory_ptr -> dm_memory_free)

            //计算空闲块大小
            free_size =  (((BYTE_PTR) (memory_ptr -> dm_next_memory)) -
                           ((BYTE_PTR) memory_ptr)) - DM_OVERHEAD;
        else

            //没有空闲可以用
            free_size =  0;

        //看是否还要继续查找
        if (free_size < size)

            //没有找到足够大的块,寻找下一个块
            memory_ptr =  memory_ptr -> dm_next_memory;
    } while((free_size < size) && (memory_ptr != pool -> dm_search_ptr));

    //是否找到了可以用的块
    if (free_size >= size)
    {

        //找到了

        //看是否需要分割
        if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation))
        {

            //是的
            new_ptr =  (DM_HEADER *) (((BYTE_PTR) memory_ptr) + size +
                                                DM_OVERHEAD);

            //把新的块标成FREE的
            new_ptr -> dm_memory_free =  TRUE;

            /* Put the pool pointer into the new block.  */
            new_ptr -> dm_memory_pool =  pool;

            //建立必要的指针
            new_ptr -> dm_previous_memory =  memory_ptr;
            new_ptr -> dm_next_memory =      memory_ptr -> dm_next_memory;
            (new_ptr -> dm_next_memory) -> dm_previous_memory =  new_ptr;
            memory_ptr -> dm_next_memory =   new_ptr;

            //可应用空间减小
            pool -> dm_available =  pool -> dm_available - size - DM_OVERHEAD;
        }
        else

            //不需要分割,则调整可用空间大小
            pool -> dm_available =  pool -> dm_available - free_size;

        //把以前的状态改为不可用
        memory_ptr -> dm_memory_free =  FALSE;

        //搜索指针改过了吗?
        if (pool -> dm_search_ptr == memory_ptr)

            /* Move the search pointer to the next free memory slot.  */
            pool -> dm_search_ptr =  memory_ptr -> dm_next_memory;

        /* Return a memory address to the caller.  */
        *return_pointer =  (void *) (((BYTE_PTR) memory_ptr) + DM_OVERHEAD);
    }
    else
    {
        //没有足够的空间
        status =            IP51_NO_MEMORY;
        *return_pointer =   NULL;
    }
    /* Return the completion status.  */
    return(status);
}


/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      IP51_DMC_Deallocate_Memory                                            */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*      This function deallocates a previously allocated dynamic memory  */
/*      block.  The deallocated dynamic memory block is merged with any  */
/*      adjacent neighbors.  This insures that there are no consecutive  */
/*      blocks of free memory in the pool (makes the search easier!).    */
/*      If there is a task waiting for dynamic memory, a determination   */
/*      of whether or not the request can now be satisfied is made after */
/*      the deallocation is complete.                                    */
/*                                                                       */
/* CALLED BY                                                             */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*      CSC_Remove_From_List                Remove from suspend list     */
/*                                                                       */
/* INPUTS                                                                */
/*                                                                       */
/*      memory                              Pointer to dynamic memory    */
/*                                                                       */
/* OUTPUTS                                                               */
/*                                                                       */
/*      SUCCESS                                                          */
/*                                                                       */
/* HISTORY                                                               */
/*                                                                       */
/*         DATE                    REMARKS                               */
/*                                                                       */
/*      02-09-2004      Created initial version 1.0                      */
/*                                                                       */
/*************************************************************************/
STATUS  IP51_DMC_Deallocate_Memory(void *memory)
{

DM_PCB      *pool;                       /* Pool pointer              */
DM_HEADER   *header_ptr;                 /* Pointer to memory hdr     */
DM_HEADER   *new_ptr;                    /* New memory block pointer  */
STATUS          status;                     /* Completion status         */

    /* Initialize the status as successful.  */
    status =  SUCCESS;

    /* Pickup the associated pool's pointer.  It is inside the header of
       each memory.  */
    header_ptr =  (DM_HEADER *) (((BYTE_PTR) memory) - DM_OVERHEAD);
    pool =        header_ptr -> dm_memory_pool;

    /* Mark the memory as available.  */
    header_ptr -> dm_memory_free =  TRUE;

    /* Adjust the available number of bytes.  */
    pool -> dm_available =  pool -> dm_available +
                        (((BYTE_PTR) (header_ptr -> dm_next_memory)) -
                           ((BYTE_PTR) header_ptr)) - DM_OVERHEAD;

    //看是否可以和前面的块合并
    if ((header_ptr -> dm_previous_memory) -> dm_memory_free)
    {

        //调整可用的字节数
        pool -> dm_available =  pool -> dm_available + DM_OVERHEAD;

        //和前面的相临的块合并
        (header_ptr -> dm_previous_memory) -> dm_next_memory =
                                header_ptr -> dm_next_memory;
        (header_ptr -> dm_next_memory) -> dm_previous_memory =
                                header_ptr -> dm_previous_memory;

        //把头指针指向前一个
        header_ptr =  header_ptr -> dm_previous_memory;

        //把搜索指针指向新合并的块
        pool -> dm_search_ptr =  header_ptr;
    }

    //再看和后面的相邻的块是否可以合并
    if ((header_ptr -> dm_next_memory) -> dm_memory_free)
    {

        //调整可用字节数
        pool -> dm_available =  pool -> dm_available + DM_OVERHEAD;

        //同下一个块合并
        new_ptr =  header_ptr -> dm_next_memory;
        (new_ptr -> dm_next_memory) -> dm_previous_memory =
                                                header_ptr;
        header_ptr -> dm_next_memory = new_ptr -> dm_next_memory;

        /* Adjust the search pointer to the new merged block.  */
        //调整内存池的搜索指针指向新合并的块
        pool -> dm_search_ptr =  header_ptr;
    }

    /* Return the completion status.  */
    return(status);
}
//以下是测试用的
/*
void main()
{
   unsigned char far test[5000];
   void *use;
   void *use1;
   void *use2;
   void *use3;
   void *use4;

   xdata IP51_MEMORY_POOL my_memory_pool; //声明一个内存池指针
   IP51_DMC_Create_Memory_Pool(&my_memory_pool, "wang",
                        test, 0x5000,100);

   IP51_DMC_Allocate_Memory(&my_memory_pool, &use,0x1000);
   IP51_DMC_Allocate_Memory(&my_memory_pool, &use1,0x1000);
   IP51_DMC_Allocate_Memory(&my_memory_pool, &use2,0x1000);
   IP51_DMC_Allocate_Memory(&my_memory_pool, &use4,0x1000);
   IP51_DMC_Deallocate_Memory(use1);
   IP51_DMC_Deallocate_Memory(use2);
   //IP51_DMC_Deallocate_Memory(use4);
   
   if(IP51_DMC_Allocate_Memory(&my_memory_pool, &use3,0x2000) == IP51_NO_MEMORY)
   {
      IP51_DMC_Allocate_Memory(&my_memory_pool, &use3,0x1000);
   }

   IP51_DMC_Delete_Memory_Pool(&my_memory_pool);
   IP51_DMC_Allocate_Memory(&my_memory_pool, &use2,0x2000);
   
   while(1);

}
*/

⌨️ 快捷键说明

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