kwork_queue.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /****************************************************************************
  2. * sched/wqueue/kwork_queue.c
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership. The
  7. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  8. * "License"); you may not use this file except in compliance with the
  9. * License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations
  17. * under the License.
  18. *
  19. ****************************************************************************/
  20. /****************************************************************************
  21. * Included Files
  22. ****************************************************************************/
  23. #include <nuttx/config.h>
  24. #include <stdint.h>
  25. #include <queue.h>
  26. #include <assert.h>
  27. #include <errno.h>
  28. #include <nuttx/irq.h>
  29. #include <nuttx/arch.h>
  30. #include <nuttx/clock.h>
  31. #include <nuttx/wqueue.h>
  32. #include "wqueue/wqueue.h"
  33. #ifdef CONFIG_SCHED_WORKQUEUE
  34. /****************************************************************************
  35. * Private Functions
  36. ****************************************************************************/
  37. /****************************************************************************
  38. * Name: work_qqueue
  39. *
  40. * Description:
  41. * Queue work to be performed at a later time. All queued work will be
  42. * performed on the worker thread of execution (not the caller's).
  43. *
  44. * The work structure is allocated by caller, but completely managed by
  45. * the work queue logic. The caller should never modify the contents of
  46. * the work queue structure; the caller should not call work_qqueue()
  47. * again until either (1) the previous work has been performed and removed
  48. * from the queue, or (2) work_cancel() has been called to cancel the work
  49. * and remove it from the work queue.
  50. *
  51. * Input Parameters:
  52. * qid - The work queue ID (index)
  53. * work - The work structure to queue
  54. * worker - The worker callback to be invoked. The callback will invoked
  55. * on the worker thread of execution.
  56. * arg - The argument that will be passed to the workder callback when
  57. * int is invoked.
  58. * delay - Delay (in clock ticks) from the time queue until the worker
  59. * is invoked. Zero means to perform the work immediately.
  60. *
  61. * Returned Value:
  62. * None
  63. *
  64. ****************************************************************************/
  65. static void work_qqueue(FAR struct kwork_wqueue_s *wqueue,
  66. FAR struct work_s *work, worker_t worker,
  67. FAR void *arg, clock_t delay)
  68. {
  69. irqstate_t flags;
  70. DEBUGASSERT(work != NULL && worker != NULL);
  71. /* Interrupts are disabled so that this logic can be called from with
  72. * task logic or ifrom nterrupt handling logic.
  73. */
  74. flags = enter_critical_section();
  75. /* Is there already pending work? */
  76. if (work->worker != NULL)
  77. {
  78. /* Remove the entry from the work queue. It will re requeued at the
  79. * end of the work queue.
  80. */
  81. dq_rem((FAR dq_entry_t *)work, &wqueue->q);
  82. }
  83. /* Initialize the work structure. */
  84. work->worker = worker; /* Work callback. non-NULL means queued */
  85. work->arg = arg; /* Callback argument */
  86. work->delay = delay; /* Delay until work performed */
  87. /* Now, time-tag that entry and put it in the work queue */
  88. work->qtime = clock_systime_ticks(); /* Time work queued */
  89. dq_addlast((FAR dq_entry_t *)work, &wqueue->q);
  90. leave_critical_section(flags);
  91. }
  92. /****************************************************************************
  93. * Public Functions
  94. ****************************************************************************/
  95. /****************************************************************************
  96. * Name: work_queue
  97. *
  98. * Description:
  99. * Queue kernel-mode work to be performed at a later time. All queued
  100. * work will be performed on the worker thread of execution (not the
  101. * caller's).
  102. *
  103. * The work structure is allocated and must be initialized to all zero by
  104. * the caller. Otherwise, the work structure is completely managed by the
  105. * work queue logic. The caller should never modify the contents of the
  106. * work queue structure directly. If work_queue() is called before the
  107. * previous work as been performed and removed from the queue, then any
  108. * pending work will be canceled and lost.
  109. *
  110. * Input Parameters:
  111. * qid - The work queue ID (index)
  112. * work - The work structure to queue
  113. * worker - The worker callback to be invoked. The callback will invoked
  114. * on the worker thread of execution.
  115. * arg - The argument that will be passed to the workder callback when
  116. * int is invoked.
  117. * delay - Delay (in clock ticks) from the time queue until the worker
  118. * is invoked. Zero means to perform the work immediately.
  119. *
  120. * Returned Value:
  121. * Zero on success, a negated errno on failure
  122. *
  123. ****************************************************************************/
  124. int work_queue(int qid, FAR struct work_s *work, worker_t worker,
  125. FAR void *arg, clock_t delay)
  126. {
  127. /* Queue the new work */
  128. #ifdef CONFIG_SCHED_HPWORK
  129. if (qid == HPWORK)
  130. {
  131. /* Queue high priority work */
  132. work_qqueue((FAR struct kwork_wqueue_s *)&g_hpwork, work, worker,
  133. arg, delay);
  134. return work_signal(HPWORK);
  135. }
  136. else
  137. #endif
  138. #ifdef CONFIG_SCHED_LPWORK
  139. if (qid == LPWORK)
  140. {
  141. /* Queue low priority work */
  142. work_qqueue((FAR struct kwork_wqueue_s *)&g_lpwork, work, worker,
  143. arg, delay);
  144. return work_signal(LPWORK);
  145. }
  146. else
  147. #endif
  148. {
  149. return -EINVAL;
  150. }
  151. }
  152. #endif /* CONFIG_SCHED_WORKQUEUE */