• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /**
16  * @defgroup workqueue Workqueue
17  * @ingroup linux
18  */
19 #ifndef _LINUX_WORKQUEUE_H
20 #define _LINUX_WORKQUEUE_H
21 
22 #include "los_task.h"
23 #include "los_list.h"
24 #include "linux/timer.h"
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif /* __cplusplus */
29 
30 struct lock_class_key {
31 };
32 
33 /* System default workqueue. */
34 extern struct workqueue_struct *g_pstSystemWq;
35 
36 /**
37  * @ingroup workqueue
38  * Workqueue task control block structure.
39  */
40 typedef struct LosTaskCB task_struct;
41 
42 typedef long atomic_long_t;
43 
44 struct work_struct;
45 
46 /**
47  * @ingroup workqueue
48  * Workqueue handling function.
49  */
50 typedef void (*work_func_t)(struct work_struct *);
51 
52 /**
53  * @ingroup workqueue
54  * Work structure.
55  * A work is a node in a workqueue.
56  */
57 struct work_struct {
58     struct LOS_DL_LIST entry;    /**< Pointer to a doubly linked list of a work. */
59     work_func_t func;            /**< Work handling function. */
60     UINT32 work_status;          /**< Work status. */
61 };
62 
63 /**
64  * @ingroup workqueue
65  * delayed_work structure.
66  * A delayed_work is a work that is delayed to be mounted to a workqueue.
67  */
68 struct delayed_work {
69     struct work_struct work;        /**< Work structure. */
70     struct timer_list timer;        /**< Delay control block parameter structure. */
71     struct workqueue_struct *wq;    /**< Workqueue that contains the delayed_work structure. */
72     int cpu;                        /**< Number of CPUs. Not in use temporarily. */
73 };
74 
75 typedef struct tag_cpu_workqueue_struct {
76     struct LOS_DL_LIST worklist;       /* Pointer to a work doubly linked list. */
77     struct work_struct *current_work;  /* Work that is being executed. */
78     struct workqueue_struct *wq;       /* Workqueue that contains the workqueue control structure. */
79     task_struct *thread;               /* Workqueue handling thread. */
80 } cpu_workqueue_struct;
81 
82 /**
83  * @ingroup workqueue
84  * Definition of a workqueue structure.
85  */
86 struct workqueue_struct {
87     cpu_workqueue_struct *cpu_wq;   /**< Workqueue control structure. */
88     struct LOS_DL_LIST list;        /**< Pointer to a workqueue doubly linked list. */
89     LOS_DL_LIST pendList;
90     unsigned int wq_id;             /**< Workqueue ID. */
91     int delayed_work_count;         /**< Number of delayed works in a workqueue. */
92     char *name;                     /**< Workqueue name. */
93     int singlethread;               /**< Whether to create a new working task. 0 indicates that
94                                          the default working task will be used. */
95     int wq_status;                  /**< Workqueue status. */
96     int freezeable;                 /**< Not in use temporarily. */
97     int rt;                         /**< Not in use temporarily. */
98 };
99 
100 /**
101  * @ingroup workqueue
102  * Work status enumeration.
103  */
104 enum work_status {
105     WORK_BUSY_PENDING   = 1U << 0,    /**< The status of work item is pending execution. */
106     WORK_BUSY_RUNNING   = 1U << 1,    /**< The status of work item is running. */
107     WORK_STRUCT_PENDING = 1U << 0,    /**< Work item is pending execution. */
108     WORK_STRUCT_RUNNING = 1U << 1,    /**< Work item is running. */
109 };
110 
111 /**
112  * @ingroup workqueue
113  * Initialize a work.
114  */
115 #define INIT_WORK(work, callbackFunc)  do { \
116     LOS_ListInit(&((work)->entry));         \
117     (work)->func = (callbackFunc);          \
118     (work)->work_status = 0;                \
119 } while (0)
120 
121 extern void init_delayed_work(struct delayed_work *dwork, work_func_t func);
122 
123 /**
124  * @ingroup  workqueue
125  * @brief Initialize a delayed work.
126  *
127  * @par Description:
128  * This API is used to initialize a delayed work.
129  *
130  * @attention
131  * <ul>
132  * <li>The parameter dwork and func should be valid memory, otherwise, the system may be abnormal. </li>
133  * </ul>
134  *
135  * @param  dwork   [IN] Work handle.
136  * @param  func    [IN] Executive function.
137  *
138  * @retval  None.
139  * @par Dependency:
140  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
141  * @see None.
142  */
143 #define INIT_DELAYED_WORK(work, func)   init_delayed_work(work, func)
144 
145 /**
146  * @ingroup  workqueue
147  * @brief Create a workqueue.
148  *
149  * @par Description:
150  * This API is used to create a workqueue that has a specified name.
151  *
152  * @attention
153  * <ul>
154  * <li> The passed-in workqueue name is a character string that cannot be null
155  * and is the only identifier of the workqueue, make sure it is unique. </li>
156  * </ul>
157  *
158  * @param  name  [IN] Workqueue name.
159  *
160  * @retval  NULL                   The workqueue fails to be created.
161  * @retval  workqueue_struct*      The workqueue is successfully created.
162  * @par Dependency:
163  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
164  * @see destroy_workqueue
165  */
166 extern struct workqueue_struct *create_singlethread_workqueue(char *name);
167 
168 /**
169  * @ingroup  workqueue
170  * @brief Create a workqueue.
171  *
172  * @par Description:
173  * This API is used to create a workqueue that has a specified name.
174  *
175  * @attention
176  * <ul>
177  * <li> The passed-in workqueue name is a character string that cannot be null
178  * and is the only identifier of the workqueue, make sure it is unique. </li>
179  * </ul>
180  *
181  * @param  name  [IN] Workqueue name.
182  *
183  * @retval  NULL                   The workqueue fails to be created.
184  * @retval  workqueue_struct*      The workqueue is successfully created.
185  * @par Dependency:
186  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
187  * @see destroy_workqueue
188  */
189 #define create_workqueue(name)      create_singlethread_workqueue(name)
190 
191 /**
192  * @ingroup  workqueue
193  * @brief Delete a workqueue.
194  *
195  * @par Description:
196  * This API is used to delete a workqueue that has a specified handle.
197  *
198  * @attention
199  * <ul>
200  * <li>The name of the workqueue will be null and the workqueue cannot be used again
201  * after the workqueue is deleted. </li>
202  * </ul>
203  *
204  * @param  wq  [IN] Workqueue handle.
205  *
206  * @retval  None.
207  * @par Dependency:
208  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
209  * @see create_workqueue
210  */
211 void destroy_workqueue(struct workqueue_struct *wq);
212 
213 /**
214  * @ingroup  workqueue
215  * @brief Queue a work on a workqueue.
216  *
217  * @par Description:
218  * This API is used to queue a work on a specified workqueue.
219  *
220  * @attention
221  * <ul>
222  * <li>The parameter wq and work should be valid memory, otherwise, the system may be abnormal. </li>
223  * <li>The work will be immediately queued on the workqueue. </li>
224  * </ul>
225  *
226  * @param  wq     [IN] Workqueue handle.
227  * @param  work  [IN] Work handle.
228  *
229  * @retval #TRUE      The work is successfully queued on the workqueue.
230  * @retval #FALSE     The work fails to be queued on the workqueue.
231  * @par Dependency:
232  * <ul>
233  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called.</li>
234  * <li>workqueue.h: the header file that contains the API declaration.</li>
235  * </ul>
236  * @see cancel_work_sync
237  */
238 bool queue_work(struct workqueue_struct *wq, struct work_struct *work);
239 
240 /**
241  * @ingroup  workqueue
242  * @brief Queue a work on a workqueue after delay.
243  *
244  * @par Description:
245  * This API is used to queue a work on a specified workqueue after delay.
246  *
247  * @attention
248  * <ul>
249  * <li>The parameter wq and dwork should be valid memory, otherwise, the system may be abnormal. </li>
250  * <li>The work will be queued on the workqueue in a delayed period of time. </li>
251  * <li>The work will be queued on the workqueue immediately if delayTime is 0, it as same as queue_work(). </li>
252  * </ul>
253  *
254  * @param  wq         [IN] Workqueue handle.
255  * @param  dwork      [IN] Delayed work handle.
256  * @param  delayTime  [IN] Delayed time, number of ticks to wait or 0 for immediate execution.
257  *
258  * @retval #TRUE      The work is successfully queued on the workqueue.
259  * @retval #FALSE     The work fails to be queued on the workqueue.
260  * @par Dependency:
261  * <ul>
262  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called.</li>
263  * <li>workqueue.h: the header file that contains the API declaration.</li>
264  * </ul>
265  * @see cancel_delayed_work
266  */
267 bool queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delayTime);
268 
269 /**
270  * @ingroup  workqueue
271  * @brief Put a work in a default workqueue.
272  *
273  * @par Description:
274  * This API is used to put a work in the default workqueue that is created when OS is initialized.
275  *
276  * @attention
277  * <ul>
278  * <li>The parameter work should be valid memory, otherwise, the system may be abnormal. </li>
279  * <li>The default workqueue is g_pstSystemWq. </li>
280  * </ul>
281  *
282  * @param  work        [IN] Work handle.
283  *
284  * @retval #TRUE      The work is successfully put in the workqueue.
285  * @retval #FALSE     The work fails to be put in the workqueue.
286  * @par Dependency:
287  * <ul>
288  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called.</li>
289  * <li>workqueue.h: the header file that contains the API declaration.</li>
290  * </ul>
291  * @see cancel_work_sync
292  */
293 #define schedule_work(work) queue_work(g_pstSystemWq, work)
294 
295 /**
296  * @ingroup  workqueue
297  * @brief Put a work in a default workqueue after delay.
298  *
299  * @par Description:
300  * This API is used to put a work in the default workqueue that is created
301  * when OS is initialized in a delayed period of time.
302  *
303  * @attention
304  * <ul>
305  * <li>The parameter dwork should be valid memory, otherwise, the system may be abnormal. </li>
306  * <li>The default workqueue is g_pstSystemWq. </li>
307  * <li>The dwork will be queued on the workqueue immediately if delayTime is 0. </li>
308  * </ul>
309  *
310  * @param  dwork         [IN] Delayed work handle.
311  * @param  delayTime     [IN] Delayed time, number of ticks to wait or 0 for immediate execution.
312  *
313  * @retval #TRUE      The work is successfully put in the workqueue.
314  * @retval #FALSE     The work fails to be put in the workqueue.
315  * @par Dependency:
316  * <ul>
317  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called.</li>
318  * <li>workqueue.h: the header file that contains the API declaration.</li>
319  * </ul>
320  * @see cancel_delayed_work
321  */
322 #define schedule_delayed_work(dwork, delayTime) queue_delayed_work(g_pstSystemWq, dwork, delayTime)
323 
324 /**
325  * @ingroup  workqueue
326  * @brief Query the work status.
327  *
328  * @par Description:
329  * This API is used to query the status of a work and a delayed work.
330  *
331  * @attention
332  * <ul>
333  * <li>The parameter work should be valid memory, otherwise, the system may be abnormal.</li>
334  * </ul>
335  *
336  * @param  work          [IN] Work handle.
337  *
338  * @retval #WORK_BUSY_PENDING                       The work is pending.
339  * @retval #WORK_BUSY_RUNNING                       The work is running.
340  * @retval #WORK_BUSY_PENDING | WORK_BUSY_RUNNING   The work is pending and running.
341  * @retval #FALSE                  The value of the parameter work is NULL.
342  * @par Dependency:
343  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
344  * @see None.
345  */
346 unsigned int work_busy(struct work_struct *work);
347 
348 /**
349  * @ingroup  workqueue
350  * @brief Immediately execute a delayed work.
351  *
352  * @par Description:
353  * This API is used to immediately put a delayed work in a workqueue
354  * and wait for the execution of the delayed work to end.
355  *
356  * @attention
357  * <ul>
358  * <li>flush_delayed_work() should be used after queue_delayed_work() has been called.</li>
359  * <li>The parameter dwork should be valid memory, otherwise, the system may be abnormal.</li>
360  * </ul>
361  *
362  * @param  dwork          [IN] Delayed work handle.
363  *
364  * @retval #TRUE      The operation succeeds.
365  * @retval #FALSE     The operation fails.
366  * @par Dependency
367  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
368  * @see None.
369  */
370 bool flush_delayed_work(struct delayed_work *dwork);
371 
372 /**
373  * @ingroup  workqueue
374  * @brief Cancel a delayed work.
375  *
376  * @par Description:
377  * This API is used to cancel a delayed work, which means that the work will not be executed regardless of
378  * whether the delayed time has expired.
379  *
380  * @attention
381  * <ul>
382  * <li>cancel_delayed_work() should be used after queue_delayed_work() has been called.</li>
383  * <li>The parameter dwork should be valid memory, otherwise, the system may be abnormal.</li>
384  * </ul>
385  *
386  * @param  dwork          [IN] Delayed work handle.
387  *
388  * @retval #TRUE      The delayed work is successfully canceled.
389  * @retval #FALSE     The delayed work fails to be canceled.
390  * @par Dependency:
391  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
392  * @see queue_delayed_work
393  */
394 bool cancel_delayed_work(struct delayed_work *dwork);
395 
396 /**
397  * @ingroup  workqueue
398  * @brief Cancel a delayed work and wait for it to finish.
399  *
400  * @par Description:
401  * This API is used to cancel a delayed work, which means that the work will not be executed regardless of
402  * whether the delayed time has expired.
403  *
404  * @attention
405  * <ul>
406  * <li>cancel_delayed_work_sync() should be used after queue_delayed_work() has been called.</li>
407  * <li>The parameter dwork should be valid memory, otherwise, the system may be abnormal.</li>
408  * </ul>
409  *
410  * @param  dwork          [IN] Delayed work handle.
411  *
412  * @retval #TRUE      The delayed work is successfully canceled.
413  * @retval #FALSE     The delayed work fails to be canceled.
414  * @par Dependency:
415  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
416  * @see queue_delayed_work
417  */
418 bool cancel_delayed_work_sync(struct delayed_work *dwork);
419 
420 /**
421  * @ingroup  workqueue
422  * @brief Immediately execute a work.
423  *
424  * @par Description:
425  * This API is used to immediately execute a specified work and wait for the execution to end.
426  *
427  * @attention
428  * <ul>
429  * <li>flush_work() should be used after queue_work() has been called.</li>
430  * <li>The parameter work should be valid memory, otherwise, the system may be abnormal.</li>
431  * </ul>
432  *
433  * @param  work          [IN] Work handle.
434  *
435  * @retval #TRUE      The operation succeeds.
436  * @retval #FALSE     The operation fails.
437  * @par Dependency:
438  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
439  * @see None.
440  */
441 bool flush_work(struct work_struct *work);
442 
443 /**
444  * @ingroup  workqueue
445  * @brief Cancel a work.
446  *
447  * @par Description:
448  * This API is used to cancel a work that is pending or running.
449  *
450  * @attention
451  * <ul>
452  * <li>cancel_work_sync() should be used after queue_work() has been called.</li>
453  * <li>The parameter work should be valid memory, otherwise, the system may be abnormal.</li>
454  * </ul>
455  *
456  * @param  work          [IN] Work handle.
457  *
458  * @retval #TRUE      The work is successfully canceled.
459  * @retval #FALSE     The work fails to be canceled.
460  * @par Dependency:
461  * <ul><li>workqueue.h: the header file that contain the API declaration.</li></ul>
462  * @see queue_work
463  */
464 bool cancel_work_sync(struct work_struct *work);
465 
466 #ifdef __cplusplus
467 }
468 #endif /* __cplusplus */
469 
470 #endif /* _LINUX_WORKQUEUE_H */
471