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

📄 dms.c

📁 nucleus 2006 source code
💻 C
📖 第 1 页 / 共 2 页
字号:
                    split_size = next_aligned - address;
                }

                /* Adjust free_size for result of front split */
                if (free_size > split_size)

                    free_size -= split_size;

                else

                    /* Can't adjust block beginning, so keep searching */
                    free_size = 0;
            }
        }

        /* Determine if the search should continue.  */
        if (free_size < size)

            /* Large enough block has not been found.  Move the search
               pointer to the next block.  */
            memory_ptr =  memory_ptr -> dm_next_memory;
    } while((free_size < size) && (memory_ptr != pool -> dm_search_ptr));

    /* Determine if the memory is available.  */
    if (free_size >= size)
    {

        /* A block that satisfies the request has been found.  */

        /* Is a front split required? The front split will represent the chunk
           of memory that goes from the last pointer to the aligned address. */
        if(address % alignment != 0)
        {
            /* Not aligned, front split the block, leaving an allocated block. */
            new_ptr = (DM_HEADER*)(((UNSIGNED)(memory_ptr)) + split_size);

            /* Mark the new block as free.  */
            new_ptr -> dm_memory_free =  NU_TRUE;

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

            /* Build the necessary pointers.  */
            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;

            /* Decrement the available byte count by one DM_OVERHEAD. */
            pool -> dm_available = pool -> dm_available - DM_OVERHEAD;

            /* Point to new aligned free block. */
            memory_ptr = new_ptr;
        }

        /* Determine if the remaining block needs to be tail split. */
        if (free_size >= (size + DM_OVERHEAD + pool -> dm_min_allocation))
        {

            /* Yes, split the block.  */
            new_ptr =  (DM_HEADER *) (((BYTE_PTR) memory_ptr) + size +
                                                DM_OVERHEAD);

            /* Mark the new block as free.  */
            new_ptr -> dm_memory_free =  NU_TRUE;

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

            /* Build the necessary pointers.  */
            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;

            /* Decrement the available byte count.  */
            pool -> dm_available =  pool -> dm_available - size - DM_OVERHEAD;
        }
        else

            /* Decrement the entire free size from the available bytes
               count.  */
            pool -> dm_available =  pool -> dm_available - free_size;

        /* Mark the allocated block as not available.  */
        memory_ptr -> dm_memory_free =  NU_FALSE;

        /* Should the search pointer be moved?   */
        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);

#ifdef NU_PROFILE_PLUS

        PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_0

#endif /* NU_PROFILE_PLUS */

    }
    else
    {

        /* Enough dynamic memory is not available.  Determine if suspension is
           required. */
        if (suspend)
        {

            /* Suspension is selected.  */

            /* Increment the number of tasks waiting.  */
            pool -> dm_tasks_waiting++;

#ifdef NU_PROFILE_PLUS

            PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_1

#endif /* NU_PROFILE_PLUS */

            /* Setup the suspend block and suspend the calling task.  */
            suspend_ptr =  &suspend_block;
            suspend_ptr -> dm_memory_pool =              pool;
            suspend_ptr -> dm_request_size =             size;
            suspend_ptr -> dm_suspend_link.cs_next =     NU_NULL;
            suspend_ptr -> dm_suspend_link.cs_previous = NU_NULL;
            task =                            (TC_TCB *) TCT_Current_Thread();
            suspend_ptr -> dm_suspended_task =           task;

            /* Determine if priority or FIFO suspension is associated with the
               memory pool.  */
            if (pool -> dm_fifo_suspend)
            {

                /* FIFO suspension is required.  Link the suspend block into
                   the list of suspended tasks on this memory pool.  */
                CSC_Place_On_List((CS_NODE **)
                        &(pool -> dm_suspension_list),
                                        &(suspend_ptr -> dm_suspend_link));
            }
            else
            {

                /* Get the priority of the current thread so the suspend block
                   can be placed in the appropriate place.  */
                suspend_ptr -> dm_suspend_link.cs_priority =
                                                     TCC_Task_Priority(task);

                CSC_Priority_Place_On_List((CS_NODE **)
                        &(pool -> dm_suspension_list),
                                        &(suspend_ptr -> dm_suspend_link));
            }

            /* Protect against system access.  */
            TCT_System_Protect();

            /* Save the list protection in preparation for suspension.  */
            TCT_Set_Suspend_Protect(&(pool -> dm_protect));

            /* Release protection of dynamic memory pool.  */
            TCT_Unprotect_Specific(&(pool -> dm_protect));

            /* Finally, suspend the calling task. Note that the suspension call
               automatically clears the system protection.  */
            TCC_Suspend_Task((NU_TASK *) task, NU_MEMORY_SUSPEND,
                                        DMC_Cleanup, suspend_ptr, suspend);

            /* Pickup the return status.  */
            status =            suspend_ptr -> dm_return_status;
            *return_pointer =   suspend_ptr -> dm_return_pointer;

#if (NU_PROFILE_PLUS == NU_TRUE)

            PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_2

#endif /* NU_PROFILE_PLUS == NU_TRUE */

        }
        else
        {

            /* No suspension requested.  Simply return an error status.  */
            status =            NU_NO_MEMORY;
            *return_pointer =   NU_NULL;

#ifdef NU_PROFILE_PLUS

            PRF_PLUS_DMS_ALLOCATE_ALIGNED_MEMORY_3

#endif /* NU_PROFILE_PLUS */

        }
    }

    /* Release protection of the memory pool.  */
    TCT_Unprotect();

    /* Return to user mode */
    NU_USER_MODE();

    /* Return the completion status.  */
    return(status);
}






⌨️ 快捷键说明

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