当前位置: 代码迷 >> 综合 >> SylixOS 内核工作队列
  详细解决方案

SylixOS 内核工作队列

热度:81   发布时间:2024-01-10 06:44:49.0

1、概述

内核工作队列(JobQueue)位于内核文件libsylixos/SylixOS/kernel/core/_JobQueue.c中,是纯粹的针对工作队列对象的一些操作集合,供内核使用,系统工作队列和网络工作队列都是基于内核工作队列实现的。

内核工作队列本质上是基于数组型环形缓冲区实现的,同时使用了自旋锁进行过程保护和使用了信号量进行资源同步。实现过程比较简单,可以看源码直接分析。


2、相关数据结构

SylixOS内核中定义了两个用于管理工作队列的数据结构。

2.1、工作队列管理的消息

typedef struct {
    VOIDFUNCPTR         	JOBM_pfuncFunc;PVOID                 	JOBM_pvArg[LW_JOB_ARGS];
} LW_JOB_MSG;
  • JOBM_pfuncFunc:工作消息的回调函数;
  • JOBM_pvArg[LW_JOB_ARGS]:工作消息的回调函数的参数。

2.2、工作队列控制块

typedef struct {
    PLW_JOB_MSG          	JOBQ_pjobmsgQueue;UINT                  	JOBQ_uiIn;UINT                  	JOBQ_uiOut;UINT                  	JOBQ_uiCnt;UINT                  	JOBQ_uiSize;size_t                	JOBQ_stLost;LW_OBJECT_HANDLE    	JOBQ_ulSync;LW_SPINLOCK_DEFINE  	(JOBQ_slLock);
} LW_JOB_QUEUE;
  • JOBQ_pjobmsgQueue:工作队列消息;
  • JOBQ_uiIn:加入工作队列的消息数量;
  • JOBQ_uiOut:移出工作队列的消息数量;
  • JOBQ_uiCnt:当前工作队列中的消息数量;
  • JOBQ_uiSize:工作队列总大小;
  • JOBQ_stLost:工作队列丢失消息数量;
  • JOBQ_ulSync:工作队列同步等待信号;
  • JOBQ_slLock:锁定工作队列自旋锁。

3、相关接口函数

3.1 创建及删除工作队列

SylixOS中创建工作队列就是分配工作队列资源和初始化工作队列控制块中各成员的过程,与之对应,删除队列就是释放工作队列资源的过程。内核中提供了两种工作队列的创建和删除操作函数:动态/静态创建和删除工作队列。

 _JobQueueCreate原型 : PLW_JOB_QUEUE  _jobQueueCreate (UINT uiQueueSize, BOOL bNonBlock)输入 : uiQueueSize       队列大小bNonBlock         执行函数是否为非阻塞方式返回 : 工作队列控制块说明 : 创建一个工作队列(动态创建)
_JobQueueDelete原型 : VOID  _jobQueueDelete (PLW_JOB_QUEUE pjobq)输入 : pjobq         工作队列控制块返回 : NONE说明 : 删除一个工作队列(动态创建)
_JobQueueInit原型 : ULONG  _jobQueueInit (PLW_JOB_QUEUE pjobq, PLW_JOB_MSG   pjobmsg, UINT          uiQueueSize, BOOL          bNonBlock)输入 : pjobq             需要初始化的工作队列控制块pjobmsg           消息缓冲区uiQueueSize       队列大小bNonBlock         执行函数是否为非阻塞方式返回 : 工作队列控制块说明 : 初始化一个工作队列 (静态创建)
_jobQueueFinit原型 : VOID  _jobQueueFinit (PLW_JOB_QUEUE pjobq)输入 : pjobq         工作队列控制块返回 : NONE说明 : 销毁一个工作队列 (静态销毁)

3.2 清空工作队列

清空工作队列的操作就是将指定工作队列控制块中的同步等待信号量清除,同时将工作队列的入队计数、出队计数和当前工作队列中消息数全部清零。

 _jobQueueFlush原型 : VOID  _jobQueueFlush (PLW_JOB_QUEUE pjobq)输入 : pjobq         工作队列控制块返回 : NONE说明 : 清空工作队列

3.3 添加工作

向一个工作队列中添加一个工作就是将一个工作消息保存到工作队列的消息管理成员,同时将该工作需要执行的回调函数及其参数保存到消息控制块中。

_JobQueueAdd原型 : ULONG  _jobQueueAdd (PLW_JOB_QUEUE pjobq,输入 : pjobq         工作队列控制块pfunc         要执行的函数pvArg0 ~ 5    函数参数返回 : ERROR说明 : 添加一个工作到工作队列

3.4 删除工作

删除工作队列中某一工作就是遍历工作队列消息列表,根据函数名及其参数个数匹配,将该工作的回调函数置空。

_JobQueueDel原型 : VOID  _jobQueueDel (PLW_JOB_QUEUE pjobq,输入 : pjobq         工作队列控制块uiMatchArgNum 匹配参数的个数pfunc         要删除的函数pvArg0 ~ 5    函数参数返回 : NONE说明 : 从工作队列中删除一个工作 (懒惰删除)

3.5 获得丢失消息数量

当工作队列控制块中当前消息数量JOBQ_uiCnt等于工作队列总大小JOBQ_uiSize时,若此时又要向该工作队列中添加新的工作消息,则该工作消息会丢失并且丢失消息数量JOBQ_stLost将会加1,因此获取工作队列控制块的JOBQ_stLost的值即可获得当前丢失的消息数量。

_jobQueueLost原型 : ULONG  _jobQueueLost (PLW_JOB_QUEUE pjobq)输入 : pjobq         工作队列控制块返回 : NONE说明 : 获得工作队列丢失信息数量

3.6 执行工作

调用_jobQueueExec即可执行工作队列中的工作,其详细描述如下:

_jobQueueExec原型 : ULONG  _jobQueueExec (PLW_JOB_QUEUE pjobq, ULONG  ulTimeout)输入 : pjobq         工作队列控制块ulTimeout     等待超时时间返回 : 不为 ERROR_NONE 表示超时说明 : 执行工作队列中的工作

执行工作队列中的工作就是判断工作队列中是否存在工作消息,若存在,则依次执行工作消息的回调函数,直至工作队列中的消息数量减为0。执行工作的具体流程如图 3.1所示。

异步工作队列执行工作流程


4、 程序源码

/********************************************************************************************************* ** ** 中国软件开源组织 ** ** 嵌入式实时操作系统 ** ** SylixOS(TM) LW : long wing ** ** Copyright All Rights Reserved ** **--------------文件信息-------------------------------------------------------------------------------- ** ** 文 件 名: _JobQueue.c ** ** 创 建 人: Han.Hui (韩辉) ** ** 文件创建日期: 2013 年 12 月 01 日 ** ** 描 述: 这是系统异步工作队列. ** ** BUG: 2018.01.05 _jobQueueDel() 如果 pfunc 参数为 NULL 则表示任意函数. *********************************************************************************************************/
#define __SYLIXOS_KERNEL
#include "../SylixOS/kernel/include/k_kernel.h"
/*********************************************************************************************************JOB MSG COPY *********************************************************************************************************/
#define LW_JOB_MSG_COPY(t, f) \{
       \(t)->JOBM_pfuncFunc = (f)->JOBM_pfuncFunc; \(t)->JOBM_pvArg[0] = (f)->JOBM_pvArg[0]; \(t)->JOBM_pvArg[1] = (f)->JOBM_pvArg[1]; \(t)->JOBM_pvArg[2] = (f)->JOBM_pvArg[2]; \(t)->JOBM_pvArg[3] = (f)->JOBM_pvArg[3]; \(t)->JOBM_pvArg[4] = (f)->JOBM_pvArg[4]; \(t)->JOBM_pvArg[5] = (f)->JOBM_pvArg[5]; \}
/********************************************************************************************************* ** 函数名称: _JobQueueCreate ** 功能描述: 创建一个工作队列 ** 输 入 : uiQueueSize 队列大小 ** bNonBlock 执行函数是否为非阻塞方式 ** 输 出 : 工作队列控制块 ** 全局变量: ** 调用模块: *********************************************************************************************************/
PLW_JOB_QUEUE  _jobQueueCreate (UINT uiQueueSize, BOOL bNonBlock)
{
    PLW_JOB_QUEUE pjobq;pjobq = (PLW_JOB_QUEUE)__KHEAP_ALLOC((size_t)(sizeof(LW_JOB_QUEUE) + (uiQueueSize * sizeof(LW_JOB_MSG))));if (pjobq == LW_NULL) {
    _DebugHandle(__ERRORMESSAGE_LEVEL, "kernel low memory.\r\n");_ErrorHandle(ERROR_KERNEL_LOW_MEMORY);return  (LW_NULL);}pjobq->JOBQ_pjobmsgQueue = (PLW_JOB_MSG)(pjobq + 1);pjobq->JOBQ_uiIn         = 0;pjobq->JOBQ_uiOut        = 0;pjobq->JOBQ_uiCnt        = 0;pjobq->JOBQ_uiSize       = uiQueueSize;pjobq->JOBQ_ulLost       = 0;if (bNonBlock == LW_FALSE) {
    pjobq->JOBQ_ulSync = API_SemaphoreBCreate("job_sync", LW_FALSE, LW_OPTION_OBJECT_GLOBAL, LW_NULL);if (pjobq->JOBQ_ulSync == LW_OBJECT_HANDLE_INVALID) {
    __KHEAP_FREE(pjobq);return  (LW_NULL);}} else {
    pjobq->JOBQ_ulSync = LW_OBJECT_HANDLE_INVALID;}LW_SPIN_INIT(&pjobq->JOBQ_slLock);return  (pjobq);
}
/********************************************************************************************************* ** 函数名称: _JobQueueDelete ** 功能描述: 删除一个工作队列 ** 输 入 : pjobq 工作队列控制块 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/
VOID  _jobQueueDelete (PLW_JOB_QUEUE pjobq)
{
    if (pjobq->JOBQ_ulSync) {
    API_SemaphoreBDelete(&pjobq->JOBQ_ulSync);}__KHEAP_FREE(pjobq);
}
/********************************************************************************************************* ** 函数名称: _JobQueueInit ** 功能描述: 初始化一个工作队列 (静态创建) ** 输 入 : pjobq 需要初始化的工作队列控制块 ** pjobmsg 消息缓冲区 ** uiQueueSize 队列大小 ** bNonBlock 执行函数是否为非阻塞方式 ** 输 出 : 工作队列控制块 ** 全局变量: ** 调用模块: *********************************************************************************************************/
ULONG  _jobQueueInit (PLW_JOB_QUEUE pjobq, PLW_JOB_MSG  pjobmsg, UINT uiQueueSize, BOOL bNonBlock)
{
    pjobq->JOBQ_pjobmsgQueue = pjobmsg;pjobq->JOBQ_uiIn         = 0;pjobq->JOBQ_uiOut        = 0;pjobq->JOBQ_uiCnt        = 0;pjobq->JOBQ_uiSize       = uiQueueSize;pjobq->JOBQ_ulLost       = 0;if (bNonBlock == LW_FALSE) {
    pjobq->JOBQ_ulSync = API_SemaphoreBCreate("job_sync", LW_FALSE, LW_OPTION_OBJECT_GLOBAL, LW_NULL);if (pjobq->JOBQ_ulSync == LW_OBJECT_HANDLE_INVALID) {
    return  (errno);}}LW_SPIN_INIT(&pjobq->JOBQ_slLock);return  (ERROR_NONE);
}
/********************************************************************************************************* ** 函数名称: _jobQueueFinit ** 功能描述: 销毁一个工作队列 (静态销毁) ** 输 入 : pjobq 工作队列控制块 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/
VOID  _jobQueueFinit (PLW_JOB_QUEUE pjobq)
{
    if (pjobq->JOBQ_ulSync) {
    API_SemaphoreBDelete(&pjobq->JOBQ_ulSync);}
}
/********************************************************************************************************* ** 函数名称: _jobQueueFlush ** 功能描述: 清空工作队列 ** 输 入 : pjobq 工作队列控制块 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/
VOID  _jobQueueFlush (PLW_JOB_QUEUE pjobq)
{
    INTREG   iregInterLevel;if (pjobq->JOBQ_ulSync) {
    API_SemaphoreBClear(pjobq->JOBQ_ulSync);}LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);pjobq->JOBQ_uiIn  = 0;pjobq->JOBQ_uiOut = 0;pjobq->JOBQ_uiCnt = 0;LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);
}
/********************************************************************************************************* ** 函数名称: _JobQueueAdd ** 功能描述: 添加一个工作到工作队列 ** 输 入 : pjobq 工作队列控制块 ** pfunc 要执行的函数 ** pvArg0 ~ 5 函数参数 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/
ULONG  _jobQueueAdd (PLW_JOB_QUEUE pjobq,VOIDFUNCPTR   pfunc,PVOID         pvArg0,PVOID         pvArg1,PVOID         pvArg2,PVOID         pvArg3,PVOID         pvArg4,PVOID         pvArg5)
{
    INTREG           iregInterLevel;PLW_JOB_MSG      pjobmsg;LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);if (pjobq->JOBQ_uiCnt == pjobq->JOBQ_uiSize) {
    pjobq->JOBQ_ulLost++;LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);_DebugHandle(__ERRORMESSAGE_LEVEL, "job message lost.\r\n");return  (ENOSPC);}pjobmsg                 = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiIn];pjobmsg->JOBM_pfuncFunc = pfunc;pjobmsg->JOBM_pvArg[0]  = pvArg0;pjobmsg->JOBM_pvArg[1]  = pvArg1;pjobmsg->JOBM_pvArg[2]  = pvArg2;pjobmsg->JOBM_pvArg[3]  = pvArg3;pjobmsg->JOBM_pvArg[4]  = pvArg4;pjobmsg->JOBM_pvArg[5]  = pvArg5;if (pjobq->JOBQ_uiIn == (pjobq->JOBQ_uiSize - 1)) {
    pjobq->JOBQ_uiIn =  0;} else {
    pjobq->JOBQ_uiIn++;}pjobq->JOBQ_uiCnt++;LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);if (pjobq->JOBQ_ulSync) {
    API_SemaphoreBPost(pjobq->JOBQ_ulSync);}return  (ERROR_NONE);
}
/********************************************************************************************************* ** 函数名称: _JobQueueDel ** 功能描述: 从工作队列中删除一个工作 (懒惰删除) ** 输 入 : pjobq 工作队列控制块 ** uiMatchArgNum 匹配参数的个数 ** pfunc 要删除的函数 ** pvArg0 ~ 5 函数参数 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/
VOID  _jobQueueDel (PLW_JOB_QUEUE pjobq,UINT          uiMatchArgNum,VOIDFUNCPTR   pfunc, PVOID         pvArg0,PVOID         pvArg1,PVOID         pvArg2,PVOID         pvArg3,PVOID         pvArg4,PVOID         pvArg5)
{
    INTREG          iregInterLevel;UINT            i = 0;PLW_JOB_MSG     pjobmsg;LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);pjobmsg = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiOut];for (i = 0; i < pjobq->JOBQ_uiCnt; i++) {
    switch (uiMatchArgNum) {
    case 0:if (pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc) {
    pjobmsg->JOBM_pfuncFunc =  LW_NULL;}break;case 1:if ((pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc) &&(pjobmsg->JOBM_pvArg[0]  == pvArg0)) {
    pjobmsg->JOBM_pfuncFunc  =  LW_NULL;}break;case 2:if ((pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc)  &&(pjobmsg->JOBM_pvArg[0]  == pvArg0) &&(pjobmsg->JOBM_pvArg[1]  == pvArg1)) {
    pjobmsg->JOBM_pfuncFunc  =  LW_NULL;}break;case 3:if ((pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc)  &&(pjobmsg->JOBM_pvArg[0]  == pvArg0) &&(pjobmsg->JOBM_pvArg[1]  == pvArg1) &&(pjobmsg->JOBM_pvArg[2]  == pvArg2)) {
    pjobmsg->JOBM_pfuncFunc  =  LW_NULL;}break;case 4:if ((pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc)  &&(pjobmsg->JOBM_pvArg[0]  == pvArg0) &&(pjobmsg->JOBM_pvArg[1]  == pvArg1) &&(pjobmsg->JOBM_pvArg[2]  == pvArg2) &&(pjobmsg->JOBM_pvArg[3]  == pvArg3)) {
    pjobmsg->JOBM_pfuncFunc  =  LW_NULL;}break;case 5:if ((pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc)  &&(pjobmsg->JOBM_pvArg[0]  == pvArg0) &&(pjobmsg->JOBM_pvArg[1]  == pvArg1) &&(pjobmsg->JOBM_pvArg[2]  == pvArg2) &&(pjobmsg->JOBM_pvArg[3]  == pvArg3) &&(pjobmsg->JOBM_pvArg[4]  == pvArg4)) {
    pjobmsg->JOBM_pfuncFunc  =  LW_NULL;}break;case 6:if ((pjobmsg->JOBM_pfuncFunc == pfunc || !pfunc)  &&(pjobmsg->JOBM_pvArg[0]  == pvArg0) &&(pjobmsg->JOBM_pvArg[1]  == pvArg1) &&(pjobmsg->JOBM_pvArg[2]  == pvArg2) &&(pjobmsg->JOBM_pvArg[3]  == pvArg3) &&(pjobmsg->JOBM_pvArg[4]  == pvArg4) &&(pjobmsg->JOBM_pvArg[5]  == pvArg5)) {
    pjobmsg->JOBM_pfuncFunc  =  LW_NULL;}break;}pjobmsg++;if (pjobmsg > &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiSize - 1]) {
    pjobmsg = &pjobq->JOBQ_pjobmsgQueue[0];}}LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);
}
/********************************************************************************************************* ** 函数名称: _jobQueueLost ** 功能描述: 获得工作队列丢失信息数量 ** 输 入 : pjobq 工作队列控制块 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/
ULONG  _jobQueueLost (PLW_JOB_QUEUE pjobq)
{
    return  (pjobq->JOBQ_ulLost);
}
/********************************************************************************************************* ** 函数名称: _jobQueueExec ** 功能描述: 执行工作队列中的工作 ** 输 入 : pjobq 工作队列控制块 ** ulTimeout 等待超时时间 ** 输 出 : 不为 ERROR_NONE 表示超时 ** 全局变量: ** 调用模块: *********************************************************************************************************/
ULONG  _jobQueueExec (PLW_JOB_QUEUE pjobq, ULONG  ulTimeout)
{
    INTREG          iregInterLevel;PLW_JOB_MSG     pjobmsg;LW_JOB_MSG      jobmsgRun;if (pjobq->JOBQ_ulSync) {
    for (;;) {
    if (API_SemaphoreBPend(pjobq->JOBQ_ulSync, ulTimeout)) {
    return  (ERROR_THREAD_WAIT_TIMEOUT);}LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);if (pjobq->JOBQ_uiCnt) {
    break;}LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);}} else {
    LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);}while (pjobq->JOBQ_uiCnt) {
    pjobmsg = &pjobq->JOBQ_pjobmsgQueue[pjobq->JOBQ_uiOut];LW_JOB_MSG_COPY(&jobmsgRun, pjobmsg);if (pjobq->JOBQ_uiOut == (pjobq->JOBQ_uiSize - 1)) {
    pjobq->JOBQ_uiOut =  0;} else {
    pjobq->JOBQ_uiOut++;}pjobq->JOBQ_uiCnt--;LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);if (jobmsgRun.JOBM_pfuncFunc) {
    jobmsgRun.JOBM_pfuncFunc(jobmsgRun.JOBM_pvArg[0],jobmsgRun.JOBM_pvArg[1],jobmsgRun.JOBM_pvArg[2],jobmsgRun.JOBM_pvArg[3],jobmsgRun.JOBM_pvArg[4],jobmsgRun.JOBM_pvArg[5]);}LW_SPIN_LOCK_QUICK(&pjobq->JOBQ_slLock, &iregInterLevel);}LW_SPIN_UNLOCK_QUICK(&pjobq->JOBQ_slLock, iregInterLevel);return  (ERROR_NONE);
}
/*********************************************************************************************************END *********************************************************************************************************/