Skip to content

Commit ce2ad51

Browse files
GUIDINGLIxiaoxiang781216
authored andcommitted
wqueue: expose wqueue API for customization
Signed-off-by: ligd <[email protected]>
1 parent f5095d7 commit ce2ad51

File tree

5 files changed

+290
-142
lines changed

5 files changed

+290
-142
lines changed

include/nuttx/wqueue.h

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@
232232

233233
#ifndef __ASSEMBLY__
234234

235+
/* Work queue forward declaration */
236+
237+
struct kwork_wqueue_s;
238+
235239
/* Defines the work callback */
236240

237241
typedef CODE void (*worker_t)(FAR void *arg);
@@ -247,13 +251,14 @@ struct work_s
247251
{
248252
struct
249253
{
250-
struct dq_entry_s dq; /* Implements a double linked list */
251-
clock_t qtime; /* Time work queued */
254+
struct dq_entry_s dq; /* Implements a double linked list */
255+
clock_t qtime; /* Time work queued */
252256
} s;
253-
struct wdog_s timer; /* Delay expiry timer */
257+
struct wdog_s timer; /* Delay expiry timer */
254258
} u;
255-
worker_t worker; /* Work callback */
256-
FAR void *arg; /* Callback argument */
259+
worker_t worker; /* Work callback */
260+
FAR void *arg; /* Callback argument */
261+
FAR struct kwork_wqueue_s *wq; /* Work queue */
257262
};
258263

259264
/* This is an enumeration of the various events that may be
@@ -330,7 +335,50 @@ int work_usrstart(void);
330335
#endif
331336

332337
/****************************************************************************
333-
* Name: work_queue
338+
* Name: work_queue_create
339+
*
340+
* Description:
341+
* Create a new work queue. The work queue is identified by its work
342+
* queue ID, which is used to queue works to the work queue and to
343+
* perform other operations on the work queue.
344+
* This function will create a work thread pool with nthreads threads.
345+
* The work queue ID is returned on success.
346+
*
347+
* Input Parameters:
348+
* name - Name of the new task
349+
* priority - Priority of the new task
350+
* stack_size - size (in bytes) of the stack needed
351+
* nthreads - Number of work thread should be created
352+
*
353+
* Returned Value:
354+
* The work queue handle returned on success. Otherwise, NULL
355+
*
356+
****************************************************************************/
357+
358+
FAR struct kwork_wqueue_s *work_queue_create(FAR const char *name,
359+
int priority,
360+
int stack_size, int nthreads);
361+
362+
/****************************************************************************
363+
* Name: work_queue_free
364+
*
365+
* Description:
366+
* Destroy a work queue. The work queue is identified by its work queue ID.
367+
* All worker threads will be destroyed and the work queue will be freed.
368+
* The work queue ID is invalid after this function returns.
369+
*
370+
* Input Parameters:
371+
* wqueue - The work queue handle
372+
*
373+
* Returned Value:
374+
* Zero on success, a negated errno value on failure.
375+
*
376+
****************************************************************************/
377+
378+
int work_queue_free(FAR struct kwork_wqueue_s *wqueue);
379+
380+
/****************************************************************************
381+
* Name: work_queue/work_queue_wq
334382
*
335383
* Description:
336384
* Queue work to be performed at a later time. All queued work will be
@@ -344,7 +392,8 @@ int work_usrstart(void);
344392
* pending work will be canceled and lost.
345393
*
346394
* Input Parameters:
347-
* qid - The work queue ID
395+
* qid - The work queue ID (must be HPWORK or LPWORK)
396+
* wqueue - The work queue handle
348397
* work - The work structure to queue
349398
* worker - The worker callback to be invoked. The callback will be
350399
* invoked on the worker thread of execution.
@@ -360,17 +409,21 @@ int work_usrstart(void);
360409

361410
int work_queue(int qid, FAR struct work_s *work, worker_t worker,
362411
FAR void *arg, clock_t delay);
412+
int work_queue_wq(FAR struct kwork_wqueue_s *wqueue,
413+
FAR struct work_s *work, worker_t worker,
414+
FAR void *arg, clock_t delay);
363415

364416
/****************************************************************************
365-
* Name: work_cancel
417+
* Name: work_cancel/work_cancel_wq
366418
*
367419
* Description:
368420
* Cancel previously queued work. This removes work from the work queue.
369421
* After work has been cancelled, it may be requeued by calling
370422
* work_queue() again.
371423
*
372424
* Input Parameters:
373-
* qid - The work queue ID
425+
* qid - The work queue ID (must be HPWORK or LPWORK)
426+
* wqueue - The work queue handle
374427
* work - The previously queued work structure to cancel
375428
*
376429
* Returned Value:
@@ -382,9 +435,11 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker,
382435
****************************************************************************/
383436

384437
int work_cancel(int qid, FAR struct work_s *work);
438+
int work_cancel_wq(FAR struct kwork_wqueue_s *wqueue,
439+
FAR struct work_s *work);
385440

386441
/****************************************************************************
387-
* Name: work_cancel_sync
442+
* Name: work_cancel_sync/work_cancel_sync_wq
388443
*
389444
* Description:
390445
* Blocked cancel previously queued user-mode work. This removes work
@@ -393,6 +448,7 @@ int work_cancel(int qid, FAR struct work_s *work);
393448
*
394449
* Input Parameters:
395450
* qid - The work queue ID (must be HPWORK or LPWORK)
451+
* wqueue - The work queue handle
396452
* work - The previously queued work structure to cancel
397453
*
398454
* Returned Value:
@@ -405,6 +461,8 @@ int work_cancel(int qid, FAR struct work_s *work);
405461
****************************************************************************/
406462

407463
int work_cancel_sync(int qid, FAR struct work_s *work);
464+
int work_cancel_sync_wq(FAR struct kwork_wqueue_s *wqueue,
465+
FAR struct work_s *work);
408466

409467
/****************************************************************************
410468
* Name: work_available

sched/wqueue/kwork_cancel.c

Lines changed: 30 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,9 @@
4949
* work_queue() again.
5050
*
5151
* Input Parameters:
52-
* wqueue - The work queue to use. Must be HPWORK or LPWORK
53-
* nthread - The number of threads in the work queue
54-
* > 0 unsynchronous cancel
55-
* < 0 synchronous cancel
52+
* wqueue - The work queue to use
53+
* sync - true: synchronous cancel
54+
* false: asynchronous cancel
5655
* work - The previously queued work structure to cancel
5756
*
5857
* Returned Value:
@@ -64,13 +63,16 @@
6463
*
6564
****************************************************************************/
6665

67-
static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, int nthread,
66+
static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, bool sync,
6867
FAR struct work_s *work)
6968
{
7069
irqstate_t flags;
7170
int ret = -ENOENT;
7271

73-
DEBUGASSERT(work != NULL);
72+
if (wqueue == NULL || work == NULL)
73+
{
74+
return -EINVAL;
75+
}
7476

7577
/* Cancelling the work is simply a matter of removing the work structure
7678
* from the work queue. This must be done with interrupts disabled because
@@ -96,11 +98,11 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, int nthread,
9698
work->worker = NULL;
9799
ret = OK;
98100
}
99-
else if (!up_interrupt_context() && !sched_idletask() && nthread > 0)
101+
else if (!up_interrupt_context() && !sched_idletask() && sync)
100102
{
101103
int wndx;
102104

103-
for (wndx = 0; wndx < nthread; wndx++)
105+
for (wndx = 0; wndx < wqueue->nthreads; wndx++)
104106
{
105107
if (wqueue->worker[wndx].work == work &&
106108
wqueue->worker[wndx].pid != nxsched_gettid())
@@ -121,20 +123,20 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, int nthread,
121123
****************************************************************************/
122124

123125
/****************************************************************************
124-
* Name: work_cancel
126+
* Name: work_cancel/work_cancel_wq
125127
*
126128
* Description:
127-
* Cancel previously queued user-mode work. This removes work from the
128-
* user mode work queue. After work has been cancelled, it may be
129-
* requeued by calling work_queue() again.
129+
* Cancel previously queued work. This removes work from the work queue.
130+
* After work has been cancelled, it may be requeued by calling
131+
* work_queue() again.
130132
*
131133
* Input Parameters:
132134
* qid - The work queue ID (must be HPWORK or LPWORK)
135+
* wqueue - The work queue handle
133136
* work - The previously queued work structure to cancel
134137
*
135138
* Returned Value:
136-
* Zero (OK) on success, a negated errno on failure. This error may be
137-
* reported:
139+
* Zero on success, a negated errno on failure
138140
*
139141
* -ENOENT - There is no such work queued.
140142
* -EINVAL - An invalid work queue was specified
@@ -143,33 +145,17 @@ static int work_qcancel(FAR struct kwork_wqueue_s *wqueue, int nthread,
143145

144146
int work_cancel(int qid, FAR struct work_s *work)
145147
{
146-
#ifdef CONFIG_SCHED_HPWORK
147-
if (qid == HPWORK)
148-
{
149-
/* Cancel high priority work */
150-
151-
return work_qcancel((FAR struct kwork_wqueue_s *)&g_hpwork,
152-
-1, work);
153-
}
154-
else
155-
#endif
156-
#ifdef CONFIG_SCHED_LPWORK
157-
if (qid == LPWORK)
158-
{
159-
/* Cancel low priority work */
148+
return work_qcancel(work_qid2wq(qid), false, work);
149+
}
160150

161-
return work_qcancel((FAR struct kwork_wqueue_s *)&g_lpwork,
162-
-1, work);
163-
}
164-
else
165-
#endif
166-
{
167-
return -EINVAL;
168-
}
151+
int work_cancel_wq(FAR struct kwork_wqueue_s *wqueue,
152+
FAR struct work_s *work)
153+
{
154+
return work_qcancel(wqueue, false, work);
169155
}
170156

171157
/****************************************************************************
172-
* Name: work_cancel_sync
158+
* Name: work_cancel_sync/work_cancel_sync_wq
173159
*
174160
* Description:
175161
* Blocked cancel previously queued user-mode work. This removes work
@@ -178,6 +164,7 @@ int work_cancel(int qid, FAR struct work_s *work)
178164
*
179165
* Input Parameters:
180166
* qid - The work queue ID (must be HPWORK or LPWORK)
167+
* wqueue - The work queue handle
181168
* work - The previously queued work structure to cancel
182169
*
183170
* Returned Value:
@@ -191,29 +178,13 @@ int work_cancel(int qid, FAR struct work_s *work)
191178

192179
int work_cancel_sync(int qid, FAR struct work_s *work)
193180
{
194-
#ifdef CONFIG_SCHED_HPWORK
195-
if (qid == HPWORK)
196-
{
197-
/* Cancel high priority work */
198-
199-
return work_qcancel((FAR struct kwork_wqueue_s *)&g_hpwork,
200-
CONFIG_SCHED_HPNTHREADS, work);
201-
}
202-
else
203-
#endif
204-
#ifdef CONFIG_SCHED_LPWORK
205-
if (qid == LPWORK)
206-
{
207-
/* Cancel low priority work */
181+
return work_qcancel(work_qid2wq(qid), true, work);
182+
}
208183

209-
return work_qcancel((FAR struct kwork_wqueue_s *)&g_lpwork,
210-
CONFIG_SCHED_LPNTHREADS, work);
211-
}
212-
else
213-
#endif
214-
{
215-
return -EINVAL;
216-
}
184+
int work_cancel_sync_wq(FAR struct kwork_wqueue_s *wqueue,
185+
FAR struct work_s *work)
186+
{
187+
return work_qcancel(wqueue, true, work);
217188
}
218189

219190
#endif /* CONFIG_SCHED_WORKQUEUE */

0 commit comments

Comments
 (0)