目录
2.2.3、__wqueue_default_wake()函数
3.2.2、rt_workqueue_destroy()函数
3.2.3、rt_workqueue_cancel_all_work()函数
3.4.2、rt_workqueue_urgent_work()函数
3.4.3、rt_workqueue_cancel_work()函数
3.4.4、rt_workqueue_cancel_work_sync()函数
1、completion
completion称为完成信号量,是一种轻量级的线程间(IPC)同步机制。有点类似条件变量,存在先后关系。completion使用场景比较广泛,如设备驱动serial、serial_v2、can中都有使用到。
1.1、完成量控制块
struct rt_completion
{
rt_uint32_t flag; //标志
rt_list_t suspended_list; //挂起链表
};
flag表示当前完成量对象的状态。
#define RT_COMPLETED 1
#define RT_UNCOMPLETED 0
1)当 flag 值为 RT_COMPLETED 时,表征当前完成量对象已完成了某一个工作,可以继续下一个工作;
2)当 flag 值为 RT_UNCOMPLETED 时,表征当前需要等待某一个工作结束才能继续下一个工作。
1.2、completion接口
1.2.1、rt_completion_init()函数
该接口用于初始化完成量,设置 flag 为 RT_UNCOMPLETED,然后初始化完成量对象的 suspend 线程链表。
void rt_completion_init(struct rt_completion *completion)
注:完成量的创建只支持静态对象初始化,不支持动态生成对象,在调用初始化接口时,需要传递一个静态的完成量对象的指针。
1.2.2、rt_completion_wait()函数
该接口用于等待某一个动作完成,根据 timeout 不同参数,做超时退出,或者永久等待的处理。
rt_err_t rt_completion_wait(struct rt_completion *completion,
rt_int32_t timeout)
1.2.3、rt_completion_done()函数
该接口用于指示某一个动作已经完成,指示完成后,其他的线程可以获取到该完成状态,并继续运行。
void rt_completion_done(struct rt_completion *completion)
2、waitqueue
等待队列是一种基于资源状态的线程管理的机制,它可以使线程在资源不满足的情况下处于休眠状态,让出CPU资源,而资源状态满足时唤醒线程,使其继续进行业务的处理。如设备驱动serial_v2、pipe中兼容POSIX时有使用到。
等待队列用于使线程等待某一特定的事件发生而无需频繁的轮询,线程在等待期间挂起,在某件事发生时由内核自动唤醒。
2.1、等待队列控制块
struct rt_wqueue
{
rt_uint32_t flag;
rt_list_t waiting_list;
};
typedef struct rt_wqueue rt_wqueue_t;
struct rt_wqueue_node
{
rt_thread_t polling_thread; //等待队列轮询线程
rt_list_t list; //等待队列链表
rt_wqueue_func_t wakeup; //唤醒回调函数
rt_uint32_t key; //唤醒条件
};
2.2、waitqueue接口
2.2.1、rt_wqueue_add()函数
该接口向等待队列插入一个节点。
void rt_wqueue_add(rt_wqueue_t *queue, struct rt_wqueue_node *node)
2.2.2、rt_wqueue_remove()函数
该接口将从等待队列中删除一个节点。
void rt_wqueue_remove(struct rt_wqueue_node *node)
2.2.3、__wqueue_default_wake()函数
该接口是默认的唤醒函数,但实际上它不做任何事情。它总是返回0,用户应该定义自己的唤醒函数。
int __wqueue_default_wake(struct rt_wqueue_node *wait, void *key)
2.2.4、rt_wqueue_wait()函数
该接口将一个线程加入到指定的等待队列,该线程将在指定的等待队列上挂起等待或超时返回。调用此接口时,唤醒条件key为0,唤醒函数为__wqueue_default_wake()
int rt_wqueue_wait(rt_wqueue_t *queue, int condition, int msec)
注:condition是与POSIX标准接口兼容的参数(目前无意义,只需传入0)。
2.2.5、rt_wqueue_wakeup()函数
该接口将唤醒满足条件key的指定等待队列上的挂起线程。
void rt_wqueue_wakeup(rt_wqueue_t *queue, void *key)
3、workqueue
工作队列是一种转移任务执行环境的工具,例如当系统产生一个中断时,可以在中断处理函数里做一些紧急地操作,然后将另外一些不那么紧急,而且需要一定时间的任务封装成函数交给工作队列执行,此时该函数的执行环境就从中断环境变成了线程环境,这就是 Linux 里经常提及的中断处理 “下半部”。
工作队列内部有一个工作链表(worklist),链表上有多个工作项(work item)节点。工作队列内有个线程一直在轮询工作链表,每次都从工作链表中取出一个工作项,并执行其相关联的函数。当工作队列为空时,线程会被挂起。
注:工作项(work item)里最好不要有会导致线程阻塞的代码,否则会影响后续工作项的执行。
3.1、workqueue控制块
struct rt_workqueue
{
rt_list_t work_list; //工作队列链表
rt_list_t delayed_list; //延时(定时)链表
struct rt_work *work_current; //当前工作
struct rt_semaphore sem; //用于同步的信号量
rt_thread_t work_thread; //工作队列处理线程
};
struct rt_work
{
rt_list_t list; //用于将该工作项挂载到工作链表上去
void (*work_func)(struct rt_work *work, void *work_data); //工作项绑定的函数指针
void *work_data; //用户自定义数据
rt_uint16_t flags; //标志。RT_WORK_STATE_PENDING、RT_WORK_STATE_SUBMITTING
rt_uint16_t type; //当前版本暂时没用到?!
struct rt_timer timer; //定时器
struct rt_workqueue *workqueue; //工作队列指针
};
3.1.1、工作项标志
1)当工作项无延迟时,将flag与上RT_WORK_STATE_PENDING标志。
2)当工作项需要延迟时,会开启一个单次软件定时器。并将flag与上RT_WORK_STATE_SUBMITTING标志。当定时器超时时,去掉RT_WORK_STATE_SUBMITTING标志,并与上RT_WORK_STATE_PENDING标志。
3.2、workqueue接口
3.2.1、rt_workqueue_create()函数
该接口用于创建一个包含线程的工作队列(除了使用系统工作队列,也可以创建属于自己的工作队列)。
struct rt_workqueue *rt_workqueue_create(const char *name, rt_uint16_t stack_size, rt_uint8_t priority)
3.2.2、rt_workqueue_destroy()函数
该接口用于销毁指定工作队列。
rt_err_t rt_workqueue_destroy(struct rt_workqueue *queue)
3.2.3、rt_workqueue_cancel_all_work()函数
该接口用于取消指定工作队列queue中的所有工作项。
rt_err_t rt_workqueue_cancel_all_work(struct rt_workqueue *queue)
3.3、系统工作队列接口
3.3.1、rt_work_init()函数
该接口用于初始化工作项,绑定回调函数。
void rt_work_init(struct rt_work *work,
void (*work_func)(struct rt_work *work, void *work_data),
void *work_data)
3.3.2、rt_work_submit()函数
该接口用于向系统工作队列提交一个有延迟的工作项。
rt_err_t rt_work_submit(struct rt_work *work, rt_tick_t ticks)
3.3.3、rt_work_urgent()函数
该接口用于向系统工作队列提交一个紧急的工作项(将工作项插入链表头)。
rt_err_t rt_work_urgent(struct rt_work *work)
3.3.4、rt_work_cancel()函数
该接口用于取消系统工作队列中的工作项。
rt_err_t rt_work_cancel(struct rt_work *work)
3.4、指定工作队列接口
3.4.1、rt_workqueue_dowork()函数
该接口用于向指定工作队列queue提交一个无延迟的工作项。
rt_err_t rt_workqueue_dowork(struct rt_workqueue *queue, struct rt_work *work)
3.4.2、rt_workqueue_urgent_work()函数
该接口用于向指定工作队列queue提交一个紧急的工作项(将工作项插入链表头)。
rt_err_t rt_workqueue_urgent_work(struct rt_workqueue *queue, struct rt_work *work)
3.4.3、rt_workqueue_cancel_work()函数
该接口用于取消指定工作队列queue中的工作项。
static rt_err_t rt_workqueue_cancel_work(struct rt_workqueue *queue, struct rt_work *work)
3.4.4、rt_workqueue_cancel_work_sync()函数
该接口用于取消指定工作队列queue中的工作项。如果工作项正在执行,则此函数将阻塞,直到完成为止。
rt_err_t rt_workqueue_cancel_work_sync(struct rt_workqueue *queue, struct rt_work *work)