1 /*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "hdf_workqueue.h"
32 #include "linux/workqueue.h"
33 #include "hdf_log.h"
34 #include "osal_mem.h"
35
36 #define HDF_LOG_TAG hdf_workqueue
37
38 struct WorkWrapper {
39 struct delayed_work work;
40 HdfWorkFunc workFunc;
41 void *para;
42 };
43
HdfWorkQueueInit(HdfWorkQueue * queue,char * name)44 int32_t HdfWorkQueueInit(HdfWorkQueue *queue, char *name)
45 {
46 if (queue == NULL || name == NULL) {
47 HDF_LOGE("%s invalid para", __func__);
48 return HDF_ERR_INVALID_PARAM;
49 }
50
51 queue->realWorkQueue = create_singlethread_workqueue(name);
52 if (queue->realWorkQueue == NULL) {
53 HDF_LOGE("%s create queue fail", __func__);
54 return HDF_FAILURE;
55 }
56
57 return HDF_SUCCESS;
58 }
59
WorkEntry(struct work_struct * work)60 static void WorkEntry(struct work_struct *work)
61 {
62 struct WorkWrapper *wrapper = NULL;
63 if (work != NULL) {
64 wrapper = (struct WorkWrapper *)work;
65 if (wrapper->workFunc != NULL) {
66 wrapper->workFunc(wrapper->para);
67 } else {
68 HDF_LOGE("%s routine null", __func__);
69 }
70 } else {
71 HDF_LOGE("%s work null", __func__);
72 }
73 }
74
HdfWorkInit(HdfWork * work,HdfWorkFunc func,void * para)75 int32_t HdfWorkInit(HdfWork *work, HdfWorkFunc func, void *para)
76 {
77 struct work_struct *realWork = NULL;
78 struct WorkWrapper *wrapper = NULL;
79
80 if (work == NULL || func == NULL) {
81 HDF_LOGE("%s invalid para", __func__);
82 return HDF_ERR_INVALID_PARAM;
83 }
84 work->realWork = NULL;
85
86 wrapper = (struct WorkWrapper *)OsalMemCalloc(sizeof(*wrapper));
87 if (wrapper == NULL) {
88 HDF_LOGE("%s malloc fail", __func__);
89 return HDF_ERR_MALLOC_FAIL;
90 }
91 realWork = &(wrapper->work.work);
92 wrapper->workFunc = func;
93 wrapper->para = para;
94
95 INIT_WORK(realWork, WorkEntry);
96 work->realWork = wrapper;
97
98 return HDF_SUCCESS;
99 }
100
HdfDelayedWorkInit(HdfWork * work,HdfWorkFunc func,void * para)101 int32_t HdfDelayedWorkInit(HdfWork *work, HdfWorkFunc func, void *para)
102 {
103 struct delayed_work *realWork = NULL;
104 struct WorkWrapper *wrapper = NULL;
105
106 if (work == NULL || func == NULL) {
107 HDF_LOGE("%s invalid para", __func__);
108 return HDF_ERR_INVALID_PARAM;
109 }
110
111 work->realWork = NULL;
112
113 wrapper = (struct WorkWrapper *)OsalMemCalloc(sizeof(*wrapper));
114 if (wrapper == NULL) {
115 HDF_LOGE("%s malloc fail", __func__);
116 return HDF_ERR_MALLOC_FAIL;
117 }
118 realWork = &(wrapper->work);
119 wrapper->workFunc = func;
120 wrapper->para = para;
121
122 INIT_DELAYED_WORK(realWork, WorkEntry);
123 work->realWork = wrapper;
124
125 return HDF_SUCCESS;
126 }
127
HdfWorkDestroy(HdfWork * work)128 void HdfWorkDestroy(HdfWork *work)
129 {
130 if (work == NULL || work->realWork == NULL) {
131 HDF_LOGE("%s invalid para", __func__);
132 return;
133 }
134
135 OsalMemFree(work->realWork);
136 work->realWork = NULL;
137
138 return;
139 }
140
HdfDelayedWorkDestroy(HdfWork * work)141 void HdfDelayedWorkDestroy(HdfWork *work)
142 {
143 if (work == NULL || work->realWork == NULL) {
144 HDF_LOGE("%s invalid para", __func__);
145 return;
146 }
147
148 return HdfWorkDestroy(work);
149 }
150
HdfWorkQueueDestroy(HdfWorkQueue * queue)151 void HdfWorkQueueDestroy(HdfWorkQueue *queue)
152 {
153 if (queue == NULL || queue->realWorkQueue == NULL) {
154 HDF_LOGE("%s invalid para", __func__);
155 return;
156 }
157
158 destroy_workqueue(queue->realWorkQueue);
159
160 return;
161 }
162
HdfAddWork(HdfWorkQueue * queue,HdfWork * work)163 bool HdfAddWork(HdfWorkQueue *queue, HdfWork *work)
164 {
165 if (queue == NULL || queue->realWorkQueue == NULL || work == NULL || work->realWork == NULL) {
166 HDF_LOGE("%s invalid para", __func__);
167 return false;
168 }
169
170 return queue_work(queue->realWorkQueue, &((struct WorkWrapper *)work->realWork)->work.work);
171 }
172
HdfAddDelayedWork(HdfWorkQueue * queue,HdfWork * work,unsigned long ms)173 bool HdfAddDelayedWork(HdfWorkQueue *queue, HdfWork *work, unsigned long ms)
174 {
175 if (queue == NULL || queue->realWorkQueue == NULL || work == NULL || work->realWork == NULL) {
176 HDF_LOGE("%s invalid para", __func__);
177 return false;
178 }
179
180 return queue_delayed_work(queue->realWorkQueue, &((struct WorkWrapper *)work->realWork)->work, LOS_MS2Tick(ms));
181 }
182
HdfWorkBusy(HdfWork * work)183 unsigned int HdfWorkBusy(HdfWork *work)
184 {
185 if (work == NULL || work->realWork == NULL) {
186 HDF_LOGE("%s invalid para", __func__);
187 return 0;
188 }
189
190 return work_busy(&((struct WorkWrapper *)work->realWork)->work.work);
191 }
192
HdfCancelWorkSync(HdfWork * work)193 bool HdfCancelWorkSync(HdfWork *work)
194 {
195 if (work == NULL || work->realWork == NULL) {
196 HDF_LOGE("%s invalid para", __func__);
197 return false;
198 }
199
200 return cancel_work_sync(&((struct WorkWrapper *)work->realWork)->work.work);
201 }
202
HdfCancelDelayedWorkSync(HdfWork * work)203 bool HdfCancelDelayedWorkSync(HdfWork *work)
204 {
205 if (work == NULL || work->realWork == NULL) {
206 HDF_LOGE("%s invalid para", __func__);
207 return false;
208 }
209
210 return cancel_delayed_work_sync(&((struct WorkWrapper *)work->realWork)->work);
211 }
212
213