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

📄 mempool.c.svn-base

📁 RT-Thread是发展中的下一代微内核嵌入式实时操作系统
💻 SVN-BASE
字号:
/* * File      : partition.c * This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006, RT-Thread Development Team * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.fayfayspace.org/license/LICENSE. * * Change Logs: * Date           Author       Notes * 2006-05-27     Bernard      implement memory pool * 2006-06-03     Bernard      fix the thread timer init bug  * 2006-06-30     Bernard      fix the allocate/free block bug */#include <rthw.h>#include <rtthread.h>#include "kservice.h"#ifdef RT_USING_MEMPOOL/** * @addtogroup Kernel *//*@{*/rt_err_t rt_mp_init(struct rt_mempool* mp, const char* name, void *start, rt_size_t size, rt_size_t block_size){	rt_uint8 *block_ptr;	register rt_base_t offset;	/* parameter check */	RT_ASSERT(mp != RT_NULL);	/* init object */	rt_object_init(&(mp->parent), RT_Object_Class_MemPool, name);	/* init memory pool */	mp->start_address = start;	mp->size = RT_ALIGN(size, RT_ALIGN_SIZE);	mp->block_size = block_size;	/* align to align size byte */	mp->block_total_count = mp->size / (mp->block_size + sizeof(rt_uint8*));	mp->block_free_count = mp->block_total_count;	/* init suspended thread list */	rt_list_init(&(mp->suspend_thread));	mp->suspend_thread_count = 0;	/* init free block list */	block_ptr  = (rt_uint8*) mp->start_address;	for (offset = 0; offset < mp->block_total_count; offset ++)	{		*(rt_uint8**)(block_ptr + offset * (block_size + sizeof(rt_uint8*)))			= (rt_uint8*)(block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8*)));	}	*(rt_uint8**)(block_ptr + offset * (block_size + sizeof(rt_uint8*))) = RT_NULL;	mp->block_list = block_ptr;	return RT_EOK;}rt_err_t rt_mp_detach(struct rt_mempool* mp){	struct rt_thread* thread;	register rt_ubase_t temp;	/* parameter check */	RT_ASSERT(mp != RT_NULL);	/* wakeup all suspended threads */	while (!rt_list_isempty(&(mp->suspend_thread)))	{		/* disable interrupt */		temp = rt_hw_interrupt_disable();		/* get next suspend thread */		thread = rt_list_entry(mp->suspend_thread.next, struct rt_thread, tlist);		/* set error code to RT_ERROR */		thread->error = -RT_ERROR;		/*		 * resume thread 		 * In rt_thread_resume function, it will remove current thread from suspend		 * list		 */		rt_thread_resume(thread);		/* decrease suspended thread count */		mp->suspend_thread_count --;		/* enable interrupt */		rt_hw_interrupt_enable(temp);	}	/* detach object */	rt_object_detach(&(mp->parent));	return RT_EOK;}rt_mp_t rt_mp_create(void *mp_start, const char* name, rt_size_t block_count, rt_size_t block_size){	rt_uint8 *block_ptr;	struct rt_mempool* mp;	register rt_base_t offset;	/* allocate object */	mp = (struct rt_mempool*)rt_object_allocate(RT_Object_Class_MemPool, name);	/* init memory pool */	mp->block_size = RT_ALIGN(block_size, RT_ALIGN_SIZE);	mp->size = (block_size + sizeof(rt_uint8*))* block_count;	/* allocate memory */	mp->start_address = rt_malloc((block_size + sizeof(rt_uint8*))* block_count);	if (mp->start_address == RT_NULL)	{		/* no memory, delete memory pool object */		rt_object_delete(&(mp->parent));		return RT_NULL;	}	mp->block_total_count = block_count;	mp->block_free_count = mp->block_total_count;	/* init suspended thread list */	rt_list_init(&(mp->suspend_thread));	mp->suspend_thread_count = 0;	/* init free block list */	block_ptr  = (rt_uint8*) mp->start_address;	for (offset = 0; offset < mp->block_total_count; offset ++)	{		*(rt_uint8**)(block_ptr + offset * (block_size + sizeof(rt_uint8*)))			= block_ptr + (offset + 1) * (block_size + sizeof(rt_uint8*));	}	*(rt_uint8**)(block_ptr + offset * (block_size + sizeof(rt_uint8*))) = RT_NULL;	mp->block_list = block_ptr;	return mp;}rt_err_t rt_mp_delete(rt_mp_t mp){	struct rt_thread* thread;	register rt_ubase_t temp;	/* parameter check */	RT_ASSERT(mp != RT_NULL);	/* wakeup all suspended threads */	while (!rt_list_isempty(&(mp->suspend_thread)))	{		/* disable interrupt */		temp = rt_hw_interrupt_disable();		/* get next suspend thread */		thread = rt_list_entry(mp->suspend_thread.next, struct rt_thread, tlist);		/* set error code to RT_ERROR */		thread->error = -RT_ERROR;		/*		 * resume thread 		 * In rt_thread_resume function, it will remove current thread from suspend		 * list		 */		rt_thread_resume(thread);		/* decrease suspended thread count */		mp->suspend_thread_count --;		/* enable interrupt */		rt_hw_interrupt_enable(temp);	}	/* release allocated room */	rt_free(mp->start_address);		/* detach object */	rt_object_delete(&(mp->parent));	return RT_EOK;}void *rt_mp_alloc (rt_mp_t mp, rt_int32 time){	rt_uint8* block_ptr;	register rt_base_t level;	struct rt_thread* thread;		/* disable interrupt */	level = rt_hw_interrupt_disable();	if(mp->block_free_count)	{		/* memory block is available. decrease the free block counter */		mp->block_free_count--;		/* get block from block list */		block_ptr = mp->block_list;		mp->block_list = *(rt_uint8**)block_ptr;		/* point to memory pool */		*(rt_uint8**)block_ptr = (rt_uint8*)mp;	}	else	{		/* memory block is unavailable. */		if (time == 0) return RT_NULL;		else		{			/* get current thread */			thread = rt_thread_self();			/* need suspend thread */			rt_thread_suspend(thread);			rt_list_insert_after(&(mp->suspend_thread), &(thread->tlist));			mp->suspend_thread_count++;			if (time > 0)			{				/* init thread timer and start it */				rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time);				rt_timer_start(&(thread->thread_timer));						}			/* enable interrupt */			level = rt_hw_interrupt_disable();			/* do a schedule */			rt_schedule();			if (thread->error != RT_EOK) return RT_NULL;			/* disable interrupt */			level = rt_hw_interrupt_disable();			/* decrease free block */			mp->block_free_count --;			/* get block from block list */			block_ptr = mp->block_list;			mp->block_list = *(rt_uint8**)block_ptr;			/* point to memory pool */			*(rt_uint8**)block_ptr = (rt_uint8*)mp;			}	}	/* enable interrupt */	rt_hw_interrupt_enable(level);	return (rt_uint8*)(block_ptr + sizeof(rt_uint8*));}void rt_mp_free  (void *block){	rt_uint8 **block_ptr;	struct rt_mempool *mp;	struct rt_thread *thread;	register rt_base_t level;	/* get the control block of pool which the block belongs to */	block_ptr = (rt_uint8**)((rt_uint8*)block - sizeof(rt_uint8*));	mp = (struct rt_mempool*) *block_ptr;	rt_kprintf("mp free: %s\n", mp->parent.name);	/* disable interrupt */	level = rt_hw_interrupt_disable();	/* increase the free block count */	mp->block_free_count ++;	/* link the block into the block list */	*block_ptr = mp->block_list;	mp->block_list = (rt_uint8*)block_ptr;	if (mp->suspend_thread_count > 0)	{		/* get the suspended thread */		thread = rt_list_entry(mp->suspend_thread.next, struct rt_thread, tlist);		/* set error */		thread->error = RT_EOK;		/* resume thread */		rt_thread_resume(thread);		/* decrease suspended thread count */		mp->suspend_thread_count --;		/* enable interrupt */		rt_hw_interrupt_enable(level);		/* do a schedule */		rt_schedule();		return;	}	/* enable interrupt */	rt_hw_interrupt_enable(level);}#endif/*@}*/

⌨️ 快捷键说明

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