代码拉取完成,页面将自动刷新
同步操作将从 AliOS Things/rhino 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "k_api.h"
#if (RHINO_CONFIG_WORKQUEUE > 0)
static kstat_t workqueue_is_exist(kworkqueue_t *workqueue)
{
CPSR_ALLOC();
kworkqueue_t *pos;
RHINO_CRITICAL_ENTER();
for (pos = krhino_list_entry(g_workqueue_list_head.next, kworkqueue_t, workqueue_node);
&pos->workqueue_node != &g_workqueue_list_head;
pos = krhino_list_entry(pos->workqueue_node.next, kworkqueue_t, workqueue_node)) {
if (pos == workqueue) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_EXIST;
}
}
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_NOT_EXIST;
}
static void worker_task(void *arg)
{
CPSR_ALLOC();
kstat_t ret;
kwork_t *work = NULL;
kworkqueue_t *queue = (kworkqueue_t *)arg;
while (1) {
ret = krhino_sem_take(&(queue->sem), RHINO_WAIT_FOREVER);
if (ret != RHINO_SUCCESS) {
k_err_proc(ret);
}
RHINO_CRITICAL_ENTER();
/* have work to do. */
work = krhino_list_entry(queue->work_list.next, kwork_t, work_node);
klist_rm_init(&(work->work_node));
queue->work_current = work;
work->work_exit = 0;
RHINO_CRITICAL_EXIT();
/* do work */
work->handle(work->arg);
RHINO_CRITICAL_ENTER();
/* clean current work */
queue->work_current = NULL;
RHINO_CRITICAL_EXIT();
}
}
kstat_t krhino_workqueue_create(kworkqueue_t *workqueue, const name_t *name,
uint8_t pri, cpu_stack_t *stack_buf, size_t stack_size)
{
CPSR_ALLOC();
kstat_t ret;
NULL_PARA_CHK(workqueue);
NULL_PARA_CHK(name);
NULL_PARA_CHK(stack_buf);
if (pri >= RHINO_CONFIG_PRI_MAX) {
return RHINO_BEYOND_MAX_PRI;
}
if (stack_size == 0u) {
return RHINO_TASK_INV_STACK_SIZE;
}
ret = workqueue_is_exist(workqueue);
if (ret == RHINO_WORKQUEUE_EXIST) {
return RHINO_WORKQUEUE_EXIST;
}
klist_init(&(workqueue->workqueue_node));
klist_init(&(workqueue->work_list));
workqueue->work_current = NULL;
workqueue->name = name;
ret = krhino_sem_create(&(workqueue->sem), "WORKQUEUE-SEM", 0);
if (ret != RHINO_SUCCESS) {
return ret;
}
RHINO_CRITICAL_ENTER();
klist_insert(&g_workqueue_list_head, &(workqueue->workqueue_node));
RHINO_CRITICAL_EXIT();
ret = krhino_task_create(&(workqueue->worker), name, (void *)workqueue, pri,
0, stack_buf, stack_size, worker_task, 1);
if (ret != RHINO_SUCCESS) {
RHINO_CRITICAL_ENTER();
klist_rm_init(&(workqueue->workqueue_node));
RHINO_CRITICAL_EXIT();
krhino_sem_del(&(workqueue->sem));
return ret;
}
TRACE_WORKQUEUE_CREATE(krhino_cur_task_get(), workqueue);
return RHINO_SUCCESS;
}
kstat_t krhino_workqueue_del(kworkqueue_t *workqueue)
{
CPSR_ALLOC();
kstat_t ret;
NULL_PARA_CHK(workqueue);
ret = workqueue_is_exist(workqueue);
if (ret == RHINO_WORKQUEUE_NOT_EXIST) {
return RHINO_WORKQUEUE_NOT_EXIST;
}
RHINO_CRITICAL_ENTER();
if (!is_klist_empty(&(workqueue->work_list))) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_BUSY;
}
if (workqueue->work_current != NULL) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_BUSY;
}
RHINO_CRITICAL_EXIT();
ret = krhino_task_del(&(workqueue->worker));
if (ret != RHINO_SUCCESS) {
return ret;
}
ret = krhino_sem_del(&(workqueue->sem));
if (ret != RHINO_SUCCESS) {
return ret;
}
RHINO_CRITICAL_ENTER();
klist_rm_init(&(workqueue->workqueue_node));
TRACE_WORKQUEUE_DEL(g_active_task[cpu_cur_get()], workqueue);
RHINO_CRITICAL_EXIT();
return RHINO_SUCCESS;
}
static void work_timer_cb(void *timer, void *arg)
{
CPSR_ALLOC();
kstat_t ret;
kwork_t *work = ((ktimer_t *)timer)->priv;
kworkqueue_t *wq = (kworkqueue_t *)arg;
RHINO_CRITICAL_ENTER();
if (wq->work_current == work) {
RHINO_CRITICAL_EXIT();
return;
}
if (work->work_exit == 1) {
RHINO_CRITICAL_EXIT();
return;
}
/* NOTE: the work MUST be initialized firstly */
klist_rm_init(&(work->work_node));
klist_insert(&(wq->work_list), &(work->work_node));
work->wq = wq;
work->work_exit = 1;
RHINO_CRITICAL_EXIT();
ret = krhino_sem_give(&(wq->sem));
if (ret != RHINO_SUCCESS) {
return;
}
}
kstat_t krhino_work_init(kwork_t *work, work_handle_t handle, void *arg,
tick_t dly)
{
kstat_t ret;
if (work == NULL) {
return RHINO_NULL_PTR;
}
if (handle == NULL) {
return RHINO_NULL_PTR;
}
NULL_PARA_CHK(work);
NULL_PARA_CHK(handle);
memset(work, 0, sizeof(kwork_t));
klist_init(&(work->work_node));
work->handle = handle;
work->arg = arg;
work->dly = dly;
work->wq = NULL;
if (dly > 0) {
ret = krhino_timer_dyn_create((ktimer_t **)(&work->timer), "WORK-TIMER", work_timer_cb,
work->dly, 0, (void *)work, 0);
if (ret != RHINO_SUCCESS) {
return ret;
}
}
TRACE_WORK_INIT(krhino_cur_task_get(), work);
return RHINO_SUCCESS;
}
kstat_t krhino_work_run(kworkqueue_t *workqueue, kwork_t *work)
{
CPSR_ALLOC();
kstat_t ret;
NULL_PARA_CHK(workqueue);
NULL_PARA_CHK(work);
RHINO_CRITICAL_ENTER();
if (work->dly == 0) {
if (workqueue->work_current == work) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_WORK_RUNNING;
}
if (work->work_exit == 1) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_WORK_EXIST;
}
/* NOTE: the work MUST be initialized firstly */
klist_rm_init(&(work->work_node));
klist_insert(&(workqueue->work_list), &(work->work_node));
work->wq = workqueue;
work->work_exit = 1;
RHINO_CRITICAL_EXIT();
ret = krhino_sem_give(&(workqueue->sem));
if (ret != RHINO_SUCCESS) {
return ret;
}
} else {
work->timer->priv = work;
RHINO_CRITICAL_EXIT();
ret = krhino_timer_arg_change_auto(work->timer, (void *)workqueue);
if (ret != RHINO_SUCCESS) {
return ret;
}
}
return RHINO_SUCCESS;
}
kstat_t krhino_work_sched(kwork_t *work)
{
return krhino_work_run(&g_workqueue_default, work);
}
kstat_t krhino_work_cancel(kwork_t *work)
{
CPSR_ALLOC();
kworkqueue_t *wq;
NULL_PARA_CHK(work);
wq = (kworkqueue_t *)work->wq;
if (wq == NULL) {
if (work->dly > 0) {
krhino_timer_stop(work->timer);
}
return RHINO_SUCCESS;
}
RHINO_CRITICAL_ENTER();
if (wq->work_current == work) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_WORK_RUNNING;
}
if (work->work_exit == 1) {
RHINO_CRITICAL_EXIT();
return RHINO_WORKQUEUE_WORK_EXIST;
}
klist_rm_init(&(work->work_node));
work->wq = NULL;
RHINO_CRITICAL_EXIT();
return RHINO_SUCCESS;
}
void workqueue_init(void)
{
klist_init(&g_workqueue_list_head);
krhino_workqueue_create(&g_workqueue_default, "DEFAULT-WORKQUEUE",
RHINO_CONFIG_WORKQUEUE_TASK_PRIO, g_workqueue_stack,
RHINO_CONFIG_WORKQUEUE_STACK_SIZE);
}
#endif
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。