📄 sharemem.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 + -