• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-
2  * Copyright (c) 2010 Isilon Systems, Inc.
3  * Copyright (c) 2010 iX Systems, Inc.
4  * Copyright (c) 2010 Panasas, Inc.
5  * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice unmodified, this list of conditions, and the following
13  *    disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $FreeBSD: releng/12.2/sys/compat/linuxkpi/common/include/linux/workqueue.h 364671 2020-08-24 12:59:55Z manu $
30  */
31 #ifndef	_LINUX_WORKQUEUE_H_
32 #define	_LINUX_WORKQUEUE_H_
33 
34 #include "pthread.h"
35 #include "los_task.h"
36 #include "semaphore.h"
37 #include "los_memory.h"
38 #include "los_event.h"
39 #include "linux/list.h"
40 #include "linux/timer.h"
41 
42 #ifdef __cplusplus
43 #if __cplusplus
44 extern "C" {
45 #endif /* __cplusplus */
46 #endif /* __cplusplus */
47 
48 
49 struct lock_class_key {
50 };
51 
52 #ifdef WORKQUEUE_SUPPORT_PRIORITY
53 /**
54  * @ingroup los_task
55  * Define a usable work priority.
56  *
57  * Highest task priority.
58  */
59 #define OS_WORK_PRIORITY_HIGHEST                    0
60 
61 /**
62  * @ingroup los_task
63  * Define a usable work priority.
64  *
65  * Lowest task priority.
66  */
67 #define OS_WORK_PRIORITY_LOWEST                     31
68 
69 
70 /**
71  * @ingroup los_task
72  * Define a usable work priority.
73  *
74  * Default task priority.
75  */
76 #define OS_WORK_PRIORITY_DEFAULT                     OS_WORK_PRIORITY_LOWEST
77 #endif
78 
79 /**
80  * @ingroup workqueue
81  * System default workqueue.
82  */
83 extern struct workqueue_struct *g_pstSystemWq;
84 
85 /**
86  * @ingroup workqueue
87  * Workqueue task control block structure.
88  */
89 typedef struct LosTaskCB task_struct;
90 
91 /**
92  * @ingroup workqueue
93  * Define atomic_long_t as a signed integer.
94  *
95  */
96 typedef long atomic_long_t;
97 
98 struct work_struct;
99 
100 /**
101  * @ingroup workqueue
102  * Workqueue handling function.
103  */
104 typedef void (*work_func_t)(struct work_struct *);
105 
106 /**
107  * @ingroup workqueue
108  * Work structure.
109  * A work is a node in a workqueue.
110  */
111 struct work_struct {
112     atomic_long_t data;        /**< Input parameter of the work handling function. */
113     struct list_head entry;    /**< Pointer to a doubly linked list of a work. */
114     work_func_t func;          /**< Work handling function. */
115     unsigned int work_status;  /**< Work status. */
116 #ifdef WORKQUEUE_SUPPORT_PRIORITY
117     unsigned int work_pri;
118 #endif
119 };
120 
121 /**
122  * @ingroup workqueue
123  * delayed_work structure.
124  * A delayed_work is a work that is delayed to be mounted to a workqueue.
125  */
126 struct delayed_work {
127     struct work_struct work;        /**< Work structure. */
128     struct timer_list timer;        /**< Delay control block parameter structure. */
129     struct workqueue_struct *wq;    /**< Workqueue that contains the delayed_work structure. */
130     int cpu;                        /**< Number of CPUs. Not in use temporarily. */
131 };
132 
133 /**
134  * @ingroup workqueue
135  * Workqueue control structure.
136  * It awakes a workqueue or makes a workqueue sleep.
137  */
138 typedef struct tag_cpu_workqueue_struct {
139     struct list_head worklist;         /**< Pointer to a work doubly linked list. */
140     struct work_struct *current_work;  /**< Work that is being executed. */
141     struct workqueue_struct *wq;       /**< Workqueue that contains the workqueue control structure. */
142     task_struct *thread;               /**< Workqueue handling thread. */
143 } cpu_workqueue_struct;
144 
145 /**
146  * @ingroup workqueue
147  * Definition of a workqueue structure.
148  */
149 struct workqueue_struct {
150     cpu_workqueue_struct *cpu_wq;   /**< Workqueue control structure. */
151     struct list_head list;          /**< Pointer to a workqueue doubly linked list. */
152     EVENT_CB_S wq_event;            /**< Event of a workqueue. */
153     unsigned int wq_id;             /**< Workqueue ID. */
154     int delayed_work_count;         /**< Number of delayed works in a workqueue. */
155     char *name;                     /**< Workqueue name. */
156     int singlethread;               /**< Whether to create a new working task. 0 indicates that
157                                          the default working task will be used. */
158     int wq_status;                  /**< Workqueue status. */
159     int freezeable;                 /**< Not in use temporarily. */
160     int rt;                         /**< Not in use temporarily. */
161 };
162 
163 /**
164  * @ingroup workqueue
165  * Work status enumeration.
166  */
167 enum work_status {
168     WORK_BUSY_PENDING   = 1U << 0,    /**< The status of work item is pending execution. */
169     WORK_BUSY_RUNNING   = 1U << 1,    /**< The status of work item is running. */
170     WORK_STRUCT_PENDING = 1U << 0,    /**< Work item is pending execution. */
171     WORK_STRUCT_RUNNING = 1U << 1,    /**< Work item is running. */
172 };
173 
174 /**
175  * @ingroup workqueue
176  * Initialize a work.
177  */
178 #ifdef WORKQUEUE_SUPPORT_PRIORITY
179 #define INIT_WORK(work, callbackFunc)  do {      \
180     INIT_LIST_HEAD(&((work)->entry));            \
181     (work)->func = (callbackFunc);               \
182     (work)->data = (atomic_long_t)(0);           \
183     (work)->work_status = 0;                     \
184     (work)->work_pri = OS_WORK_PRIORITY_DEFAULT; \
185 } while (0)
186 #else
187 #define INIT_WORK(work, callbackFunc)  do { \
188     INIT_LIST_HEAD(&((work)->entry));       \
189     (work)->func = (callbackFunc);          \
190     (work)->data = (atomic_long_t)(0);      \
191     (work)->work_status = 0;                \
192 } while (0)
193 #endif
194 
195 /**
196  * @ingroup workqueue
197  * Initialize a delayed work.
198  */
199 #define INIT_DELAYED_WORK(work, func) \
200     linux_init_delayed_work(work, func)
201 
202 #define create_singlethread_workqueue(name) \
203     linux_create_singlethread_workqueue(name)
204 
205 #define create_workqueue(name) \
206     linux_create_singlethread_workqueue(name)
207 
208 #define destroy_workqueue(wq) \
209     linux_destroy_workqueue(wq)
210 
211 #define queue_work(wq, work) \
212     linux_queue_work(wq, work)
213 
214 #define queue_delayed_work(wq, dwork, delayTime) \
215     linux_queue_delayed_work(wq, dwork, delayTime)
216 
217 #define schedule_work(work) \
218     linux_schedule_work(work)
219 
220 #define schedule_delayed_work(dwork, delayTime) \
221     linux_schedule_delayed_work(dwork, delayTime)
222 
223 #define work_busy(work) \
224     linux_work_busy(work)
225 
226 #define flush_delayed_work(dwork) \
227     linux_flush_delayed_work(dwork)
228 
229 #define cancel_delayed_work(dwork) \
230     linux_cancel_delayed_work(dwork)
231 
232 #define cancel_delayed_work_sync(dwork) \
233     linux_cancel_delayed_work_sync(dwork)
234 
235 #define flush_work(work) \
236     linux_flush_work(work)
237 
238 #define cancel_work_sync(work) \
239     linux_cancel_work_sync(work)
240 
241 /* prototypes */
242 
243 /**
244  * @ingroup  workqueue
245  * @brief Initialize a delayed work.
246  *
247  * @par Description:
248  * This API is used to initialize a delayed work.
249  *
250  * @attention
251  * <ul>
252  * <li>The parameter dwork and func shoud be valid memory, otherwise, the system may be abnormal. </li>
253  * </ul>
254  *
255  * @param  dwork   [IN] Work handle.
256  * @param  func    [IN] Executive function.
257  *
258  * @retval  None.
259  * @par Dependency:
260  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
261  * @see none.
262  */
263 extern void linux_init_delayed_work(struct delayed_work *dwork, work_func_t func);
264 
265 /**
266  * @ingroup  workqueue
267  * @brief Create a workqueue.
268  *
269  * @par Description:
270  * This API is used to create a workqueue that has a specified name.
271  *
272  * @attention
273  * <ul>
274  * <li> The passed-in workqueue name is a character string that cannot be null
275  * and is the only identifier of the workqueue, make sure it is unique. </li>
276  * </ul>
277  *
278  * @param  name  [IN] Workqueue name.
279  *
280  * @retval  NULL                   The workqueue fails to be created.
281  * @retval  workqueue_struct*      The workqueue is successfully created.
282  * @par Dependency:
283  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
284  * @see destroy_workqueue
285  */
286 extern struct workqueue_struct *linux_create_singlethread_workqueue(char *name);
287 
288 /**
289  * @ingroup  workqueue
290  * @brief Delete a workqueue.
291  *
292  * @par Description:
293  * This API is used to delete a workqueue that has a specified handle.
294  *
295  * @attention
296  * <ul>
297  * <li>The name of the workqueue will be null and the workqueue cannot be used again
298  * after the workqueue is deleted. </li>
299  * </ul>
300  *
301  * @param  wq  [IN] Workqueue handle.
302  *
303  * @retval  None.
304  * @par Dependency:
305  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
306  * @see create_workqueue
307  */
308 extern void linux_destroy_workqueue(struct workqueue_struct *wq);
309 
310 /**
311  * @ingroup  workqueue
312  * @brief Queue a work on a workqueue.
313  *
314  * @par Description:
315  * This API is used to queue a work on a specified workqueue.
316  *
317  * @attention
318  * <ul>
319  * <li>The parameter wq and work shoud be valid memory, otherwise, the system may be abnormal. </li>
320  * <li>The work will be immediately queued on the workqueue. </li>
321  * </ul>
322  *
323  * @param  wq     [IN] Workqueue handle.
324  * @param  work  [IN] Work handle.
325  *
326  * @retval #TRUE      The work is successfully queued on the workqueue.
327  * @retval #FALSE     The work fails to be queued on the workqueue.
328  * @par Dependency:
329  * <ul>
330  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called</li>
331  * <li>workqueue.h: the header file that contains the API declaration.</li>
332  * </ul>
333  * @see cancel_work_sync
334  */
335 extern bool linux_queue_work(struct workqueue_struct *wq, struct work_struct *work);
336 
337 /**
338  * @ingroup  workqueue
339  * @brief Queue a work on a workqueue after delay.
340  *
341  * @par Description:
342  * This API is used to queue a work on a specified workqueue after delay.
343  *
344  * @attention
345  * <ul>
346  * <li>The parameter wq and dwork shoud be valid memory, otherwise, the system may be abnormal. </li>
347  * <li>The work will be queued on the workqueue in a delayed period of time. </li>
348  * <li>The work will be queued on the workqueue immediately if delayTime is 0, it as same as queue_work(). </li>
349  * </ul>
350  *
351  * @param  wq         [IN] Workqueue handle.
352  * @param  dwork      [IN] Delayed work handle.
353  * @param  delayTime  [IN] Delayed time, number of ticks to wait or 0 for immediate execution.
354  *
355  * @retval #TRUE      The work is successfully queued on the workqueue.
356  * @retval #FALSE     The work fails to be queued on the workqueue.
357  * @par Dependency:
358  * <ul>
359  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called</li>
360  * <li>workqueue.h: the header file that contains the API declaration.</li>
361  * </ul>
362  * @see cancel_delayed_work
363  */
364 extern bool linux_queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned int delayTime);
365 
366 /**
367  * @ingroup  workqueue
368  * @brief Put a work in a default workqueue.
369  *
370  * @par Description:
371  * This API is used to put a work in the default workqueue that is created when Huawei LiteOS is initialized.
372  *
373  * @attention
374  * <ul>
375  * <li>The parameter work shoud be valid memory, otherwise, the system may be abnormal. </li>
376  * <li>The default workqueue is g_pstSystemWq. </li>
377  * </ul>
378  *
379  * @param  work        [IN] Work handle.
380  *
381  * @retval #TRUE      The work is successfully put in the workqueue.
382  * @retval #FALSE     The work fails to be put in the workqueue.
383  * @par Dependency:
384  * <ul>
385  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called</li>
386  * <li>workqueue.h: the header file that contains the API declaration.</li>
387  * </ul>
388  * @see cancel_work_sync
389  */
390 extern bool linux_schedule_work(struct work_struct *work);
391 
392 /**
393  * @ingroup  workqueue
394  * @brief Put a work in a default workqueue after delay.
395  *
396  * @par Description:
397  * This API is used to put a work in the default workqueue that is created
398  * when Huawei LiteOS is initialized in a delayed period of time.
399  *
400  * @attention
401  * <ul>
402  * <li>The parameter dwork shoud be valid memory, otherwise, the system may be abnormal. </li>
403  * <li>The default workqueue is g_pstSystemWq. </li>
404  * <li>The dwork will be queued on the workqueue immediately if delayTime is 0. </li>
405  * </ul>
406  *
407  * @param  dwork         [IN] Delayed work handle.
408  * @param  delayTime     [IN] Delayed time, number of ticks to wait or 0 for immediate execution.
409  *
410  * @retval #TRUE      The work is successfully put in the workqueue.
411  * @retval #FALSE     The work fails to be put in the workqueue.
412  * @par Dependency:
413  * <ul>
414  * <li>This function should be used after create_singlethread_workqueue() or create_workqueue() has been called</li>
415  * <li>workqueue.h: the header file that contains the API declaration.</li>
416  * </ul>
417  * @see cancel_delayed_work
418  */
419 extern bool linux_schedule_delayed_work(struct delayed_work *dwork, unsigned int delayTime);
420 
421 /**
422  * @ingroup  workqueue
423  * @brief Query the work status.
424  *
425  * @par Description:
426  * This API is used to query the status of a work and a delayed work.
427  *
428  * @attention
429  * <ul>
430  * <li>The parameter work shoud be valid memory, otherwise, the system may be abnormal.</li>
431  * </ul>
432  *
433  * @param  work          [IN] Work handle.
434  *
435  * @retval #WORK_BUSY_PENDING      The work is pending.
436  * @retval #WORK_BUSY_RUNNING      The work is running.
437  * @retval #FALSE                  The value of the parameter work is NULL.
438  * @par Dependency:
439  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
440  * @see None.
441  */
442 extern unsigned int linux_work_busy(struct work_struct *work);
443 
444 /**
445  * @ingroup  workqueue
446  * @brief Immediately execute a delayed work.
447  *
448  * @par Description:
449  * This API is used to immediately put a delayed work in a workqueue
450  * and wait for the execution of the delayed work to end.
451  *
452  * @attention
453  * <ul>
454  * <li>flush_delayed_work() should be used after queue_delayed_work() has been called.</li>
455  * <li>The parameter dwork shoud be valid memory, otherwise, the system may be abnormal.</li>
456  * </ul>
457  *
458  * @param  dwork          [IN] Delayed work handle.
459  *
460  * @retval #TRUE      The operation succeeds.
461  * @retval #FALSE     The operation fails.
462  * @par Dependency
463  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
464  * @see None.
465  */
466 extern bool linux_flush_delayed_work(struct delayed_work *dwork);
467 
468 /**
469  * @ingroup  workqueue
470  * @brief Cancel a delayed work.
471  *
472  * @par Description:
473  * This API is used to cancel a delayed work, which means that the work will not be executed regardless of
474  * whether the delayed time has expired.
475  *
476  * @attention
477  * <ul>
478  * <li>cancel_delayed_work() should be used after queue_delayed_work() has been called.</li>
479  * <li>The parameter dwork shoud be valid memory, otherwise, the system may be abnormal.</li>
480  * </ul>
481  *
482  * @param  dwork          [IN] Delayed work handle.
483  *
484  * @retval #TRUE      The delayed work is successfully canceled.
485  * @retval #FALSE     The delayed work fails to be canceled.
486  * @par Dependency:
487  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
488  * @see queue_delayed_work
489  */
490 extern bool linux_cancel_delayed_work(struct delayed_work *dwork);
491 /**
492  * @ingroup  workqueue
493  * @brief Cancel a delayed work and wait for it to finish.
494  *
495  * @par Description:
496  * This API is used to cancel a delayed work, which means that the work will not be executed regardless of
497  * whether the delayed time has expired.
498  *
499  * @attention
500  * <ul>
501  * <li>cancel_delayed_work_sync() should be used after queue_delayed_work() has been called.</li>
502  * <li>The parameter dwork shoud be valid memory, otherwise, the system may be abnormal.</li>
503  * </ul>
504  *
505  * @param  dwork          [IN] Delayed work handle.
506  *
507  * @retval #TRUE      The delayed work is successfully canceled.
508  * @retval #FALSE     The delayed work fails to be canceled.
509  * @par Dependency:
510  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
511  * @see queue_delayed_work
512  */
513 extern bool linux_cancel_delayed_work_sync(struct delayed_work *dwork);
514 
515 /**
516  * @ingroup  workqueue
517  * @brief Immediately execute a work.
518  *
519  * @par Description:
520  * This API is used to immediately execute a specified work and wait for the execution to end.
521  *
522  * @attention
523  * <ul>
524  * <li>flush_work() should be used after queue_work() has been called.</li>
525  * <li>The parameter work shoud be valid memory, otherwise, the system may be abnormal.</li>
526  * </ul>
527  *
528  * @param  work          [IN] Work handle.
529  *
530  * @retval #TRUE      The operation succeeds.
531  * @retval #FALSE     The operation fails.
532  * @par Dependency:
533  * <ul><li>workqueue.h: the header file that contains the API declaration.</li></ul>
534  * @see None.
535  */
536 extern bool linux_flush_work(struct work_struct *work);
537 
538 /**
539  * @ingroup  workqueue
540  * @brief Cancel a work.
541  *
542  * @par Description:
543  * This API is used to cancel a work that is pending or running.
544  *
545  * @attention
546  * <ul>
547  * <li>cancel_work_sync() should be used after queue_work() has been called.</li>
548  * <li>The parameter work shoud be valid memory, otherwise, the system may be abnormal.</li>
549  * </ul>
550  *
551  * @param  work          [IN] Work handle.
552  *
553  * @retval #TRUE      The work is successfully canceled.
554  * @retval #FALSE     The work fails to be canceled.
555  * @par Dependency:
556  * <ul><li>workqueue.h: the header file that contain the API declaration.</li></ul>
557  * @see queue_work
558  */
559 extern bool linux_cancel_work_sync(struct work_struct *work);
560 
561 #ifdef __cplusplus
562 #if __cplusplus
563 }
564 #endif /* __cplusplus */
565 #endif /* __cplusplus */
566 
567 #endif /* _LINUX_WORKQUEUE_H_ */
568