PebbleOS v4.45.0-223-gf3212a729
Loading...
Searching...
No Matches
Work queues

Run functions on a kernel thread, deferred from interrupts or other threads. More...

Data Structures

struct  pbl_work
 Work item. More...
 
struct  pbl_delayed_work
 Work item submitted after a delay. More...
 
struct  pbl_wallclock_work
 Work item submitted at wall clock boundaries. More...
 
struct  pbl_workq_ops
 Optional hooks run on a queue's thread. More...
 
struct  pbl_workq
 Work queue. More...
 
struct  pbl_work_pool
 Slots for pbl_work_call(). More...
 

Macros

#define PBL_WORK_INITIALIZER(_fn)   {.fn = (_fn)}
 Static initializer for a work item.
 
#define PBL_WORK_DEFINE(name, fn)   struct pbl_work name = PBL_WORK_INITIALIZER(fn)
 Define a work item, usable without pbl_work_init().
 
#define PBL_DELAYED_WORK_INITIALIZER(_fn)
 Static initializer for a delayed work item.
 
#define PBL_DELAYED_WORK_DEFINE(name, fn)    struct pbl_delayed_work name = PBL_DELAYED_WORK_INITIALIZER(fn)
 Define a delayed work item, usable without pbl_delayed_work_init().
 
#define PBL_WORKQ_INITIALIZER   {.wake = PBL_SEM_INITIALIZER(0, 1)}
 Static initializer for a work queue.
 
#define PBL_WORKQ_DEFINE(name)   struct pbl_workq name = PBL_WORKQ_INITIALIZER
 Define a work queue, usable without pbl_workq_init().
 
#define PBL_WORK_POOL_DEFINE(name, n)
 Define a pool for pbl_work_call(), usable without pbl_work_pool_init().
 

Typedefs

typedef void(* pbl_work_fn_t) (struct pbl_work *work)
 Work function, run on the queue's thread.
 
typedef void(* pbl_work_call_fn_t) (void *data)
 Function run by pbl_work_call().
 

Functions

void pbl_workq_init (struct pbl_workq *q)
 Initialize a work queue in dynamically allocated memory.
 
void pbl_workq_set_ops (struct pbl_workq *q, const struct pbl_workq_ops *ops)
 Set the hooks of a queue, which take effect once it is next idle.
 
void pbl_workq_thread (void *arg)
 Thread entry serving a queue, with the queue as its argument.
 
void pbl_workq_flush (struct pbl_workq *q)
 Wait until everything submitted so far has run.
 
struct pbl_thread * pbl_workq_get_thread (const struct pbl_workq *q)
 Get the thread serving a queue.
 
bool pbl_workq_is_current (const struct pbl_workq *q)
 Check whether the caller runs on a queue's thread.
 
void * pbl_workq_current_fn (const struct pbl_workq *q)
 Get the function being run, for debugging.
 
void pbl_work_init (struct pbl_work *work, pbl_work_fn_t fn)
 Initialize a work item.
 
bool pbl_work_submit (struct pbl_workq *q, struct pbl_work *work)
 Queue a work item.
 
void pbl_workq_set_boost_prio (struct pbl_workq *q, pbl_prio_t prio)
 Set the priority a queue's thread runs at while it has boosted work.
 
bool pbl_work_submit_boosted (struct pbl_workq *q, struct pbl_work *work)
 Queue a work item that raises its queue's priority until it has run.
 
bool pbl_work_cancel (struct pbl_work *work)
 Remove a work item from its queue, without waiting for it if it is running.
 
bool pbl_work_cancel_sync (struct pbl_work *work)
 Remove a work item from its queue and wait for it to finish running.
 
bool pbl_work_flush (struct pbl_work *work)
 Wait for a work item to finish its last submission.
 
bool pbl_work_is_pending (const struct pbl_work *work)
 Check whether a work item is queued.
 
bool pbl_work_is_running (const struct pbl_work *work)
 Check whether a work item's function is running.
 
void pbl_delayed_work_init (struct pbl_delayed_work *dwork, pbl_work_fn_t fn)
 Initialize a delayed work item.
 
bool pbl_delayed_work_schedule (struct pbl_workq *q, struct pbl_delayed_work *dwork, pbl_timeout_t delay)
 Queue a delayed work item after a delay, unless it is already pending.
 
bool pbl_delayed_work_reschedule (struct pbl_workq *q, struct pbl_delayed_work *dwork, pbl_timeout_t delay)
 Queue a delayed work item after a delay, replacing any pending delay.
 
void pbl_delayed_work_schedule_next (struct pbl_delayed_work *dwork, pbl_tick_t period)
 Queue a delayed work item one period after its last expiry, so it does not drift.
 
bool pbl_delayed_work_cancel (struct pbl_delayed_work *dwork)
 Stop a delayed work item, without waiting for it if it is running.
 
bool pbl_delayed_work_cancel_sync (struct pbl_delayed_work *dwork)
 Stop a delayed work item and wait for it to finish running.
 
bool pbl_delayed_work_is_pending (const struct pbl_delayed_work *dwork)
 Check whether a delayed work item is pending.
 
pbl_tick_t pbl_delayed_work_remaining (const struct pbl_delayed_work *dwork)
 Get the time left on a delayed work item.
 
void pbl_work_pool_init (struct pbl_work_pool *pool, struct pbl_work_call *slots, size_t num_slots)
 Initialize a pool in dynamically allocated memory.
 
size_t pbl_work_pool_num_free (const struct pbl_work_pool *pool)
 Get the free slots of a pool.
 
int pbl_work_call (struct pbl_workq *q, struct pbl_work_pool *pool, pbl_work_call_fn_t fn, void *data, pbl_timeout_t timeout)
 Run a function with a payload on a queue.
 
void pbl_wallclock_work_init (struct pbl_wallclock_work *w, pbl_work_fn_t fn)
 Initialize a wall clock work item.
 
void pbl_wallclock_work_start (struct pbl_workq *q, struct pbl_wallclock_work *w, uint32_t unit_s, uint32_t every)
 Queue a work item at every every -th boundary of the wall clock's unit_s seconds.
 
bool pbl_wallclock_work_stop (struct pbl_wallclock_work *w)
 Stop a wall clock work item, and remove it from its queue if it is pending.
 
bool pbl_wallclock_work_is_running (const struct pbl_wallclock_work *w)
 Check whether a wall clock work item is started.
 
bool pbl_sys_work_call (pbl_work_call_fn_t fn, void *data)
 Run a function with a payload on pbl_sys_workq.
 
bool pbl_sys_work_call_from_isr (pbl_work_call_fn_t fn, void *data)
 Like pbl_sys_work_call(), from an ISR: stops the system at once if no slot is free.
 
bool pbl_sys_work_try_call (pbl_work_call_fn_t fn, void *data)
 Like pbl_sys_work_call(), but never waits nor stops the system.
 
bool pbl_sys_work_call_high (pbl_work_call_fn_t fn, void *data)
 Run a short, time sensitive function with a payload on pbl_sys_workq_high.
 
void pbl_sys_work_call_high_from_isr (pbl_work_call_fn_t fn, void *data)
 Like pbl_sys_work_call_high(), from an ISR: the call is dropped if no slot is free.
 
void pbl_sys_work_block (bool block)
 Refuse new calls to pbl_sys_workq, e.g.
 
size_t pbl_sys_work_num_free (void)
 Get how many calls the caller can make to pbl_sys_workq without waiting.
 
void * pbl_sys_work_current_fn (void)
 Get the function running on pbl_sys_workq, for debugging.
 

Variables

struct pbl_workq pbl_sys_workq
 Queue for background work, which may block and take a while.
 
struct pbl_workq pbl_sys_workq_high
 Queue for short, time sensitive work, at the highest thread priority.
 

Detailed Description

Run functions on a kernel thread, deferred from interrupts or other threads.

A work item is a caller-owned struct, usually embedded in the object it acts on. Submitting allocates nothing and cannot fail: an item is queued at most once, so submitting a pending item does nothing, and its function runs once for any number of submits. Items run one at a time in submission order. An item may be resubmitted or freed by its own function.

Delayed work adds a timer in front of the queue. Payloads that cannot share one item go through pbl_work_call(), which takes its slots from a bounded pool.

The kernel provides pbl_sys_workq for background work and pbl_sys_workq_high for short, time sensitive work.

Everything may be called from an ISR except where noted.

struct foo {
struct pbl_delayed_work flush;
...
};
static void prv_flush(struct pbl_work *work) {
struct foo *foo = container_of(work, struct foo, flush.work);
...
}
pbl_delayed_work_init(&foo->flush, prv_flush);
...
pbl_delayed_work_cancel_sync(&foo->flush);
#define PBL_MSEC(ms)
Timeout in milliseconds, rounded down to whole ticks.
Definition types.h:61
struct pbl_work work
Work item, passed to the function.
Definition work.h:74
Work item.
Definition work.h:59
Work item submitted after a delay.
Definition work.h:72
bool pbl_delayed_work_reschedule(struct pbl_workq *q, struct pbl_delayed_work *dwork, pbl_timeout_t delay)
Queue a delayed work item after a delay, replacing any pending delay.
struct pbl_workq pbl_sys_workq
Queue for background work, which may block and take a while.
void pbl_delayed_work_init(struct pbl_delayed_work *dwork, pbl_work_fn_t fn)
Initialize a delayed work item.
#define container_of(ptr, type, member)
Get the structure that contains a member.
Definition misc.h:44

Data Structure Documentation

◆ pbl_work

struct pbl_work

Work item.

Data Fields
pbl_work_fn_t fn Function.

◆ pbl_delayed_work

struct pbl_delayed_work

Work item submitted after a delay.

Data Fields
struct pbl_work work Work item, passed to the function.

◆ pbl_wallclock_work

struct pbl_wallclock_work

Work item submitted at wall clock boundaries.

Data Fields
struct pbl_work work Work item, passed to the function.

◆ pbl_workq

struct pbl_workq

Work queue.

◆ pbl_work_pool

struct pbl_work_pool

Slots for pbl_work_call().

Macro Definition Documentation

◆ PBL_DELAYED_WORK_DEFINE

#define PBL_DELAYED_WORK_DEFINE (   name,
  fn 
)     struct pbl_delayed_work name = PBL_DELAYED_WORK_INITIALIZER(fn)

Define a delayed work item, usable without pbl_delayed_work_init().

Parameters
nameName of the variable.
fnFunction.

◆ PBL_DELAYED_WORK_INITIALIZER

#define PBL_DELAYED_WORK_INITIALIZER (   _fn)
Value:
{ \
.work = PBL_WORK_INITIALIZER(_fn), \
.timer = PBL_TIMER_INITIALIZER(pbl_delayed_work_expired), \
}
#define PBL_TIMER_INITIALIZER(_fn)
Static initializer for a timer.
Definition timer.h:50
#define PBL_WORK_INITIALIZER(_fn)
Static initializer for a work item.
Definition work.h:146

Static initializer for a delayed work item.

Parameters
_fnFunction.

◆ PBL_WORK_DEFINE

#define PBL_WORK_DEFINE (   name,
  fn 
)    struct pbl_work name = PBL_WORK_INITIALIZER(fn)

Define a work item, usable without pbl_work_init().

Parameters
nameName of the variable.
fnFunction.

◆ PBL_WORK_INITIALIZER

#define PBL_WORK_INITIALIZER (   _fn)    {.fn = (_fn)}

Static initializer for a work item.

Parameters
_fnFunction.

◆ PBL_WORK_POOL_DEFINE

#define PBL_WORK_POOL_DEFINE (   name,
  n 
)
Value:
struct pbl_work_pool name = { \
.slots = (struct pbl_work_call[n]){}, \
.num_slots = (n), \
.free = PBL_SEM_INITIALIZER(n, n), \
}
#define PBL_SEM_INITIALIZER(init, lim)
Static initializer for a semaphore.
Definition sem.h:54
Slots for pbl_work_call().
Definition work.h:131
int pbl_work_call(struct pbl_workq *q, struct pbl_work_pool *pool, pbl_work_call_fn_t fn, void *data, pbl_timeout_t timeout)
Run a function with a payload on a queue.

Define a pool for pbl_work_call(), usable without pbl_work_pool_init().

Parameters
nameName of the variable.
nNumber of calls that can be pending at once.

◆ PBL_WORKQ_DEFINE

#define PBL_WORKQ_DEFINE (   name)    struct pbl_workq name = PBL_WORKQ_INITIALIZER

Define a work queue, usable without pbl_workq_init().

Parameters
nameName of the variable.

◆ PBL_WORKQ_INITIALIZER

#define PBL_WORKQ_INITIALIZER   {.wake = PBL_SEM_INITIALIZER(0, 1)}

Static initializer for a work queue.

Typedef Documentation

◆ pbl_work_call_fn_t

typedef void(* pbl_work_call_fn_t) (void *data)

Function run by pbl_work_call().

◆ pbl_work_fn_t

typedef void(* pbl_work_fn_t) (struct pbl_work *work)

Work function, run on the queue's thread.

Function Documentation

◆ pbl_delayed_work_cancel()

bool pbl_delayed_work_cancel ( struct pbl_delayed_work *  dwork)

Stop a delayed work item, without waiting for it if it is running.

Parameters
dworkDelayed work item.
Returns
true if it was pending.

◆ pbl_delayed_work_cancel_sync()

bool pbl_delayed_work_cancel_sync ( struct pbl_delayed_work *  dwork)

Stop a delayed work item and wait for it to finish running.

Thread context only.

Holds against an item that schedules itself again from its function.

Parameters
dworkDelayed work item.
Returns
true if it was pending.

◆ pbl_delayed_work_init()

void pbl_delayed_work_init ( struct pbl_delayed_work *  dwork,
pbl_work_fn_t  fn 
)

Initialize a delayed work item.

Parameters
[out]dworkDelayed work item.
fnFunction.

◆ pbl_delayed_work_is_pending()

bool pbl_delayed_work_is_pending ( const struct pbl_delayed_work *  dwork)

Check whether a delayed work item is pending.

Parameters
dworkDelayed work item.
Returns
true while its delay runs or it is queued.

◆ pbl_delayed_work_remaining()

pbl_tick_t pbl_delayed_work_remaining ( const struct pbl_delayed_work *  dwork)

Get the time left on a delayed work item.

Parameters
dworkDelayed work item.
Returns
Ticks until it is queued, 0 if its delay is not running.

◆ pbl_delayed_work_reschedule()

bool pbl_delayed_work_reschedule ( struct pbl_workq *  q,
struct pbl_delayed_work *  dwork,
pbl_timeout_t  delay 
)

Queue a delayed work item after a delay, replacing any pending delay.

Parameters
qQueue.
dworkDelayed work item.
delayDelay, PBL_NO_WAIT to queue now; must not be PBL_FOREVER.
Returns
true if it was already pending.

◆ pbl_delayed_work_schedule()

bool pbl_delayed_work_schedule ( struct pbl_workq *  q,
struct pbl_delayed_work *  dwork,
pbl_timeout_t  delay 
)

Queue a delayed work item after a delay, unless it is already pending.

Parameters
qQueue.
dworkDelayed work item.
delayDelay, PBL_NO_WAIT to queue now; must not be PBL_FOREVER.
Returns
true if scheduled, false if it was already pending.

◆ pbl_delayed_work_schedule_next()

void pbl_delayed_work_schedule_next ( struct pbl_delayed_work *  dwork,
pbl_tick_t  period 
)

Queue a delayed work item one period after its last expiry, so it does not drift.

For a periodic item, from its own function. When that time has passed, the item is queued on the next tick and later periods count from there, so missed periods do not pile up.

Parameters
dworkDelayed work item, which must have been scheduled before.
periodTicks since its last expiry.

◆ pbl_sys_work_block()

void pbl_sys_work_block ( bool  block)

Refuse new calls to pbl_sys_workq, e.g.

while the system shuts down.

Parameters
blocktrue to refuse them, false to accept them again.

◆ pbl_sys_work_call()

bool pbl_sys_work_call ( pbl_work_call_fn_t  fn,
void *  data 
)

Run a function with a payload on pbl_sys_workq.

For work that cannot embed a work item. Thread context only. A thread with its own slots, see pbl_thread_attr, waits for one; the queue's own thread puts what does not fit on the heap; any other thread waits a while, then stops the system, as a queue that stays full is stuck.

Parameters
fnFunction.
dataArgument of fn.
Returns
true if queued, false while calls are blocked.

◆ pbl_sys_work_call_from_isr()

bool pbl_sys_work_call_from_isr ( pbl_work_call_fn_t  fn,
void *  data 
)

Like pbl_sys_work_call(), from an ISR: stops the system at once if no slot is free.

Parameters
fnFunction.
dataArgument of fn.
Returns
true if queued, false while calls are blocked.

◆ pbl_sys_work_call_high()

bool pbl_sys_work_call_high ( pbl_work_call_fn_t  fn,
void *  data 
)

Run a short, time sensitive function with a payload on pbl_sys_workq_high.

Thread context only; waits a little for a free slot.

Parameters
fnFunction.
dataArgument of fn.
Returns
true if queued, false if no slot became free.

◆ pbl_sys_work_call_high_from_isr()

void pbl_sys_work_call_high_from_isr ( pbl_work_call_fn_t  fn,
void *  data 
)

Like pbl_sys_work_call_high(), from an ISR: the call is dropped if no slot is free.

Parameters
fnFunction.
dataArgument of fn.

◆ pbl_sys_work_current_fn()

void * pbl_sys_work_current_fn ( void  )

Get the function running on pbl_sys_workq, for debugging.

Returns
The function, including one behind a call the queue made to itself, NULL when idle.

◆ pbl_sys_work_num_free()

size_t pbl_sys_work_num_free ( void  )

Get how many calls the caller can make to pbl_sys_workq without waiting.

Returns
Free slots, the caller's own if it has some.

◆ pbl_sys_work_try_call()

bool pbl_sys_work_try_call ( pbl_work_call_fn_t  fn,
void *  data 
)

Like pbl_sys_work_call(), but never waits nor stops the system.

Callable from an ISR.

Parameters
fnFunction.
dataArgument of fn.
Returns
true if queued, false if no slot was free or calls are blocked.

◆ pbl_wallclock_work_init()

void pbl_wallclock_work_init ( struct pbl_wallclock_work *  w,
pbl_work_fn_t  fn 
)

Initialize a wall clock work item.

Parameters
[out]wWall clock work item.
fnFunction, whose argument is &w->work.

◆ pbl_wallclock_work_is_running()

bool pbl_wallclock_work_is_running ( const struct pbl_wallclock_work *  w)

Check whether a wall clock work item is started.

Parameters
wWall clock work item.
Returns
true from pbl_wallclock_work_start() until pbl_wallclock_work_stop().

◆ pbl_wallclock_work_start()

void pbl_wallclock_work_start ( struct pbl_workq *  q,
struct pbl_wallclock_work *  w,
uint32_t  unit_s,
uint32_t  every 
)

Queue a work item at every every -th boundary of the wall clock's unit_s seconds.

E.g. every minute, as the wall clock's minute changes, or every 5 seconds, as its second does. The first is every boundaries from now. Items due at the same boundary expire together, so they wake the system once.

Setting the clock moves the boundaries with it. A change that lands in another unit counts as one boundary, so a minute item runs at once when the clock moves to another minute. Starting a running item restarts it.

Parameters
qQueue.
wWall clock work item.
unit_sUnit in seconds, e.g. 1 or 60.
everyNumber of boundaries between runs.

◆ pbl_wallclock_work_stop()

bool pbl_wallclock_work_stop ( struct pbl_wallclock_work *  w)

Stop a wall clock work item, and remove it from its queue if it is pending.

Does not wait for a function that is running.

Parameters
wWall clock work item.
Returns
true if it was running.

◆ pbl_work_call()

int pbl_work_call ( struct pbl_workq *  q,
struct pbl_work_pool *  pool,
pbl_work_call_fn_t  fn,
void *  data,
pbl_timeout_t  timeout 
)

Run a function with a payload on a queue.

For work that cannot share a work item because several payloads may be pending at once; prefer a work item otherwise. The slot is released before fn runs, so fn may queue another call.

The queue's own thread never waits, as only it can release the slots of its queue's calls.

Parameters
qQueue.
poolPool to take the slot from.
fnFunction.
dataArgument of fn.
timeoutHow long to wait for a free slot; must be PBL_NO_WAIT in an ISR.
Returns
0 on success, -EBUSY if no slot was free without waiting, -EAGAIN on timeout.

◆ pbl_work_cancel()

bool pbl_work_cancel ( struct pbl_work *  work)

Remove a work item from its queue, without waiting for it if it is running.

Parameters
workWork item.
Returns
true if it was pending.

◆ pbl_work_cancel_sync()

bool pbl_work_cancel_sync ( struct pbl_work *  work)

Remove a work item from its queue and wait for it to finish running.

Thread context only.

On return the function is not running, unless called by the item itself, and will not run unless submitted again.

Parameters
workWork item.
Returns
true if it was pending.

◆ pbl_work_flush()

bool pbl_work_flush ( struct pbl_work *  work)

Wait for a work item to finish its last submission.

Thread context only.

Must not be called from the thread of the item's queue.

Parameters
workWork item.
Returns
true if it had to wait, false if the item was idle.

◆ pbl_work_init()

void pbl_work_init ( struct pbl_work *  work,
pbl_work_fn_t  fn 
)

Initialize a work item.

Parameters
[out]workWork item.
fnFunction.

◆ pbl_work_is_pending()

bool pbl_work_is_pending ( const struct pbl_work *  work)

Check whether a work item is queued.

Parameters
workWork item.
Returns
true from submission until its function starts or it is canceled.

◆ pbl_work_is_running()

bool pbl_work_is_running ( const struct pbl_work *  work)

Check whether a work item's function is running.

Parameters
workWork item.
Returns
true while the function runs.

◆ pbl_work_pool_init()

void pbl_work_pool_init ( struct pbl_work_pool *  pool,
struct pbl_work_call *  slots,
size_t  num_slots 
)

Initialize a pool in dynamically allocated memory.

Parameters
[out]poolPool.
slotsStorage for the slots, which must outlive the pool.
num_slotsNumber of calls that can be pending at once.

◆ pbl_work_pool_num_free()

size_t pbl_work_pool_num_free ( const struct pbl_work_pool *  pool)

Get the free slots of a pool.

Parameters
poolPool.
Returns
Number of calls that can be queued without waiting.

◆ pbl_work_submit()

bool pbl_work_submit ( struct pbl_workq *  q,
struct pbl_work *  work 
)

Queue a work item.

Parameters
qQueue.
workWork item.
Returns
true if queued, false if it was already pending.

◆ pbl_work_submit_boosted()

bool pbl_work_submit_boosted ( struct pbl_workq *  q,
struct pbl_work *  work 
)

Queue a work item that raises its queue's priority until it has run.

For latency sensitive work on a low priority queue, such as reading a device after its interrupt. The queue's thread runs at the priority set with pbl_workq_set_boost_prio() from now until the function returns or the item is canceled, together with any other boosted item. Submitting an item that is already pending boosts it.

Parameters
qQueue.
workWork item.
Returns
true if queued, false if it was already pending.

◆ pbl_workq_current_fn()

void * pbl_workq_current_fn ( const struct pbl_workq *  q)

Get the function being run, for debugging.

Parameters
qQueue.
Returns
The work or call function being run, NULL when idle.

◆ pbl_workq_flush()

void pbl_workq_flush ( struct pbl_workq *  q)

Wait until everything submitted so far has run.

Thread context only.

Must not be called from the queue's own thread.

Parameters
qQueue.

◆ pbl_workq_get_thread()

struct pbl_thread * pbl_workq_get_thread ( const struct pbl_workq *  q)

Get the thread serving a queue.

Parameters
qQueue.
Returns
Its thread, NULL until it has one.

◆ pbl_workq_init()

void pbl_workq_init ( struct pbl_workq *  q)

Initialize a work queue in dynamically allocated memory.

Parameters
[out]qQueue.

◆ pbl_workq_is_current()

bool pbl_workq_is_current ( const struct pbl_workq *  q)

Check whether the caller runs on a queue's thread.

Parameters
qQueue.
Returns
true on its thread, false elsewhere, including in an ISR.

◆ pbl_workq_set_boost_prio()

void pbl_workq_set_boost_prio ( struct pbl_workq *  q,
pbl_prio_t  prio 
)

Set the priority a queue's thread runs at while it has boosted work.

Parameters
qQueue.
prioPriority, above the thread's own for the boost to have an effect.

◆ pbl_workq_set_ops()

void pbl_workq_set_ops ( struct pbl_workq *  q,
const struct pbl_workq_ops *  ops 
)

Set the hooks of a queue, which take effect once it is next idle.

Parameters
qQueue.
opsHooks, which must outlive the queue.

◆ pbl_workq_thread()

void pbl_workq_thread ( void *  arg)

Thread entry serving a queue, with the queue as its argument.

For queues other than the system ones, which the kernel starts at boot. The caller creates the thread, which picks the queue's priority and stack. Work may be submitted before it starts.

Parameters
argQueue.

Variable Documentation

◆ pbl_sys_workq

struct pbl_workq pbl_sys_workq
extern

Queue for background work, which may block and take a while.

◆ pbl_sys_workq_high

struct pbl_workq pbl_sys_workq_high
extern

Queue for short, time sensitive work, at the highest thread priority.