2021年7月20日【Jiawei_Z】内存乒乓缓存机制与消息分发机制的C代码实现

//****************************************************
//*内存乒乓 BUFF 机制
//*算法是,1 Buff ->write,1 Buff ->read,写满后反过来。
//*正常返回 0,出错返回-1
//****************************************************
/*ping pong Buff's ID */
typedef enum{
 BUFF_PING = 0, /*Ping ID 的 Buff*/ 
 BUFF_PONG = 1, /*Pong ID 的 Buff*/
 BUFF_PIPONUM
}EN_PINGPONG_ID;
/*ping pong use ststus */
typedef enum{
 BUFF_WRITEABLE = 0, /*Buff 可写状态*/
 BUFF_READABLE = 1 /*Buff 可读状态*/ 
}EN_USE_STATUS;
/*buff use description*/
typedef struct _T_BUFF_USE_DES{
 EN_USE_STATUS eUseStatus;/*可用状态*/
 char* pcHeadAddr;/*首地址*/
 unsigned int nBuffSize; /*Buff size*/
 unsigned int nOffset; /*当前可用偏移*/
}T_BUFF_USE_DES;
/*ping pong buff 的使用描述*/
typedef struct _T_PINGPONGBUFF_USE_DES{
 EN_PINGPONG_ID eCurUseID; /*current use ID*/
 T_BUFF_USE_DES tPingBuffUse[BUFF_PIPONUM];/*Ping Buff use status*//*Pong Buff use status*/
}T_PINGPONGBUFF_USE_DES;
/*可读消息结构*/
typedef struct _T_MSG_REC2FILE{
 //EN_PINGPONG_ID enBuffID;/*Buff ID*/
 T_BUFF_USE_DES *ptBuffUse;/*Buff USE*/
 REC_FILE_DESLIST *ptFileList; /*Rec File List*/
}T_MSG_REC2FILE;
//****************************************************
//*实现一个简单消息队列
//****************************************************
/* Time Weight Task Process Msg type */
typedef enum{
 TWT_PINGPONGBUFF_REC = 0, /*ping pong buff 记录文件消息*/ 
 TWT_MSGTYPE_NUM
}EN_TWT_MSGTYPE;
/*Twt 消息结构*/
typedef struct _T_TWTMSG{
 EN_TWT_MSGTYPE enMsgType;/*msg type*/
 void* pvMsg;/*msg entry*/
 void (*pfDestroyMsg)(void* pvMsg);/*回收消息体的方法*/
}T_TWTMSG;
#define TIMEWEIGHT_TASKQUEUE_SIZE 10
/* Helper struct to hold a queue of Msgs */
typedef struct _T_TWTMSG_QUEUE{
 T_TWTMSG *pvMsg[TIMEWEIGHT_TASKQUEUE_SIZE];
unsigned long qwrite;
 unsigned long qread;
 unsigned long overflow;
}T_TWTMSG_QUEUE;
/* Helper macros for accessing Msg queues. */
#define TWT_QUEUE_EMPTY(q) \
 (((q)->qwrite == (q)->qread) ?1:0)
#define TWT_QUEUE_FULL(q) \
 ((((((q)->qwrite + 1) % TIMEWEIGHT_TASKQUEUE_SIZE)) == (q)->qread)?1:0)
/**
* generate a Msg entity 
* 正常返回消息体的指针,异常返回 NULL
*/
T_TWTMSG* generateMsg(){
 T_TWTMSG* ptMsg = NULL;
 if(NULL == (ptMsg = malloc(sizeof(T_TWTMSG)))) return NULL;
 memset(ptMsg, 0, sizeof(T_TWTMSG));
 return ptMsg;
}
/**
* destroy a Msg
*
*/
void destroyMsg(T_TWTMSG* ptMsg){
 if (NULL != ptMsg->pfDestroyMsg)ptMsg->pfDestroyMsg(ptMsg->pvMsg);
 if (NULL != ptMsg)free(ptMsg);
}
/**
* free a Msg Queue
*
*/
void freeTWTMsgQue(T_TWTMSG_QUEUE* ptMsgQ){
 if (NULL != ptMsgQ)free(ptMsgQ);
}
/**
* Init a Msg Queue
*
*/
T_TWTMSG_QUEUE* initTWTMsgQue(){
 T_TWTMSG_QUEUE* ptMsgQ = NULL;
 if (NULL == (ptMsgQ = malloc(sizeof(T_TWTMSG_QUEUE))))goto _ErrRet;
 memset(ptMsgQ, 0, sizeof(T_TWTMSG_QUEUE));
 return ptMsgQ;
 
_ErrRet:
 printf("initTWTMsgQue Fail!\n");
 freeTWTMsgQue(ptMsgQ);
 return NULL; 
}

/**
* Pop a pvMsg packet from a Msg packet queue
*
* @param q is the packet queue from which to pop the pbuf.
*
* @return pointer to pvMsg packet if available, NULL otherswise.
*/
T_TWTMSG* TWTMsgGet(T_TWTMSG_QUEUE *q)
{
 T_TWTMSG* ptMsg;
 //*加锁
 if(TWT_QUEUE_EMPTY(q)) {
 /* Return a NULL pointer if the queue is empty. */
 ptMsg = NULL;
 }else {
 /**
 * The queue is not empty so return the next frame from it
 * and adjust the read pointer accordingly.
 *
 */
 ptMsg = q->pvMsg[q->qread];
 q->qread = ((q->qread + 1) % TIMEWEIGHT_TASKQUEUE_SIZE);
 }
 //*解锁
 return(ptMsg);
}
/**
* Push a pvMsg packet onto a pvMsg packet queue
*
* @param p is the pvMsg to push onto the packet queue.
* @param q is the packet queue.
*
* @return 0 if successful, -1 if q is full.
*/
int TWTMsgSend(T_TWTMSG *p, T_TWTMSG_QUEUE *q)
{
 int ret;
 //*加锁
 if(!TWT_QUEUE_FULL(q)){
 /**
 * The queue isn't full so we add the new frame at the current
 * write position and move the write pointer.
 *
 */
 q->pvMsg[q->qwrite] = p;
 q->qwrite = ((q->qwrite + 1) % TIMEWEIGHT_TASKQUEUE_SIZE);
 ret = 0;
 }else{
 /**
 * The stack is full so we are throwing away this value. Keep track* of the number of times this happens.
 *
 */
 q->overflow++;
 ret = -1;
 }
 //*解锁
 return(ret);
}
//****************************************************
//*消息分发机制
//*算法是,
//*正常返回 0,出错返回-1
//****************************************************
extern int RecToFileMsgProc(T_MSG_REC2FILE* ptMsg);
int DispatchMsg(T_TWTMSG *ptMsg){
 if (NULL == ptMsg)goto _ErrRet;
 /*dispatch msg*/
 switch(ptMsg->enMsgType){
 case TWT_PINGPONGBUFF_REC:
 RecToFileMsgProc((T_MSG_REC2FILE*)(ptMsg->pvMsg));/*处理消息*/
 destroyMsg(ptMsg);/*消毁消息*/
 break;
 default:
 printf("DispatchMsg Msgtype Error!\n");
 break;
}
 return 0;
 
_ErrRet:
 printf("DispatchMsg Fail!\n");
 return -1; 
}
/*buff size*/
#define PINGPONG_BUFF_BSIZE 0x20000//10*1024*1024/*10M*/
/*ping pong buff*/
//char gacPINGBUFF[PINGPONG_BUFF_BSIZE];/*Ping Buff*/
//char gacPONGBUFF[PINGPONG_BUFF_BSIZE];/*Pong Buff*/
//****************************************************
//*释放 ping pong buff
//*必然成功
//*无返回
//****************************************************
void DestroyPingPongBuff(T_PINGPONGBUFF_USE_DES* ptPingPongBuff){
 int nLoop;
 if (NULL == ptPingPongBuff)return ;
 for (nLoop=0; nLoop<BUFF_PIPONUM; nLoop++){
 if (NULL != ptPingPongBuff->tPingBuffUse[nLoop].pcHeadAddr)free(ptPingPongBuff->tPingBuffUse[nLoop].pcHeadAddr);
 }
 free(ptPingPongBuff); 
}
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JIAWEI_Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值