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

📄 mem.c

📁 一种操作系统源码核
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif

/*
#include "ebos.h"
/*
*********************************************************************************************************
*                                       Mem module implement FILE
*********************************************************************************************************
*/


/*
*********************************************************************************************************
*                                   Creates a Dyn_MEMory Mem pool and then places it on the list of created Mem pools.

*********************************************************************************************************
*/


static MEM_MCB *MemPoolTable[MAX_POOL_NUM];//存储池向量表
static void CleanupPool(void *information);//存储池清除函数
static MEM_MCB *FreePoolList; //可用存储池列表
/*
*********************************************************************************************************
*              获得一个可用的ID号                       

*********************************************************************************************************
*/
static SIGNED _NewPoolId()
{
	static UNSIGNED Next_ID;
	UNSIGNED  id;			/* process id to return		*/
       	EnLock();
	if((id=Next_ID++)< MAX_POOL_NUM){
            	if (MemPoolTable[id] == NULL){
	       		UnLock();
	       		return(id);
	    	}
	}
	else if(FreePoolList){
	    	id=FreePoolList->id;
	    	#if ENABLE_MEM
			FreeBuff(FreePoolList);
	    	#endif
	    	FreePoolList=FreePoolList->next;
	    	UnLock();
	    	return(id);
	}
	UnLock();
	return(NO_POOL_SPACE);

}
/*
*********************************************************************************************************
*                                   创建一个块存储池

*********************************************************************************************************
*/
SIGNED CreateBlockMemPool(MEM_MCB *pool_ptr, void *start_address,INT32U pool_size)
{
	SIGNED pool_id;
	struct BLOCK_STRUCT * pheader;
	if (pool_ptr==NULL)  return(ERR_INVALID_POOL);
	if(start_address==NULL) return(ERR_INVALID_MEMORY);
	if(pool_size<sizeof(struct BLOCK_STRUCT)) return(ERR_INVALID_SIZE);
        if (MemPoolTable[pool_ptr->id]==pool_ptr)
       	     	return pool_ptr->id;
	pool_id=_NewPoolId();
        if(pool_id<0)
               	return (pool_id);
	#if DEBUG
	     	DebugLog(CREATE_BLOCK_POOL,pool_ptr->id);//在日志中记录操作,时间等信息
	#endif
 	MemPoolTable[pool_id]=pool_ptr;
	pool_ptr->id =pool_id ;
	pool_ptr->current_protect=NULL;
	pool_ptr->start_address=start_address;
	pool_ptr->pool_size=pool_size;
	pool_ptr->suspend_type=FIFO;
	pool_ptr->task_wait_header=NULL;
	pheader= (struct BLOCK_STRUCT *)start_address;
	pheader->block_size=pool_size;
	pheader->next= pheader;
	pheader->prev= pheader;
	pool_ptr->available_header=pheader;
        return(pool_id);

}
/*
*********************************************************************************************************
*                                   创建一个分区存储池

*********************************************************************************************************
*/
SIGNED CreateEvenMemPool(MEM_MCB *pool_ptr,void *start_address,INT32U pool_size,UNSIGNED partition_size)
{
	UNSIGNED pages,i;
	struct BLOCK_STRUCT * pheader;
	SIGNED pool_id;
	if (pool_ptr==NULL)  return(ERR_INVALID_POOL);
	if(start_address==NULL) return(ERR_INVALID_MEMORY);
	if(partition_size<sizeof(struct BLOCK_STRUCT) ||pool_size==0 ||partition_size>pool_size ) return(ERR_INVALID_SIZE);
       	if (MemPoolTable[pool_ptr->id]==pool_ptr)
       	     	return pool_ptr->id;
	pool_id=_NewPoolId();
	if(pool_id<0)
              	return (pool_id);
	#if DEBUG
	     	DebugLog(CREATE_EVEN_POOL,pool_ptr->pool_id);//在日志中记录操作,时间等信息
	#endif
	MemPoolTable[pool_id]=pool_ptr;
        pages=pool_size/partition_size;
        pool_ptr->id =pool_id ;
	pool_ptr->current_protect=NULL;
	pool_ptr->start_address=start_address;
	pool_ptr->pool_size=pool_size;
        pool_ptr->partition_size=partition_size;
	pool_ptr->suspend_type=FIFO;
	pool_ptr->task_wait_header=NULL;
	pool_ptr->availables=pages;
	pool_ptr->available_header=(struct BLOCK_STRUCT *)start_address;
	pheader=pool_ptr->available_header;
	for(i=0;i<pages;i++){
	     	pheader->next=(struct BLOCK_STRUCT *)((INT8U *)start_address+(i+1)*partition_size);
	     	pheader->block_size=partition_size;
	     	pheader=pheader->next;
	} 
	pheader->next=NULL;
        return(pool_id);

}
/*
*********************************************************************************************************
*                                   删除一个存储池

*********************************************************************************************************
*/
STATUS DeleteMemPool(SIGNED pool_id)
{
    	STATUS state,oldstate;
    	MEM_MCB *pool_ptr;
    	if (pool_id<0 || pool_id >=MAX_POOL_NUM) {                                 /* Not allowed to delete idle task     */
        	return (ERR_INVALID_POOL);
    	}
    	pool_ptr=MemPoolTable[pool_id];
    	#if DEBUG
        	DebugLog(DELETE_MEMPOOL,pool_id);//在日志中记录操作,时间等信息
    	#endif
    	oldstate=0;
    	DoProtect(pool_ptr);
    	if (pool_ptr == NULL)                                 /* Not allowed to delete idle pool     */
        	return (ERR_INVALID_POOL);
     	if(pool_ptr->ref_count){   //如果有任务等待,肯定该池被其它任务占用,否则没有任务等待
    	     	UnProtect(pool_ptr);  //在删除一个还在使用的池时是不安全的
          	return  ERR_INVALID_DELETE;
        }    
    	// while(pool_ptr->task_wait_header){
    	//     state=_ResumeTask(pool_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
    	//	if(state==TRUE)
    	//	    oldstate =state;
    	//	DelHead(&(void *)(pool_ptr->task_wait_header));
    	//  }
    	MemPoolTable[pool_id]=NULL;
    	UnProtect(pool_ptr);
    	EnLock();
    	pool_ptr->next=FreePoolList;
    	FreePoolList=pool_ptr;
    	MemPoolTable[pool_id]=NULL;
    	UnLock();
    	if(oldstate==TRUE)
        	_ControlToSystem();
    	return (OK);

}
/*
*********************************************************************************************************
*                                      存储池参数设置函数

*********************************************************************************************************
*/
STATUS SysPoolCtl(SIGNED pool_id,INT8U cmd,INT8U param)
{
	STATUS ret;
	MEM_MCB *pool_ptr;
        if (pool_id<0 || pool_id >=MAX_POOL_NUM) {                                 /* Not allowed to delete idle task     */
           	return (ERR_INVALID_POOL);
        }
   	#if DEBUG
            	DebugLog(SYS_POOL_CTL,pool_id);//在日志中记录操作,时间等信息
        #endif
        pool_ptr=MemPoolTable[pool_id];
        DoProtect(pool_ptr);
	if (pool_ptr == NULL) {
	   	return (ERR_INVALID_POOL); /* Not allowed is idle task     */
	 }
	switch(cmd){
	   	case SUSPEND_TYPE:
 	      		pool_ptr->suspend_type=param;
	      		ret=OK;
	      		break;
	   	default:
	      		ret=ERR_INVALID_CMD;
	      		break;
        }
        UnProtect(pool_ptr);
	return(ret);
}

/*
*********************************************************************************************************
*            从块存储池分配一个存储块,

*********************************************************************************************************
*/
STATUS AllocMem(SIGNED pool_id,void **return_pointer,INT32U size,SIGNED suspend)
{
	WAIT_QUEUE *suspend_list;
	struct	BLOCK_STRUCT *p,*leftover;
	WAIT_QUEUE *task_suspend;
	MEM_MCB *pool_ptr;
	#if WAIT_QUEUE_ALLOC_MODE	
            	task_suspend=WaitQueueFreeList;
            	WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
        #else
            	WAIT_QUEUE  mem_wait_queue;
            	task_suspend=&mem_wait_queue;
            	
        #endif  
        if (return_pointer == NULL)                                  /* Not allowed to delete idle pool     */
	    	return (ERR_INVALID_POINTER);
        if (size<=0)
	    	return (ERR_INVALID_SIZE);    
        if (pool_id<0 || pool_id >=MAX_POOL_NUM) {                                 /* Not allowed to delete idle task     */
            	return (ERR_INVALID_POOL);
        }
        pool_ptr=MemPoolTable[pool_id];
      	#if DEBUG
	    	DebugLog(ALLOC_MEM,pool_id);//在日志中记录操作,时间等信息
	#endif
        DoProtect(pool_ptr);
	if (pool_ptr == NULL)                               /* Not allowed to delete idle pool     */
            	return (ERR_INVALID_POOL);
	p=pool_ptr->available_header;
	do{
	    	if ( p->block_size == size) {
	        	DelList(&(void *)(pool_ptr->available_header),p);
         		UnProtect(pool_ptr);
	        	return (OK);
	    	}
	    	else if ( p->block_size > size ) {
			*return_pointer= (void *)p;
			leftover = (struct  BLOCK_STRUCT *)( (INT8U *)p + size );
			leftover->block_size = p->block_size - size;
			p->prev->next = leftover;
			leftover->prev=p->prev;
			leftover->next = p->next;
			p->next->prev=leftover;
 	        	if (p==pool_ptr->available_header) {
		     		pool_ptr->available_header=leftover;
		 	}
     	        	UnProtect(pool_ptr);
			return (OK);
	    	}
	    	p=p->next;
	}while (p!=pool_ptr->available_header);
	if(suspend!=NO_SUSPEND){
	    	if(((TASK_TCB *)KERNAL.current_thread)->type !=TASK) {
	 		UnProtect(pool_ptr);
	 		return(ERR_INVALID_SUSPEND);
	    	}
            	pool_ptr->tasks_waiting++;
	    	task_suspend->mem_request_size=size;
	    	task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
	    	task_suspend->mem_return_pointer=NULL;
  	    	task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);
	    	AddList(&(void *)(pool_ptr->task_wait_header),task_suspend,pool_ptr->suspend_type);
  	    	UnProtect(pool_ptr);
  	    	_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupPool,pool_ptr,suspend);
            	_ControlToSystem();
	    	Enlock(); 
           	#if WAIT_QUEUE_ALLOC_MODE
 			task_suspend->queue_ptr=WaitQueueFreeList;
 			WaitQueueFreeList=task_suspend;
 		#endif
	    	if (task_suspend->mem_return_pointer==NULL){
	    		Unlock(); 
	        	return(ERR_TIMEOUT);
	    	}
	    	
	    	if(pool_ptr==NULL) {
	    		Unlock(); 
	        	return(ERR_POOL_DELETED);
	        }	
            	pool_ptr->tasks_waiting--;      
	    	*return_pointer=task_suspend->mem_return_pointer;
	    	DelList(&(void *)(pool_ptr->task_wait_header),task_suspend);
	    	Unlock();
	    	
	    	
 	    	return (OK);
	}
  	else
	    	return(ERR_NO_MEMORY);

}
/*
*********************************************************************************************************
*            从一个分区存储池分配一个存储块,

*********************************************************************************************************
*/
STATUS AllocBuff(SIGNED pool_id,void **return_pointer,SIGNED suspend)
{
	WAIT_QUEUE *suspend_list;
        struct BLOCK_STRUCT *pheader;
	WAIT_QUEUE *task_suspend;
	MEM_MCB *pool_ptr;
	UNSIGNED *buf;
        #if WAIT_QUEUE_ALLOC_MODE	
            	task_suspend=WaitQueueFreeList;
            	WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
            	
        #else
            	WAIT_QUEUE  mem_wait_queue;
            	task_suspend=&mem_wait_queue;
        #endif        
        if (return_pointer == NULL)                                  /* Not allowed to delete idle pool     */
		return (ERR_INVALID_POINTER);
        if (pool_id<0 || pool_id >=MAX_POOL_NUM) {                                 /* Not allowed to delete idle task     */
            	return (ERR_INVALID_POOL);
        }
        pool_ptr=MemPoolTable[pool_id];
	#if DEBUG
	    	DebugLog(ALLOC_BUFF,pool_id);//在日志中记录操作,时间等信息
	#endif
	DoProtect(pool_ptr);
	if (pool_ptr == NULL)                                  /* Not allowed to delete idle pool     */
	    	return (ERR_INVALID_POOL);
	if(pool_ptr->availables>0){
	    	(pool_ptr->availables)--;
	    	buf=(UNSIGNED *)(pool_ptr->available_header);
	    	*buf++=pool_id;
	       	*return_pointer=buf;
	    	pool_ptr->available_header=(pool_ptr->available_header)->next;
	      	++pool_ptr->ref_count;
	    	UnProtect(pool_ptr);
	    	return (OK);
	}
	else if(suspend!=NO_SUSPEND){
	    	if(((TASK_TCB *)KERNAL.current_thread)->type!=TASK) {
	 		UnProtect(pool_ptr);
	 		return(ERR_INVALID_SUSPEND);
	    	}
	    	pool_ptr->tasks_waiting++;
	    	task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
	    	task_suspend->mem_return_pointer=NULL;
 	    	task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);;
	    	AddList(&(void *)(pool_ptr->task_wait_header),task_suspend,pool_ptr->suspend_type);
	    	UnProtect(pool_ptr);
	    	_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupPool,pool_ptr,suspend);

⌨️ 快捷键说明

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