1、概述

本篇主要介绍SylixOS中异步工作队列(JobQueue)的原理及相关函数接口。

2、简介

异步工作队列是SylixOS中将工作推后执行的一种机制,该机制将推后的工作交由一个内核工作线程去执行,其特点在于它允许重新调度甚至睡眠。

3、数据结构及相关接口函数

SylixOS中关于异步工作队列的相关数据结构和接口函数定义位于内核文件"libsylixos/SylixOS/kernel/core/_JobQueue.c"中。

3.1数据结构

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

1、工作队列管理的消息

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

  • JOBM_pvArg[LW_JOB_ARGS]:工作消息的回调函数的参数。

2、工作队列控制块

#include 
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.2创建及删除工作队列

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

3.2.1动态创建及删除

1、动态创建工作队列

#include 
 PLW_JOB_QUEUE  _jobQueueCreate (UINT  uiQueueSize,  BOOL  bNonBlock);

函数_jobQueueCreate原型分析:

  • 此函数成功返回工作队列控制块,失败返回LW_NULL

  • 参数uiQueueSize是队列大小;

  • 参数bNonBlock是判断执行函数是否为非阻塞方式。

2、删除一个工作队列

#include 
 VOID  _jobQueueDelete (PLW_JOB_QUEUE  pjobq);

函数_jobQueueDelete原型分析:

  • 此函数无返回值;

  • 参数pjobq是工作队列控制块。

3.2.2静态创建及删除

1、静态创建工作队列

#include 
 ULONG  _jobQueueInit (PLW_JOB_QUEUE   pjobq,                       PLW_JOB_MSG     pjobmsg,                       UINT              uiQueueSize,                       BOOL             bNonBlock);

函数_jobQueueInit原型分析:

  • 此函数成功返回ERROR_NONE,输出工作队列控制块,失败返回错误号

  • 参数pjobq是需要初始化的工作队列控制块;

  • 参数pjobmsg是消息缓冲区;

  • 参数uiQueueSize是队列大小;

  • 参数bNonBlock是判断执行函数是否为非阻塞方式。

2、静态销毁工作队列

#include 
 VOID  _jobQueueFinit (PLW_JOB_QUEUE  pjobq);

函数_ jobQueueFinit原型分析:

  • 此函数无返回值;

  • 参数pjobq是工作队列控制块。

3.3清空工作队列

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

#include 
 VOID  _jobQueueFlush (PLW_JOB_QUEUE  pjobq);

函数_ jobQueueFlush原型分析:

  • 此函数无返回值;

  • 参数pjobq是工作队列控制块。

3.4添加工作

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

#include 
 ULONG  _jobQueueAdd (PLW_JOB_QUEUE   pjobq,                      VOIDFUNCPTR     pfunc,                      PVOID             pvArg0,                      PVOID             pvArg1,                      PVOID             pvArg2,                      PVOID             pvArg3,                      PVOID             pvArg4,                      PVOID             pvArg5);

函数_ jobQueueAdd原型分析:

  • 此函数成功返回ERROR_NONE,失败返回错误号;

  • 参数pjobq是工作队列控制块;

  • 参数pfunc是该工作消息的回调函数;

  • 参数pvArg0 ~ 5是回调函数的参数。

3.5删除工作

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

#include 
 VOID  _jobQueueDel (PLW_JOB_QUEUE   pjobq,                    UINT                uiMatchArgNum,                    VOIDFUNCPTR        pfunc,                     PVOID               pvArg0,                    PVOID               pvArg1,                    PVOID               pvArg2,                    PVOID               pvArg3,                    PVOID               pvArg4,                    PVOID               pvArg5);

函数_ jobQueueDel原型分析:

  • 此函数无返回值;

  • 参数pjobq是工作队列控制块;

  • 参数uiMatchArgNum是匹配参数的个数;

  • 参数pfunc是该工作消息的回调函数;

  • 参数pvArg0 ~ 5是回调函数的参数。

3.6获得丢失消息数量

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

#include 
 size_t  _jobQueueLost (PLW_JOB_QUEUE  pjobq);

函数_ jobQueueDel原型分析:

  • 此函数返回当前丢失消息数量;

  • 参数pjobq是工作队列控制块。

3.7执行工作

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

#include 
 ULONG  _jobQueueExec (PLW_JOB_QUEUE  pjobq, ULONG  ulTimeout);

函数_ jobQueueExec原型分析:

  • 此函数成功返回ERROR_NONE,失败返回ERROR_THREAD_WAIT_TIMEOUT;

  • 参数pjobq是工作队列控制块;

  • 参数ulTimeout是等待超时时间。

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

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