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

📄 sharemem.c

📁 一种操作系统源码核
💻 C
字号:
//共享内存
//多个进程共享一个存储区域,但在某个时刻,只允许一个进程向该区域写。在写后,其它进程都可以读该区域的数据
//
typedef struct	share_mem_struct{
	struct share_mem_struct *next;
       	WAIT_QUEUE *task_wait_header;  //向共享区域写的进程在该区域已经锁定时在该指针指向的结构列表上挂起
       	UNSIGNED    id;                //系统分配的ID
       	INT8U    suspend_type;         //标志指示任务在共享区域上挂起的类型
       	INT8U  lock;             //指示该共享区域是否正在写
       	INT8U reserved[2];
       	UNSIGNED tasks_waiting;
      	void    *start_address;        //存储分区池的开始地址
       	INT32U   mem_size;  //共享区域的尺寸

}SHARE_MEM_MCB;
typedef struct	{
	
       	INT8U   suspend_type;         //标志指示任务在共享区域上挂起的类型
       	INT8U   task_id; 
       	INT8U  	lock;             //指示该共享区域是否正在写
       	UNSIGNED tasks_waiting;
     
}SHARE_MEM_DATA;
static SHARE_MEM_MCB *ShareMemTable[MAX_SHARE_MEM_NUM];

static void ShareMemCleanup(void *information);
static SHARE_MEM_MCB *    ShareMemFreeList
/*
*********************************************************************************************************
*                                      CREATE A ShareMem and then places it on the list of created ShareMemes.
Functions Called
CSC_AddList
[HIC_Make_History_Entry]
[TCT_Check_Stack]
TCT_Protect
TCT_Unprotect
*********************************************************************************************************
*/
static SIGNED _NewShareMemId()
{
	static UNSIGNED Next_ID;
	UNSIGNED  id;			/* process id to return		*/
	UNSIGNED  i;
        EnLock();
	for (i=0 ; i<MAX_SHARE_MEM_NUM ; i++) {	/* check all NPROC slots	*/
		if ( (id=Next_ID++) == MAX_SHARE_MEM_NUM){
			break;

			}
		if (ShareMemTable[id] == NULL){
			UnLock();
			return(id);
			}
	}
	if(ShareMemFreeList){
		id=ShareMemFreeList->id;
		#if ENABLE_MEM
	    		FreeBuff(KERNAL.ShareMem_pool,TaskFreeList);
		#endif
		ShareMemFreeList=ShareMemFreeList->next;
		UnLock();
		return(id);
	}
	UnLock();
	return(ERR_NO_SHARE_MEM_SPACE);

}
#if ENABLE_MEM
SIGNED  CreateShareMemGroup ()
#else
SIGNED CreateShareMemGroup (SHARE_MEM_MCB *share_mem_ptr,INT32U mem_size,void *start_address )
#endif
{
   	SIGNED share_mem_id;
   	SIGNED err;
     	#if ENABLE_MEM
	   	SHARE_MEM_MCB *share_mem_ptr;
     	#endif	   
     	share_mem_id=_NewShareMemId();
	if(share_mem_id<0)
	      	return (share_mem_id);
    	#if ENABLE_MEM
		SHARE_MEM_MCB *share_mem_ptr;
		err=AllocBuff(KERNAL.ShareMem_pool,&(void *)share_mem_ptr,-1);
		if(err!=OK)
	    		return (ERR_NO_MEMORY);
     	#else
       		if(!share_mem_ptr) return  ERR_INVALID_GROUP;
      		else  if(ShareMemTable[share_mem_ptr->id]==share_mem_ptr) return (share_mem_ptr->id);
    	#endif
     	#if DEBUG
	   	DebugLog(CreateShareMemGroup,share_mem_ptr->ShareMem_name);//在日志中记录操作,时间等信息
     	#endif
	ShareMemTable[share_mem_id]=share_mem_ptr;
 	share_mem_ptr->id=share_mem_id;
	share_mem_ptr->mem_size=mem_size;
	share_mem_ptr->start_address=start_address;
	share_mem_ptr->lock=0;
	share_mem_ptr->task_wait_header=NULL;
        return(share_mem_id);

}
/*
*********************************************************************************************************
*                                      Del A ShareMem

*********************************************************************************************************
*/
STATUS DelShareMemGroup(SIGNED share_mem_id)
{

     	STATUS state,oldstate;
     	SHARE_MEM_MCB *share_mem_ptr;

    	if (share_mem_id<0 || share_mem_id >MAX_SHARE_MEM_NUM) {                                 /* Not allowed to Del idle task     */
		return (ERR_INVALID_SHARE_MEM);
        }
    	share_mem_ptr=ShareMemTable[share_mem_id];
 
     	#if DEBUG
         	DebugLog(Del_SHARE_MEM,share_mem_ptr->ID);//在日志中记录操作,时间等信息
     	#endif
    	DoProtect(share_mem_ptr);
    	if (share_mem_ptr == NULL) {                                 /* Not allowed to Del idle ShareMem     */
        	return (ERR_INVALID_GROUP);
    	}
    	while(share_mem_ptr->task_wait_header){
	  	state=_ResumeTask(share_mem_ptr->task_wait_header->task_ptr,ShareMem_SUSPEND);
	  	if(state==TRUE) oldstate =state;
	 	DelHead(&(void *)(share_mem_ptr->task_wait_header));
      	}
     	UnProtect(share_mem_ptr);
      	EnLock();
        share_mem_ptr->next=ShareMemFreeList;
        ShareMemFreeList=share_mem_ptr;
        ShareMemTable[share_mem_id]=NULL;
      	UnLock();

   	if(oldstate==TRUE) _ControlToSystem();
	return (OK);

}
/*
*********************************************************************************************************
*                                     SEND A MESSAGE TO A ShareMem

*********************************************************************************************************
*/
STATUS SendToShareMem(SIGNED share_mem_id,UNSIGNED size,INT32 suspend)
{
   	WAIT_QUEUE *linknode;
   	TASK_TCB * task_ptr;
   	INT8U status,oldstate;
   	UNSIGNED flags;
    	SHARE_MEM_MCB *share_mem_ptr;
   	flags=FALSE;
    	if (share_mem_id<0 ||share_mem_id >MAX_SHARE_MEM_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_SHARE_MEM);
        }
    	share_mem_ptr=ShareMemTable[share_mem_id];
     	#if DEBUG
           	DebugLog(SetShareMems,share_mem_ptr->ID);//在日志中记录操作,时间等信息
     	#endif
    	DoProtect(share_mem_ptr);
     	if (share_mem_ptr == NULL) {                                 /* Not allowed to Del idle ShareMem     */
        	return (ERR_INVALID_GROUP);
     	}
        if(share_mem_ptr->task_wait_header){//有任务等待信号灯释放,恢复任务
	  	linknode=share_mem_ptr->task_wait_header;
	   	do{
	       		task_ptr=linknode->task_ptr;
			if (linknode->ShareMem_operation==AND)  {
		 		if(linknode->ShareMem_requested_SHARE_MEMs==share_mem_ptr->current_SHARE_MEMs)
				flags=TRUE;
		  	}
			else if (linknode->ShareMem_operation==OR)
		  		flags=(linknode->ShareMem_requested_SHARE_MEMs) & (share_mem_ptr->current_SHARE_MEMs);

			if (flags){
		     		linknode->ShareMem_return_status=FINISHED;
		     		status=_ResumeTask(task_ptr,ShareMem_SUSPEND);
		    		if (status==TRUE) oldstate =status;

		 	}
	       		linknode=(WAIT_QUEUE *)(linknode->next);
	     	}while(linknode!=share_mem_ptr->task_wait_header);
	       	UnProtect(share_mem_ptr);
		if (oldstate==TRUE) _ControlToSystem();
       	}
       	else
	  	UnProtect(share_mem_ptr);
	return (OK);
}
/*
*********************************************************************************************************
*                                    RECEIVE A MESSAGE FROM A ShareMem

*********************************************************************************************************
*/
STATUS ReadFromShareMem(SIGNED share_mem_id, UNSIGNED size,INT32 suspend)
{
 	WAIT_QUEUE *task_suspend;	
  	TASK_TCB *task_ptr;
  	STATUS status;
   	UNSIGNED flags;
    	SHARE_MEM_MCB *share_mem_ptr;
   	#if WAIT_QUEUE_ALLOC_MODE	
    		task_suspend=WaitQueueFreeList;
      		WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
    		
   	#else
      		WAIT_QUEUE  ShareMem_wait_queue;
    		task_suspend=&ShareMem_wait_queue;
   	#endif      
    	if (share_mem_id<0 || share_mem_id >MAX_SHARE_MEM_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_SHARE_MEM);
        }
    	share_mem_ptr=ShareMemTable[share_mem_id];
   	flags=FALSE;
    	if (requested_SHARE_MEMs==NULL)
     		return (ERR_INVALID_POINTER);
        #if DEBUG
       		DebugLog(Del_TASK,share_mem_ptr->TASK_name);//在日志中记录操作,时间等信息
     	#endif
    	DoProtect(share_mem_ptr);
       	if (share_mem_ptr == NULL) 
       		return (ERR_INVALID_GROUP);
  	if(!flags){   //事件请求不能满足
      		if(suspend!=NO_SUSPEND){//任务挂起
	   		if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
	     			UnProtect(share_mem_ptr);
	       			return(ERR_INVALID_SUSPEND);
	   		}
	   		share_mem_ptr->tasks_waiting++;
	   		task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
	   		task_suspend->ShareMem_requested_SHARE_MEMs=*requested_SHARE_MEMs;
	   		task_suspend->ShareMem_operation=operation;
	    		task_suspend->ShareMem_return_status=ShareMem_SUSPEND;
	     		AddList(&(void *)(share_mem_ptr->task_wait_header),task_suspend,0);
	     		UnProtect(share_mem_ptr);
	    		_SuspendTask(KERNAL.current_thread,ShareMem_SUSPEND,ShareMemCleanup,share_mem_ptr,suspend);
                 	_ControlToSystem();
             		Enlock(); 
           		#if WAIT_QUEUE_ALLOC_MODE
 				task_suspend->queue_ptr=WaitQueueFreeList;
 				WaitQueueFreeList=task_suspend;
 			#endif
	    		if(share_mem_ptr==NULL){
	    			Unlock(); 
	      			return(ERR_GROUP_DELETED);
	      		}
	    	    	if (task_suspend->ShareMem_return_status!=FINISHED){
	      			*requested_SHARE_MEMs=share_mem_ptr->current_SHARE_MEMs;
                 		Unlock(); 
	      			return(ERR_TIMEOUT);
	     		}
	     		share_mem_ptr->tasks_waiting--;
	     		DelList(&(void *)(share_mem_ptr->task_wait_header),task_suspend);
	    		(share_mem_ptr->current_SHARE_MEMs) &= ~ (*requested_SHARE_MEMs);
	     		Unlock(); 
	     		return (OK);

		}
       		else{
	  		UnProtect(share_mem_ptr);
	  		return (ERR_NOT_PRESENT);
		}
     	}
     	else{
         	(share_mem_ptr->current_SHARE_MEMs) &= ~ (*requested_SHARE_MEMs);
	 	//   share_mem_ptr->message_present=FALSE;
      		UnProtect(share_mem_ptr);
     		return (OK);

      	}

}
/*
*********************************************************************************************************
*                                    REMOVE A suspension BLOCK FROM A ShareMem

*********************************************************************************************************
*/
static void ShareMemCleanup(void *information)
{
    	SHARE_MEM_MCB *share_mem_ptr;
   	TASK_TCB *task_ptr;
    	WAIT_QUEUE *linknode;
     	share_mem_ptr=(SHARE_MEM_MCB *)information;
      	UnProtect(share_mem_ptr);
     	EnLock();
	linknode=share_mem_ptr->task_wait_header;
	do{
	    	task_ptr=linknode->task_ptr;
	    	if (task_ptr==((TASK_TCB *)KERNAL.current_thread)){
	    		share_mem_ptr->tasks_waiting--;
	       		DelList(&(void *)(share_mem_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!=share_mem_ptr->task_wait_header);
   	UnLock();

}


/*
*********************************************************************************************************
*                              Returns information about the specified ShareMem.

*********************************************************************************************************
*/
STATUS ListShareMem(SIGNED share_mem_id, SHARE_MEM_DATA **share_mem_lst)
{
     	SHARE_MEM_MCB *share_mem_ptr;
     	UNSIGNED i;
    	if (share_mem_id+1<0 || share_mem_id >MAX_SHARE_MEM_NUM)                                  /* Not allowed to Del idle task     */
        	return (ERR_INVALID_SHARE_MEM);
        if(share_mem_id>=0){	
      		share_mem_ptr=ShareMemTable[share_mem_id];
        	DoProtect(share_mem_ptr);
        	if (share_mem_ptr == NULL)                                  /* Not allowed to Del idle task     */
              		return (ERR_INVALID_GROUP);
       		share_mem_lst->tasks_waiting=queue_ptr->tasks_waiting;
        	share_mem_lst->lock= share_mem_ptr->lock;
        	share_mem_lst->suspend_type=share_mem_ptr->suspend_type;
        	share_mem_lst->task_id=(share_mem_ptr->task_wait_header)->task_ptr->id;
        	UnProtect(share_mem_ptr);
        	return (OK);
        }
        else{
        	for(i=0;i<MAX_SHARE_MEM_NUM;i++){
        		share_mem_ptr=ShareMemTable[i];
        		DoProtect(share_mem_ptr);
        		if (share_mem_ptr){                                  /* Not allowed to Del idle task     */
              			share_mem_lst->tasks_waiting=queue_ptr->tasks_waiting;
        			share_mem_lst->lock= share_mem_ptr->lock;
        			share_mem_lst->suspend_type=share_mem_ptr->suspend_type;
        			share_mem_lst->task_id=(share_mem_ptr->task_wait_header)->task_ptr->id;
        			share_mem_lst++;
        		}
        		UnProtect(share_mem_ptr);
        	}
        	return (OK);

  	}
}

⌨️ 快捷键说明

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