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