@@ -149,6 +149,21 @@ and the user-mode work queue is functionally equivalent to the high
149149priority work queue. It differs in that its implementation does not
150150depend on internal, kernel-space facilities.
151151
152+ **Custom User Work Queues **. Applications can use
153+ ``work_queue_create() `` to create additional user-mode queues with a
154+ configurable priority and worker pool. The returned handle is passed to
155+ the ``*_wq() `` interfaces and to ``work_queue_free() ``. The predefined
156+ ``USRWORK `` queue remains available through the queue-ID interfaces.
157+
158+ **Execution Context **. The user-mode implementation uses mutexes and
159+ semaphores for synchronization. Its queue, cancel, create, priority, and
160+ destroy interfaces must therefore only be called from task context and
161+ must not be called from an interrupt handler. Kernel-mode and flat-build
162+ ``work_queue() ``, ``work_queue_wq() ``, ``work_cancel() ``, and
163+ ``work_cancel_wq() `` remain safe for interrupt handlers. Creation,
164+ destruction, and synchronous cancellation are task-context operations in
165+ all build modes.
166+
152167**Configuration Options **.
153168
154169- ``CONFIG_LIBC_USRWORK ``. If CONFIG_LIBC_USRWORK is also defined
@@ -202,7 +217,7 @@ Work Queue Interfaces
202217---------------------
203218
204219.. c :function :: int work_queue (int qid, FAR struct work_s *work, worker_t worker, \
205- FAR void *arg, uint32_t delay)
220+ FAR void *arg, clock_t delay)
206221
207222 Queue work to be performed at a later time. All
208223 queued work will be performed on the worker thread of execution
@@ -230,6 +245,56 @@ Work Queue Interfaces
230245
231246 :return: Zero is returned on success; a negated errno is returned on failure.
232247
248+ .. c :function :: FAR struct kwork_wqueue_s *work_queue_create ( \
249+ FAR const char *name, int priority, FAR void *stack_addr, \
250+ int stack_size, int nthreads)
251+
252+ Create a custom work queue containing ``nthreads `` workers. All
253+ workers use the requested name, priority, and stack size. If
254+ ``stack_addr `` is ``NULL ``, each worker stack is allocated by the
255+ thread creation logic. Otherwise, ``stack_addr `` must identify storage
256+ for ``nthreads * stack_size `` bytes.
257+
258+ This interface must only be called from task context.
259+
260+ :return: A work queue handle on success; ``NULL `` on failure.
261+
262+ .. c :function :: int work_queue_free (FAR struct kwork_wqueue_s *wqueue)
263+
264+ Destroy a custom queue, discard pending work, and wait for all running
265+ callbacks and worker threads to finish. Pending work structures become
266+ available for reuse before the function returns. The predefined
267+ ``HPWORK ``, ``LPWORK ``, and ``USRWORK `` queues cannot be destroyed.
268+
269+ This interface must only be called from task context and cannot be
270+ called from one of the queue's own callbacks.
271+
272+ :return: Zero on success, ``-EINVAL `` for an invalid or predefined
273+ queue, or ``-EDEADLK `` when called by one of the queue's workers.
274+
275+ .. c :function :: int work_queue_wq (FAR struct kwork_wqueue_s *wqueue, \
276+ FAR struct work_s *work, worker_t worker, FAR void *arg, \
277+ clock_t delay)
278+
279+ Queue work on a custom queue. If the work structure is already pending
280+ on the same queue, the pending instance is replaced. A work structure
281+ must be cancelled before it is moved to another queue.
282+
283+ :return: Zero on success, ``-EINVAL `` for invalid arguments, or
284+ ``-ESHUTDOWN `` after queue destruction starts.
285+
286+ .. c :function :: int work_queue_next_wq ( \
287+ FAR struct kwork_wqueue_s *wqueue, \
288+ FAR struct work_s *work, worker_t worker, FAR void *arg, \
289+ clock_t delay)
290+
291+ Queue the next invocation relative to the work structure's previous
292+ expiration time. This avoids accumulating callback execution time in a
293+ periodic schedule. It is normally called from the work callback.
294+
295+ :return: Zero on success, ``-EINVAL `` for invalid arguments, or
296+ ``-ESHUTDOWN `` after queue destruction starts.
297+
233298.. c :function :: int work_cancel (int qid, FAR struct work_s *work)
234299
235300 Cancel previously queued work. This removes work
@@ -240,11 +305,37 @@ Work Queue Interfaces
240305 :param work: The previously queued work structure to cancel.
241306
242307 :return: Zero is returned on success; a negated ``errno `` is returned on
243- failure.
308+ failure. Cancelling work that is not queued is a successful no-op.
244309
245- - ``ENOENT ``: There is no such work queued.
246310 - ``EINVAL ``: An invalid work queue was specified.
247311
312+ .. c :function :: int work_cancel_wq (FAR struct kwork_wqueue_s *wqueue, \
313+ FAR struct work_s *work)
314+
315+ Cancel pending work on a custom queue. Cancelling work that is not
316+ queued is a successful no-op.
317+
318+ :return: Zero on success or ``-EINVAL `` for an invalid argument.
319+
320+ .. c :function :: int work_cancel_sync_wq ( \
321+ FAR struct kwork_wqueue_s *wqueue, \
322+ FAR struct work_s *work)
323+
324+ Cancel pending work and wait for callbacks already using the same work
325+ structure to finish. If called from that work's own callback, the caller
326+ is excluded from the wait to avoid self-deadlock.
327+
328+ This interface must only be called from task context.
329+
330+ :return: Zero on success or ``-EINVAL `` for an invalid argument.
331+
332+ .. c :function :: int work_queue_priority_wq ( \
333+ FAR struct kwork_wqueue_s *wqueue)
334+
335+ Return the common scheduling priority of a custom queue's worker pool.
336+
337+ :return: The worker priority on success or a negated errno on failure.
338+
248339.. c :function :: int work_signal (int qid)
249340
250341 Signal the worker thread to process the work
@@ -295,4 +386,3 @@ Work Queue Interfaces
295386
296387 :param reqprio: Previously requested minimum worker thread
297388 priority to be "unboosted".
298-
0 commit comments