Allow the creator of a work_queue instance to choose whether
the work_queue thread should be marked as ESSENTIAL or not.
Signed-off-by: Mohamed ElShahawi <ExtremeGTX@hotmail.com>
Add a closing comment to the endif with the configuration
information to which the endif belongs too.
To make the code more clearer if the configs need adaptions.
Signed-off-by: Simon Hein <Shein@baumer.com>
The code `SYS_SLIST_FOR_EACH_CONTAINER_SAFE` just for remove work
from `pending_cancels`.
After removing work successfully, the function can return early.
It is unnecessary to iterate continuously.
Signed-off-by: TaiJu Wu <tjwu1217@gmail.com>
After a call to k_work_flush returns the sync variable
may still be modified by the workq. This is because
the work queue thread continues to modify the flag in
sync even after k_work_flush returns. This commit adds
K_WORK_FLUSHING_BIT, and with this bit, we moved the
logic of waking up the caller from handle_flush to the
finalize_flush_locked in workq, so that after waking up
the caller, the workqueue will no longer operate on sync.
Fixes: #64530
Signed-off-by: Junfan Song <sjf221100@gmail.com>
Assert that the handler of a work is not NULL when submitting
it to the queue. This allows early detection of the
code that is submitting a non-NULL work with NULL handler to
the work queue (where it happens), rather than right before the
work item get executed in the queue (when it happens).
Signed-off-by: Yong Cong Sin <ycsin@meta.com>
This header does not expose any public APIs, so move it under
kernel/include and change files including it.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The call to unschedule_locked() would return true ("successfully
unscheduled") even in the case where the underlying z_abort_timeout()
failed (because the callback was already unpended and
in-progress/complete/about-to-be-run, remember that timeout callbacks
are unsynchronized), leading to state bugs and races against the
callback behavior.
Correctly detect that case and propagate the error to the caller.
Fixes#51872
Signed-off-by: Andy Ross <andyross@google.com>
This adds the internal function z_work_submit_to_queue(), which
submits the work item to the queue but doesn't force the thread to yield,
compared to the public function k_work_submit_to_queue().
When called from poll.c in the context of k_work_poll events, it ensures
that the thread does not yield in the context of the spinlock of object
that became available.
Fixes#45267
Signed-off-by: Lucas Dietrich <ld.adecy@gmail.com>
In order to bring consistency in-tree, migrate all kernel code to the
new prefix <zephyr/...>. Note that the conversion has been scripted,
refer to zephyrproject-rtos#45388 for more details.
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
The work queue has a semi/non-standard reschedule point implemented
using k_yield(), with a check to see if the current thread is
preemptible. Just call z_reschedule_unlocked(), it has this check
internally and is the intended API for this.
Really, this is only a half fix. Ideally the schedule point and the
lock release should be atomic[1] via the more idiomatic
z_reschedule(). But that would take some surgery, so let's go with
the simpler cleanup first.
This also avoids having to duplicate logic that gets added to
reschedule points by an upcoming patch.
[1] So that they represent a condition variable and don't race at the
end. In this case the race is present but benign, since the only thing
we really want to know is that the queue thread gets a chance to run.
The only cost is an occasional duplicated/needless context switch if
two threads are racing on a submit.
Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
The k_work::flags field is not an atomic_t and would cause
-Wpointer-sign warning on some compilers. This function was the only
one in work.c to use atomic_get() so there is no benefit to atomicity.
Signed-off-by: Chris Reed <chris.reed@arm.com>
k_work_queue_start receives a struct that is expected to be
uninitialized (zeroed). Otherwise the behavior is undefined.
Following the Zephyr semantics, this pr introduce a new init function
for this struct.
Fixes#36865
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
Coding scanning tool raises a violation that happens dereferencing
of the "work" pointer in the expression "work->handler"
As were discussed before in PR #35664 it is not true.
Add explanation comment, because static code analysis tool
raised false-positive violation there.
Signed-off-by: Maksim Masalski <maksim.masalski@intel.com>
The original state management solution involved separate locks for a
work queue and each work item. To avoid inter-lock dependencies a
window was left between the point where the work item was removed from
the queue (protected by queue lock) and the point where the work item
state was updated to mark the work item running.
This introduced a bug: If a cancellation was issued during this window
it would succeed, and the work item would appear to be idle even
though in fact the work queue thread was about to run it.
Since there is now only one lock, move the work item state updates
into the mutex regions associated with dequeuing the work item and
clearing the work queue busy flag.
Note that removing the window between queue and work mutex regions
eliminates the potential of having a dequeued work item be cancelled
before its QUEUED flag is cleared, simplifying the work item state
update.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
work_timeout() is a function, a statement like "(void)work_timeout;"
has no effect.
Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
work_queue_main() was missing final else statement
in the if else if construct. This commit adds else {}
to comply with coding guideline 15.7. Includes a
context-specific description of why this branch is empty.
Signed-off-by: Jennifer Williams <jennifer.m.williams@intel.com>
The return value is documented to be true if the work was pending, but
the implementation returned true only if the work was actually running
(i.e. the caller had to wait). It should also return true if
scheduled or submitted work was cancelled.
Note that this means the return value cannot be used to determine
whether the call slept.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Add a 'U' suffix to values when computing and comparing against
unsigned variables and other related fixes of the same MISRA rule (10.4)
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
k_work_schedule() is supposed to be a no-op if the work item is
already scheduled or submitted: the previous schedule is left
unchanged. The check incorrectly inhibited the schedule operation
when the work item was neither scheduled nor submitted, but was
running.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This commit provides a complete reimplementation of the work queue
infrastructure intended to eliminate the race conditions and feature
gaps in the existing implementation.
Both bare and delayable work structures are supported. Items can be
submitted; delayable items can be scheduled for submission at a future
time. Items can be delayed, queued, and running all at the same time.
A running item can also be canceling.
The new implementation:
* replaces "pending" with "busy" which identifies the active states;
* supports canceling delayed and submitted items;
* prevents resubmission of a item being canceled until cancellation
completes;
* supports waiting for cancellation to complete;
* supports flushing a work item (waiting for the last submission to
complete without preventing resubmission);
* supports waiting for a queue to drain (only allows resubmission from
the work thread);
* supports stopping a work queue in conjunction with draining it;
* prevents handler-reentrancy during resubmission.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>