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

📄 mem.c

📁 一种操作系统源码核
💻 C
📖 第 1 页 / 共 2 页
字号:
	    	_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);
	       	}	
	       	buf=(UNSIGNED *)(task_suspend->mem_return_pointer);
	    	*buf++=pool_id;
	       	*return_pointer=buf;
	      	pool_ptr->tasks_waiting--;  
	    	DelList(&(void *)(pool_ptr->task_wait_header),task_suspend);
	    	Unlock();
	    	
	    	
	    	return (OK);
	}
	else{
	    	UnProtect(pool_ptr);
	    	return(ERR_NO_MEMORY);
       	}
}



/*
*********************************************************************************************************
*            释放先前分配的一个分区到其存储池,若有任务在存储池上等待分配,则释放给等待队列上的某个任务

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

STATUS FreeBuff(void *memory)
{
	STATUS status;
	SIGNED pool_id;
	MEM_MCB *pool_ptr;
        TASK_TCB *task_ptr;
	SIGNED i;
        if (memory== NULL )                                  /* Not allowed to delete idle pool     */
	    	return (ERR_INVALID_POINTER);
	pool_id=*((SIGNED *)memory-1);
	
	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((INT8U *)memory<pool_ptr->start_address || ((INT8U *)memory+pool_ptr->partition_size)>(pool_ptr->start_address+pool_ptr->pool_size))
           	return (ERR_INVALID_POINTER);
        
   	#if DEBUG
	    	DebugLog(FREE_BUFF,pool_id);//在日志中记录操作,时间等信息
	#endif
	
	DoProtect(pool_ptr);
	if(pool_ptr->task_wait_header){
	    	task_ptr=(pool_ptr->task_wait_header)->task_ptr;
	   	pool_ptr->task_wait_header->mem_return_pointer=memory;
	    	status=_ResumeTask(task_ptr,EVENT_SUSPEND);
	    	if (status==TRUE)
	        	_ControlToSystem();
	    	UnProtect(pool_ptr);
	    	return(OK);
	}
	else{
	    	(pool_ptr->availables)++;
	    	--pool_ptr->ref_count;
	    	((struct BLOCK_STRUCT *)memory)->block_size=pool_ptr->partition_size;
	    	((struct BLOCK_STRUCT *)memory)->next=pool_ptr->available_header;
	    	pool_ptr->available_header=memory;
	    	UnProtect(pool_ptr);
	    	return (OK);
	}
}
/*
*********************************************************************************************************
*            释放先前分配的一个存储块给等待队列上的任务使用

*********************************************************************************************************
*/
STATUS _FreeTask(MEM_MCB *pool_ptr,void **free_memory,INT32U *size)
{
    	STATUS status,oldstatus;
    	TASK_TCB *task_ptr;
    	WAIT_QUEUE *suspend_list;
    	ULONG request_size;
    	oldstatus=FALSE;
    	suspend_list=(WAIT_QUEUE *)(pool_ptr->task_wait_header);
    	if (suspend_list){
       		do {
          		request_size=suspend_list->mem_request_size;
          		if ((*size) >= request_size){
	      			task_ptr=suspend_list->task_ptr;
	      			suspend_list->mem_return_pointer=*free_memory;
	      			status=_ResumeTask(task_ptr,EVENT_SUSPEND);
	      			if (status==TRUE)
	          			oldstatus=status;
	      			*size=*size-request_size;
  	      			(*free_memory)=(INT8U *)(*free_memory)+request_size;
	      			if (*size==0) 
	         		break;
          		}//end if
          		suspend_list=(WAIT_QUEUE *)(suspend_list->next);
       		}while(suspend_list!=(WAIT_QUEUE *)(pool_ptr->task_wait_header));
   	} //end if
   	return (oldstatus);
}

//如果定期执行碎片的回收,是否可行
/*
*********************************************************************************************************
*            释放先前分配的一个存储块到其存储池,若有任务在存储池上等待分配,则释放给等待队列上的某个任务
             并执行碎快的合并
*********************************************************************************************************
*/

STATUS FreeMem(void *memory,INT32U size)
{
	STATUS status;
	BOOLEAN found;
	MEM_MCB *pool_ptr;
	struct	BLOCK_STRUCT *block;
	struct	BLOCK_STRUCT *p,*q;
	INT8U *top;
	SIGNED i;
	ULONG j;
	if (memory== NULL )                                /* Not allowed to delete idle pool     */
	      	return (ERR_INVALID_POINTER);
	if (size==0 )
	      	return (ERR_INVALID_SIZE);
	#if DEBUG
	      	DebugLog(FREE_MEM,pool_id);//在日志中记录操作,时间等信息
        #endif

	 /**************************************************************************
	 寻找所在的存储池
	 ***************************************************************************/

	found=FALSE;
	EnLock();
	for (i=MAX_POOL_NUM-1; i>=0 ; i--){
	    	if(MemPoolTable[i]==NULL)
	        	continue;
	    	if ((memory>=MemPoolTable[i]->start_address) && ((INT8U *)memory < (INT8U *)(MemPoolTable[i]->start_address)+MemPoolTable[i]->pool_size)){
			found=TRUE;
			break;
	     	}
	}
	UnLock();
	if (!found)
	     	return (ERR_INVALID_POINTER);
	pool_ptr=MemPoolTable[i];
	DoProtect(pool_ptr);
	status=_FreeTask(pool_ptr,&memory,&size);
	if(size==0) {//释放的存储块完全释放给等待任务使用
	     	if (status==TRUE)
	         	_ControlToSystem();
	     	UnProtect(pool_ptr);
	     	return (OK);
	}
	if(size>0)//等待的任务未用完释放的存储块,插入链表
	     	block = (struct BLOCK_STRUCT *)memory;
	p= pool_ptr->available_header;
	do{
		if(p>block) break;
		p=p->next;
	}while (p!=pool_ptr->available_header);
	q=p->prev;
	if ((top=(INT8U *)q + q->block_size)>(INT8U *)block && q!=pool_ptr->available_header ||
	     	p!=NULL && ((INT8U *)block +size) > (INT8U *)p ) {
	        UnProtect(pool_ptr);
		return (ERR_INVALID_POINTER);
	}
	if(p==NULL){
            	block->next =block;
	    	block->prev=block;
	    	block->block_size = size;
	    	pool_ptr->available_header=block;
	    	q=block;
	}

	else if (top == (INT8U *)block )
	    	q->block_size += size;
	else {
	    	block->block_size = size;
	    	block->next = p;
	    	p->prev=block;
	    	q->next = block;
	    	block->prev=q;
	    	if(p==pool_ptr->available_header)
	        	pool_ptr->available_header=block;
     	    	q = block;
	}
	if (( q->block_size + (INT8U *)q ) == (INT8U *)p) {
	    	q->block_size += p->block_size;
	    	q->next = p->next;
	    	p->next->prev=q;
	    	if(p==pool_ptr->available_header)
			pool_ptr->available_header=q;

	}
	block =q;
	j=q->block_size;
	if(j!=size)
	    	status= _FreeTask(pool_ptr,&(void *)q,&j);
	if(j==0){
	    	block->prev->next=block->next;
	    	block->next->prev= block->prev;
	    	if(block->next==pool_ptr->available_header)
	        	pool_ptr->available_header=NULL;

	}
	else if(j<block->block_size){  //未用完合并后的存储块,重新插入链表
	    	q->block_size=j;
	    	block->prev->next=q;
	    	q->prev=block->prev;
	    	q->next=block->next;
	    	block->next->prev=q;
	    	if(block==pool_ptr->available_header)
	        	pool_ptr->available_header=q;

	}
	else
	    	--pool_ptr->ref_count;
	UnProtect(pool_ptr);
	if (status==TRUE) 
	     	_ControlToSystem();
	return (OK);


}
/*
*********************************************************************************************************
*                                    在一个存储池上的挂起结构上的某个任务恢复或删除时,清除相应等待列表上的项

*********************************************************************************************************
*/
static void CleanupPool(void *information)
{
     	MEM_MCB *pool_ptr;
     	TASK_TCB *task_ptr;
     	WAIT_QUEUE *linknode;
     	pool_ptr=(MEM_MCB *)information;
     	UnProtect(pool_ptr);
     	EnLock();
     	linknode=pool_ptr->task_wait_header;
     	do{
	 	task_ptr=linknode->task_ptr;
	 	if (task_ptr==((TASK_TCB *)KERNAL.current_thread)){
	      		pool_ptr->tasks_waiting--;  
	      		DelList(&(void *)(pool_ptr->task_wait_header),linknode);
	      	        #if WAIT_QUEUE_ALLOC_MODE
   				linknode->queue_ptr=WaitQueueFreeList;
 				WaitQueueFreeList=linknode;
      			#endif
	 	}
	 	linknode=(WAIT_QUEUE *)(linknode->next) ;
	 	if (linknode==NULL) 
	    		break;
     	}while(linknode!=pool_ptr->task_wait_header);
     	UnLock();
}
/*
*********************************************************************************************************
*                              列出系统中存在的存储池信息

*********************************************************************************************************
*/
STATUS ListMemPool(SIGNED pool_id,POOL_DATA **pool_lst)
{
       	struct BLOCK_STRUCT *pheader;
       	UNSIGNED num,i;
       	MEM_MCB *pool_ptr;
       	if (pool_id+1<0 || pool_id >=MAX_POOL_NUM) {                                 /* Not allowed to delete idle task     */
           	return (ERR_INVALID_POOL);
       	}
       	if(pool_id>=0){
       		pool_ptr=MemPoolTable[pool_id];
       		DoProtect(pool_ptr);
       		if (pool_ptr == NULL)                                 /* Not allowed to delete idle task     */
			return (ERR_INVALID_POOL);
       		pheader=(struct BLOCK_STRUCT *)(pool_ptr->available_header);
       		num=0;
       		do {
	  		num+=pheader->block_size;
	  		pheader=pheader->next;
       		}while((pheader!= (struct BLOCK_STRUCT *)pool_ptr->available_header) && (pheader!=NULL));
		(*pool_lst)->availables=num;
		(*pool_lst)->suspend_type=pool_ptr->suspend_type;
		(*pool_lst)->ref_count=pool_ptr->ref_count;
		(*pool_lst)->tasks_waiting=pool_ptr->tasks_waiting;
		(*pool_lst)->task_id=(pool_ptr->task_wait_header)->task_ptr->id;
		UnProtect(pool_ptr);
		return (OK);
	}
	else{
		for(i=0;i<MAX_POOL_NUM;i++){
			pool_ptr=MemPoolTable[pool_id];
			DoProtect(pool_ptr);
			if (pool_ptr){                                 /* Not allowed to delete idle task     */
				pheader=(struct BLOCK_STRUCT *)(pool_ptr->available_header);
				num=0;
				do {
					num+=pheader->block_size;
					pheader=pheader->next;
				}while((pheader!= (struct BLOCK_STRUCT *)pool_ptr->available_header) && (pheader!=NULL));
				(*pool_lst)->availables=num;
				(*pool_lst)->suspend_type=pool_ptr->suspend_type;
				(*pool_lst)->ref_count=pool_ptr->ref_count;
				(*pool_lst)->tasks_waiting=pool_ptr->tasks_waiting;
				(*pool_lst)->task_id=(pool_ptr->task_wait_header)->task_ptr->id;
				(pool_lst)++;
       			}	
       			UnProtect(pool_ptr);	
       		}
       		return (OK);
       	}	 	
}

/*
*********************************************************************************************************
*                           存储池模块的初始化
创建两个系统使用的存储池
*********************************************************************************************************
*/
#define  TCB_POOL_SIZE   1024
#define  STACK_POOL_SIZE  4096
static MEM_MCB SysMemPool;
static MEM_MCB EventPool;
static MEM_MCB TcbPool;
static MEM_MCB StackPool;
 void KernalMemInit(void *first_available_memory)
 {
	void *pointer;
	KERNAL.mem_pool=CreateBlockMemPool(&SysMemPool,first_available_memory,SYS_POOL_SIZE);
	AllocMem(KERNAL.mem_pool,&pointer,EVENT_POOL_SIZE,-1);
	KERNAL.event_pool=CreateEvenMemPool(&EventPool,pointer,EVENT_POOL_SIZE,sizeof(OS_EVENT));
	AllocMem(KERNAL.mem_pool,&pointer,TCB_POOL_SIZE,-1);
	KERNAL.task_pool=CreateEvenMemPool(&TcbPool,pointer,TCB_POOL_SIZE,sizeof(TASK_TCB));
	AllocMem(KERNAL.mem_pool,&pointer,STACK_POOL_SIZE,-1);
	KERNAL.stack_pool=CreateEvenMemPool(&StackPool,pointer,STACK_POOL_SIZE,sizeof(STK_DEFAULT));

 }

void MemPoolInit(void)
{
  	UNSIGNED i;
  	for(i=0;i<MAX_POOL_NUM;i++)
      		MemPoolTable[i]=NULL;


}

⌨️ 快捷键说明

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