嵌入式操作系统内核原理和开发(等值block内存池设计)
来源:互联网 发布:30岁男人打扮风格知乎 编辑:程序博客网 时间:2024/06/07 01:41
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
内存池设计是嵌入式系统的一个重要环节,之前我们也讨论过相关的内容。但是,看了rawos的代码之后,我觉得rawos的内存池设计更有特点。整个内存池的设计非常健壮,不但考虑了字节对齐的问题,而且还引入了等待调度机制,这是我所没有想到的。所以,在此我很愿意和大家分享这份优秀的代码。闲话不多说,我们看看rawos的mempool数据结构是什么样的,
typedef struct MEM_POOL { RAW_COMMON_BLOCK_OBJECT common_block_obj; /* Define the number of available memory blocks in the pool. */ RAW_U32 raw_block_pool_available; /* Define the head pointer of the available block pool. */ RAW_U8 *raw_block_pool_available_list; } MEM_POOL;内存池的结构非常简单,主要包括了通用阻塞结构、block数值,block起始指针。内存池下面可以包括若干个block,每个block的大小都是相等的,同时block之间是通过链表串联在一起的,这个我们看了后面的代码就明白了。mempool的处理函数不多,就三个,初始化、申请、释放函数。
RAW_U16 raw_block_pool_create(MEM_POOL *pool_ptr, RAW_U8 *name_ptr, RAW_U32 block_size, RAW_VOID *pool_start, RAW_U32 pool_size) { //MEM_POOL *tail_ptr; /* Working block pool pointer */ RAW_U32 blocks; /* Number of blocks in pool */ RAW_U8 *block_ptr; /* Working block pointer */ RAW_U8 *next_block_ptr; /* Next block pointer */ RAW_U8 *end_of_pool; /* End of pool area */ RAW_U8 block_align_mask; #if (RAW_BLOCK_FUNCTION_CHECK > 0) /* Check for invalid pool size. */ if (pool_size < (block_size + block_size) ) { return RAW_BLOCK_SIZE_ERROR; } if (pool_ptr == 0) { return RAW_NULL_OBJECT; } if (pool_start == 0) { return RAW_NULL_POINTER; } #endif block_align_mask = sizeof(void *) - 1u; if (((RAW_U32)pool_start & block_align_mask)){ return RAW_INVALID_ALIGN; } if ((pool_size & block_align_mask)) { return RAW_INVALID_ALIGN; } if ((block_size & block_align_mask)) { return RAW_INVALID_ALIGN; } /*Init the list*/ list_init(&pool_ptr->common_block_obj.block_list); /* Setup the basic block pool fields. */ pool_ptr ->common_block_obj.name = name_ptr; pool_ptr ->common_block_obj.block_way = 0; /* Calculate the end of the pool's memory area. */ end_of_pool = (RAW_U8 *) pool_start + pool_size; /* Walk through the pool area, setting up the available block list. */ blocks = 0; block_ptr = (RAW_U8 *) pool_start; next_block_ptr = block_ptr + block_size; while (next_block_ptr <= end_of_pool) { blocks++; if (next_block_ptr == end_of_pool) { break; } /* Setup the link to the next block. */ *((RAW_U8 * *) block_ptr) = next_block_ptr; /* Advance to the next block. */ block_ptr = next_block_ptr; /* Update the next block pointer. */ next_block_ptr = block_ptr + block_size; } /* Set the last block's forward pointer to NULL. */ *((RAW_U8 * *) block_ptr) = 0; /* Save the remaining information in the pool control block. */ pool_ptr ->raw_block_pool_available = blocks; pool_ptr ->raw_block_pool_available_list = (RAW_U8 *) pool_start; return RAW_SUCCESS; }上面就是内存池的创建函数,入参共有五个参数,分别是mempool结构、名称、block大小、pool起始地址、pool大小。函数基本内容如下所示,
(1)判断内存池、指针参数合法性;
(2)检验指针是否n字节对齐,n取决于地址的大小;
(3)构建block链表,前后相连,最后一个block指向NULL指针;
(4)将pool首地址赋值给raw_block_pool_available_list,函数返回。
RAW_U16 raw_block_allocate(MEM_POOL *pool_ptr, RAW_VOID **block_ptr, RAW_U32 wait_option) { RAW_U16status; RAW_U8*work_ptr; RAW_SR_ALLOC(); #if (RAW_BLOCK_FUNCTION_CHECK > 0) if (pool_ptr == 0) { return RAW_NULL_OBJECT; } if (block_ptr == 0) { return RAW_NULL_POINTER; } if (raw_int_nesting) { if (wait_option != RAW_NO_WAIT) { return RAW_NOT_CALLED_BY_ISR; } } #endif RAW_CRITICAL_ENTER(); /* Determine if there is an available block. */ if (pool_ptr ->raw_block_pool_available) { /* Yes, a block is available. Decrement the available count. */ pool_ptr ->raw_block_pool_available--; /* Pickup the current block pointer. */ work_ptr = pool_ptr ->raw_block_pool_available_list; /* Return the first available block to the caller. */ *((RAW_U8 **)block_ptr) = work_ptr; /* Modify the available list to point at the next block in the pool. */ pool_ptr ->raw_block_pool_available_list = *((RAW_U8 **)work_ptr); /* Set status to success. */ status = RAW_SUCCESS; } /*if no block memory is available then do it depend wait_option*/ else { if (wait_option == RAW_NO_WAIT) { *((RAW_U8 **)block_ptr) = 0; RAW_CRITICAL_EXIT(); return RAW_NO_PEND_WAIT; } /*system is locked so task can not be blocked just return immediately*/ if (raw_sched_lock) { *((RAW_U8 **)block_ptr) = 0; RAW_CRITICAL_EXIT(); return RAW_SCHED_DISABLE; } raw_pend_object(&pool_ptr->common_block_obj, raw_task_active, wait_option); RAW_CRITICAL_EXIT(); raw_sched(); RAW_CRITICAL_ENTER(); *((RAW_U8 **)block_ptr) = 0; status = block_state_post_process(raw_task_active, block_ptr); RAW_CRITICAL_EXIT(); } return status; }和其他的内存池申请函数不一样,这里有一个wait_option选项。也就是说,如果当前没有合适的block,那么你可以选择等待处理。一旦别的线程释放内存,你就可以得到调度继续运行了。当然你也可以不等待,一旦寻找不到合适的block,立即返回为NULL。
RAW_U16 raw_block_release(MEM_POOL *pool_ptr, RAW_VOID *block_ptr) { LIST *block_list_head; RAW_U8 *work_ptr; /* Working block pointer */ RAW_U8 need_schedule = 0; RAW_SR_ALLOC(); #if (RAW_BLOCK_FUNCTION_CHECK > 0) if (block_ptr == 0) { return RAW_NULL_OBJECT; } if (pool_ptr == 0) { return RAW_NULL_OBJECT; } #endif block_list_head = &pool_ptr->common_block_obj.block_list; RAW_CRITICAL_ENTER(); work_ptr = ((RAW_U8 *) block_ptr); if (is_list_empty(block_list_head)) { /* Put the block back in the available list. */ *((RAW_U8 **) work_ptr) = pool_ptr ->raw_block_pool_available_list; /* Adjust the head pointer. */ pool_ptr ->raw_block_pool_available_list = work_ptr; /* Increment the count of available blocks. */ pool_ptr ->raw_block_pool_available++; } else { need_schedule = 1; wake_send_msg(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list), block_ptr); } RAW_CRITICAL_EXIT(); if (need_schedule) { raw_sched(); } /* Return completion status. */ return RAW_SUCCESS; }和其他的内存free函数不一样,这里的free函数多了一个wake_send_msg的功能。这也就是说,当然如果存在阻塞等待资源的线程,那么把资源送给该线程,同时把该线程唤醒,还要把need_schedule设置为1才可以。当然如果没有等待的线程,那么直接把内存插入到链表前面中即可,就是这么简单。
- 嵌入式操作系统内核原理和开发(等值block内存池设计)
- 嵌入式操作系统内核原理和开发(等值block内存池设计)
- 嵌入式操作系统内核原理和开发(内存分配算法)
- 嵌入式操作系统内核原理和开发(内存分配算法)
- 嵌入式操作系统内核原理和开发(内存分配算法)
- 嵌入式操作系统内核原理和开发(固定内存分配算法)
- 嵌入式操作系统内核原理和开发(基于链表节点的内存分配算法)
- 嵌入式操作系统内核原理和开发(最快、最优、最差内存分配算法)
- 嵌入式操作系统内核原理和开发(改进的链表内存分配算法)
- 嵌入式操作系统内核原理和开发
- 嵌入式操作系统内核原理和开发
- 嵌入式操作系统内核原理和开发(开篇)
- 嵌入式操作系统内核原理和开发(开篇)
- 嵌入式操作系统内核原理和开发(中断)
- 嵌入式操作系统内核原理和开发(地址空间)
- 嵌入式操作系统内核原理和开发(基础)
- 嵌入式操作系统内核原理和开发(系统中断仿真)
- 嵌入式操作系统内核原理和开发(线程切换)
- Google的编程样式指南
- sqlserver数据类型查看
- 推荐一系列优秀的Android开发源码
- 15所名校计算机专业之特色分析
- android 项目中出现红色感叹号的解决方法
- 嵌入式操作系统内核原理和开发(等值block内存池设计)
- 面试题整理-空格变更
- 数据库系统基础
- C语言变参处理
- SharedPreference存储的使用
- uboot移植到Keil(mdk-arm)笔记
- 常见的动态内存的管理错误
- ReportExporter中导出Excel2007不能修改
- NYOJ - 5个数求最值