📄 queue.c
字号:
/*
miniTOS V0.1.0 1998-2005 (c) 林良水 (Lin LS)
miniTOS是一个完全开放源码的软件,您可以自由的使用和修改以及可以用在您想用的用途,但开发
人员不保证本软件的可靠性,以及对您的损失负任何责任。
本文实现miniTOS队列。
create by Lin LS ,2004.8
*/
//#define VC_dQueue
#include <stdio.h>
#include "minitosdef.h"
#include "extdefine.h"
#ifdef VC_dQueue
#include "proctbl.h"
void lock_int(void){};
void unlock_int(void){};
void switch_task(void){};
void SendOneChar(int i,char a){i=i;a=a;};
#endif
/*
begin --->ptrMsg[0]---->a message
begin[read] ---> ptrMsg[1]---->b message
...
begin[write]---> ptrMsg[size-2]-->message
end---> ptrMsg[size-1]--> message
*/
//初始化为以上结构
QUEUE * CreateQueue(QUEUE *ptrQ,void *ptrMsg[],int size)
{
lock_int();
ptrQ->ptrBegin=&ptrMsg[0];
ptrQ->end=size-1;
ptrQ->read=0;
ptrQ->write=0;
ptrQ->size=size;
ptrQ->ptrSuspendProc=NULL;
unlock_int();
return ptrQ;
}
/*******************************************************************
**Function:
判断Queue是否为full
**Input:
ptrQ --
**Output:
none
**return:
0--no full
1--full
********************************************************************/
int IsQueueFull(QUEUE *ptrQ)
{
if(ptrQ->read > 0)
{
if( (ptrQ->write)==(ptrQ->read-1) )
return 1;
}else //ptrQ->read==0
{
if(ptrQ->write==ptrQ->end)
return 1; //1---Queue Full
}
return 0; //0--queue not full
}
/*******************************************************************
**Function:
判断Queue是否为空
**Input:
ptrQ --
**Output:
none
**return:
0--no empty
1--empty
********************************************************************/
int IsQueueEmpty(QUEUE *ptrQ)
{
if(ptrQ->read==ptrQ->write)
return 1; //1--queue empty
return 0; //0-no empty
}
//这里不判断队列是否满,请先调用IsQueueFull再使用本函数,否则...
void PutMsgToQueue(QUEUE *ptrQ,void *msg)
{
ptrQ->ptrBegin[ptrQ->write]=msg; //bug???
if(ptrQ->write==ptrQ->end)
ptrQ->write=0;
else
ptrQ->write++;
}
//这里不判断队列是否为空,请先调用IsQueueEmpty
void * GetMsgFromQueue(QUEUE *ptrQ)
{
void *msg;
msg=ptrQ->ptrBegin[ptrQ->read]; //bug???
if (ptrQ->read==ptrQ->end)
ptrQ->read=0;
else
ptrQ->read++;
return msg;
}
/*
suspend--MO_SUSPEND/MO_NOSUSPEND
*/
int QueueSend(QUEUE *ptrQ,void *msg)
{
lock_int();
if( IsQueueFull(ptrQ) )
{ //full
unlock_int();
return ERR_QUEUEFULL;
}
PutMsgToQueue(ptrQ,msg);
if(ptrQ->ptrSuspendProc==NULL) //有进程挂起在该信号量吗?
{ //没有
unlock_int();
return 0; //成功送给队列
} else
{ //有,使之就绪
ready(ptrQ->ptrSuspendProc);
ptrQ->ptrSuspendProc=NULL;
sched();
return 0;
}
}
//返回指针,指向存放消息的缓冲区
void *ReceiveQueueSuspend(QUEUE *ptrQ)
{
void *msg;
lock_int();
if( !IsQueueEmpty(ptrQ) )
{ //no empty,get msg
msg=GetMsgFromQueue(ptrQ);
unlock_int();
return msg; //bug???这里允许进程调度,别的进程有可能改变msg内容吗?
//
}
lb_ContinueWait:
ptrCurrProc->status|=0x01; //set status bit mean blocking for waiting
ptrQ->ptrSuspendProc=ptrCurrProc; //目前只支持一个任务挂在该队列
ptrCurrProc->ptrNextProc=NULL; //挂在最后
unready(ptrCurrProc);
sched(); //等待接收
lock_int();
ptrCurrProc->status&=0xFE;
ptrQ->ptrSuspendProc=NULL; //目前只支持一个任务挂在该队列
if( !IsQueueEmpty(ptrQ) ) //再判断一次,队列是否为空,防止错误
{ //no empty,get msg
msg=GetMsgFromQueue(ptrQ);
unlock_int();
return msg; //bug???这里允许进程调度,别的进程有可能改变msg内容吗?
//
}else
goto lb_ContinueWait;
}
#ifdef VC_dQueue
//队列使用例子 VC6.0
void main()
{
//队列使用的结构定义开始
QUEUE que;
void *ptrMsg[5];
char buf1[100]="11112225555234234";
char buf2[100]="abcdef";
//队列使用的结构定义结束
char *test;
CreateQueue(&que,ptrMsg,5);
QueueSend(&que,buf1);
QueueSend(&que,buf2);
test=ReceiveQueueSuspend(&que) ;
printf("%s\n",test);
test=ReceiveQueueSuspend(&que) ;
printf("%s\n",test);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -