mirror of
https://github.com/openharmony/drivers_framework.git
synced 2026-08-27 10:51:15 -04:00
21192b9302
Signed-off-by: yanghaizhou <yanghaizhou1@huawei.com>
204 lines
4.9 KiB
C
204 lines
4.9 KiB
C
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
*
|
|
* HDF is dual licensed: you can use it either under the terms of
|
|
* the GPL, or the BSD license, at your option.
|
|
* See the LICENSE file in the root of this repository for complete details.
|
|
*/
|
|
|
|
#include "hdf_task_queue.h"
|
|
#include "hdf_log.h"
|
|
#include "osal_mem.h"
|
|
#include "securec.h"
|
|
|
|
static int32_t HdfThreadTasker(void *data);
|
|
|
|
#define HDF_LOG_TAG hdf_task_queue
|
|
|
|
static int32_t HdfCreateThread(struct HdfTaskQueue *queue)
|
|
{
|
|
int32_t ret;
|
|
|
|
ret = OsalThreadCreate(&queue->thread, (OsalThreadEntry)HdfThreadTasker, queue);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("HdfCreateThread: create thread fail!");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
struct HdfTaskQueue *HdfTaskQueueCreate(HdfTaskFunc func, const char *name)
|
|
{
|
|
int32_t ret;
|
|
struct HdfTaskQueue *queue = NULL;
|
|
|
|
queue = (struct HdfTaskQueue *)OsalMemCalloc(sizeof(*queue));
|
|
if (queue == NULL) {
|
|
HDF_LOGE("%s malloc fail", __func__);
|
|
return queue;
|
|
}
|
|
|
|
DListHeadInit(&queue->head);
|
|
|
|
ret = OsalMutexInit(&queue->mutex);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalMutexInit fail", __func__);
|
|
OsalMemFree(queue);
|
|
return NULL;
|
|
}
|
|
|
|
ret = OsalSemInit(&queue->sem, 0);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalSemInit fail", __func__);
|
|
OsalMutexDestroy(&queue->mutex);
|
|
OsalMemFree(queue);
|
|
return NULL;
|
|
}
|
|
|
|
ret = HdfCreateThread(queue);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s HdfCreateThread fail", __func__);
|
|
(void)OsalMutexDestroy(&queue->mutex);
|
|
(void)OsalSemDestroy(&queue->sem);
|
|
OsalMemFree(queue);
|
|
return NULL;
|
|
}
|
|
|
|
queue->queueName = name;
|
|
queue->threadRunFlag = false;
|
|
|
|
if (func != NULL) {
|
|
queue->queueFunc = func;
|
|
}
|
|
|
|
return queue;
|
|
}
|
|
|
|
static void hdfQueueStopThread(struct HdfTaskQueue *queue)
|
|
{
|
|
int32_t ret;
|
|
|
|
if (queue == NULL) {
|
|
HDF_LOGE("%s queue ptr is null", __func__);
|
|
return;
|
|
}
|
|
|
|
queue->threadRunFlag = false;
|
|
|
|
ret = OsalSemPost(&queue->sem);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalSemPost fail", __func__);
|
|
}
|
|
}
|
|
|
|
void HdfTaskQueueDestroy(struct HdfTaskQueue *queue)
|
|
{
|
|
if (queue == NULL) {
|
|
HDF_LOGE("%s queue ptr is null", __func__);
|
|
return;
|
|
}
|
|
hdfQueueStopThread(queue);
|
|
}
|
|
|
|
static void hdfQueueStartThread(struct HdfTaskQueue *queue)
|
|
{
|
|
int32_t ret;
|
|
struct OsalThreadParam param;
|
|
|
|
(void)memset_s(¶m, sizeof(param), 0, sizeof(param));
|
|
param.name = (char *)queue->queueName;
|
|
param.priority = OSAL_THREAD_PRI_HIGH;
|
|
queue->threadRunFlag = true;
|
|
|
|
ret = OsalThreadStart(&queue->thread, ¶m);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalThreadStart fail", __func__);
|
|
}
|
|
}
|
|
|
|
void HdfTaskEnqueue(struct HdfTaskQueue *queue, struct HdfTaskType *task)
|
|
{
|
|
int32_t ret;
|
|
|
|
if (queue == NULL || task == NULL) {
|
|
HDF_LOGE("%s ptr is null", __func__);
|
|
return;
|
|
}
|
|
|
|
ret = OsalMutexLock(&queue->mutex);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalMutexLock fail", __func__);
|
|
return;
|
|
}
|
|
|
|
if (!queue->threadRunFlag) {
|
|
hdfQueueStartThread(queue);
|
|
}
|
|
|
|
DListInsertTail(&task->node, &queue->head);
|
|
|
|
ret = OsalMutexUnlock(&queue->mutex);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalMutexUnlock fail", __func__);
|
|
return;
|
|
}
|
|
|
|
ret = OsalSemPost(&queue->sem);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalSemPost fail", __func__);
|
|
}
|
|
}
|
|
|
|
static struct HdfTaskType *HdfTaskDequeue(struct HdfTaskQueue *queue)
|
|
{
|
|
struct HdfTaskType *task = NULL;
|
|
|
|
if (!DListIsEmpty(&queue->head)) {
|
|
task = DLIST_FIRST_ENTRY(&queue->head, struct HdfTaskType, node);
|
|
DListRemove(&task->node);
|
|
}
|
|
|
|
return task;
|
|
}
|
|
|
|
static int32_t HdfThreadTasker(void *data)
|
|
{
|
|
int32_t ret;
|
|
struct HdfTaskType *task = NULL;
|
|
struct HdfTaskQueue *queue = (struct HdfTaskQueue *)data;
|
|
|
|
while (queue->threadRunFlag) {
|
|
ret = OsalSemWait(&queue->sem, HDF_WAIT_FOREVER);
|
|
if (ret != HDF_SUCCESS) {
|
|
continue;
|
|
}
|
|
ret = OsalMutexLock(&queue->mutex);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalMutexLock fail", __func__);
|
|
continue;
|
|
}
|
|
task = HdfTaskDequeue(queue);
|
|
while (task != NULL) {
|
|
if (task->func) {
|
|
task->func(task);
|
|
} else if (queue->queueFunc) {
|
|
queue->queueFunc(task);
|
|
} else {
|
|
HDF_LOGE("%s no task and queue function", __func__);
|
|
}
|
|
task = HdfTaskDequeue(queue);
|
|
}
|
|
ret = OsalMutexUnlock(&queue->mutex);
|
|
if (ret != HDF_SUCCESS) {
|
|
HDF_LOGE("%s OsalMutexUnlock fail", __func__);
|
|
}
|
|
}
|
|
|
|
(void)OsalMutexDestroy(&queue->mutex);
|
|
(void)OsalSemDestroy(&queue->sem);
|
|
OsalMemFree(queue);
|
|
HDF_LOGI("%s thread exit", __func__);
|
|
|
|
return HDF_SUCCESS;
|
|
}
|