• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "hdf_task_queue.h"
10 #include "hdf_log.h"
11 #include "osal_mem.h"
12 #include "securec.h"
13 
14 static int32_t HdfThreadTasker(void *data);
15 
16 #define HDF_LOG_TAG hdf_task_queue
17 
HdfCreateThread(struct HdfTaskQueue * queue)18 static int32_t HdfCreateThread(struct HdfTaskQueue *queue)
19 {
20     int32_t ret;
21 
22     ret = OsalThreadCreate(&queue->thread, (OsalThreadEntry)HdfThreadTasker, queue);
23     if (ret != HDF_SUCCESS) {
24         HDF_LOGE("HdfCreateThread: create thread fail!");
25     }
26 
27     return ret;
28 }
29 
HdfTaskQueueCreate(HdfTaskFunc func,const char * name)30 struct HdfTaskQueue *HdfTaskQueueCreate(HdfTaskFunc func, const char *name)
31 {
32     int32_t ret;
33     struct HdfTaskQueue *queue = NULL;
34 
35     queue = (struct HdfTaskQueue *)OsalMemCalloc(sizeof(*queue));
36     if (queue == NULL) {
37         HDF_LOGE("%s malloc fail", __func__);
38         return queue;
39     }
40 
41     DListHeadInit(&queue->head);
42 
43     ret = OsalMutexInit(&queue->mutex);
44     if (ret != HDF_SUCCESS) {
45         HDF_LOGE("%s OsalMutexInit fail", __func__);
46         OsalMemFree(queue);
47         return NULL;
48     }
49 
50     ret = OsalSemInit(&queue->sem, 0);
51     if (ret != HDF_SUCCESS) {
52         HDF_LOGE("%s OsalSemInit fail", __func__);
53         OsalMutexDestroy(&queue->mutex);
54         OsalMemFree(queue);
55         return NULL;
56     }
57 
58     ret = HdfCreateThread(queue);
59     if (ret != HDF_SUCCESS) {
60         HDF_LOGE("%s HdfCreateThread fail", __func__);
61         (void)OsalMutexDestroy(&queue->mutex);
62         (void)OsalSemDestroy(&queue->sem);
63         OsalMemFree(queue);
64         return NULL;
65     }
66 
67     queue->queueName = name;
68     queue->threadRunFlag = false;
69 
70     if (func != NULL) {
71         queue->queueFunc = func;
72     }
73 
74     return queue;
75 }
76 
hdfQueueStopThread(struct HdfTaskQueue * queue)77 static void hdfQueueStopThread(struct HdfTaskQueue *queue)
78 {
79     int32_t ret;
80 
81     if (queue == NULL) {
82         HDF_LOGE("%s queue ptr is null", __func__);
83         return;
84     }
85 
86     queue->threadRunFlag = false;
87 
88     ret = OsalSemPost(&queue->sem);
89     if (ret != HDF_SUCCESS) {
90         HDF_LOGE("%s OsalSemPost fail", __func__);
91     }
92 }
93 
HdfTaskQueueDestroy(struct HdfTaskQueue * queue)94 void HdfTaskQueueDestroy(struct HdfTaskQueue *queue)
95 {
96     if (queue == NULL) {
97         HDF_LOGE("%s queue ptr is null", __func__);
98         return;
99     }
100     hdfQueueStopThread(queue);
101 }
102 
hdfQueueStartThread(struct HdfTaskQueue * queue)103 static void hdfQueueStartThread(struct HdfTaskQueue *queue)
104 {
105     int32_t ret;
106     struct OsalThreadParam param;
107 
108     (void)memset_s(&param, sizeof(param), 0, sizeof(param));
109     param.name = (char *)queue->queueName;
110     param.priority = OSAL_THREAD_PRI_HIGH;
111     queue->threadRunFlag = true;
112 
113     ret = OsalThreadStart(&queue->thread, &param);
114     if (ret != HDF_SUCCESS) {
115         HDF_LOGE("%s OsalThreadStart fail", __func__);
116     }
117 }
118 
HdfTaskEnqueue(struct HdfTaskQueue * queue,struct HdfTaskType * task)119 void HdfTaskEnqueue(struct HdfTaskQueue *queue, struct HdfTaskType *task)
120 {
121     int32_t ret;
122 
123     if (queue == NULL || task == NULL) {
124         HDF_LOGE("%s ptr is null", __func__);
125         return;
126     }
127 
128     ret = OsalMutexLock(&queue->mutex);
129     if (ret != HDF_SUCCESS) {
130         HDF_LOGE("%s OsalMutexLock fail", __func__);
131         return;
132     }
133 
134     if (!queue->threadRunFlag) {
135         hdfQueueStartThread(queue);
136     }
137 
138     DListInsertTail(&task->node, &queue->head);
139 
140     ret = OsalMutexUnlock(&queue->mutex);
141     if (ret != HDF_SUCCESS) {
142         HDF_LOGE("%s OsalMutexUnlock fail", __func__);
143         return;
144     }
145 
146     ret = OsalSemPost(&queue->sem);
147     if (ret != HDF_SUCCESS) {
148         HDF_LOGE("%s OsalSemPost fail", __func__);
149     }
150 }
151 
HdfTaskDequeue(struct HdfTaskQueue * queue)152 static struct HdfTaskType *HdfTaskDequeue(struct HdfTaskQueue *queue)
153 {
154     struct HdfTaskType *task = NULL;
155 
156     if (!DListIsEmpty(&queue->head)) {
157         task = DLIST_FIRST_ENTRY(&queue->head, struct HdfTaskType, node);
158         DListRemove(&task->node);
159     }
160 
161     return task;
162 }
163 
HdfThreadTasker(void * data)164 static int32_t HdfThreadTasker(void *data)
165 {
166     int32_t ret;
167     struct HdfTaskType *task = NULL;
168     struct HdfTaskQueue *queue = (struct HdfTaskQueue *)data;
169 
170     while (queue->threadRunFlag) {
171         ret = OsalSemWait(&queue->sem, HDF_WAIT_FOREVER);
172         if (ret != HDF_SUCCESS) {
173             continue;
174         }
175         ret = OsalMutexLock(&queue->mutex);
176         if (ret != HDF_SUCCESS) {
177             HDF_LOGE("%s OsalMutexLock fail", __func__);
178             continue;
179         }
180         task = HdfTaskDequeue(queue);
181         while (task != NULL) {
182             if (task->func) {
183                 task->func(task);
184             } else if (queue->queueFunc) {
185                 queue->queueFunc(task);
186             } else {
187                 HDF_LOGE("%s no task and queue function", __func__);
188             }
189             task = HdfTaskDequeue(queue);
190         }
191         ret = OsalMutexUnlock(&queue->mutex);
192         if (ret != HDF_SUCCESS) {
193             HDF_LOGE("%s OsalMutexUnlock fail", __func__);
194         }
195     }
196 
197     (void)OsalMutexDestroy(&queue->mutex);
198     (void)OsalSemDestroy(&queue->sem);
199     OsalMemFree(queue);
200     HDF_LOGI("%s thread exit", __func__);
201 
202     return HDF_SUCCESS;
203 }
204