Skip to content

Commit

Permalink
[nrf fromtree] kernel/workq: Cleanup bespoke reschedule point
Browse files Browse the repository at this point in the history
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>
Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
(cherry picked from commit b676d48)
  • Loading branch information
Andy Ross authored and mbolivar-nordic committed May 19, 2022
1 parent 19915ba commit 3707606
Showing 1 changed file with 6 additions and 6 deletions.
12 changes: 6 additions & 6 deletions kernel/work.c
Expand Up @@ -368,13 +368,13 @@ int k_work_submit_to_queue(struct k_work_q *queue,

k_spin_unlock(&lock, key);

/* If we changed the queue contents (as indicated by a positive ret)
* the queue thread may now be ready, but we missed the reschedule
* point because the lock was held. If this is being invoked by a
* preemptible thread then yield.
/* submit_to_queue_locked() won't reschedule on its own
* (really it should, otherwise this process will result in
* spurious calls to z_swap() due to the race), so do it here
* if the queue state changed.
*/
if ((ret > 0) && (k_is_preempt_thread() != 0)) {
k_yield();
if (ret > 0) {
z_reschedule_unlocked();
}

SYS_PORT_TRACING_OBJ_FUNC_EXIT(k_work, submit_to_queue, queue, work, ret);
Expand Down

0 comments on commit 3707606

Please sign in to comment.