mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-06 00:20:29 +00:00
Add missing pieces of r315280
I moved this branch from github to a private server, and pulled from the wrong one when committing r315280, so I failed to include two recent commits. Thankfully, they were only cosmetic and were included in the review. Specifically: Add documentation, polish comments, and improve style(9). Tested by: pho (r315280) MFC after: 2 weeks Sponsored by: Dell EMC Differential Revision: https://reviews.freebsd.org/D9791
This commit is contained in:
parent
40769242ed
commit
8addc72b3e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=315287
|
@ -280,6 +280,21 @@ to
|
|||
pay particular attention to ensure that no other threads wait on the
|
||||
same
|
||||
.Fa chan .
|
||||
.Pp
|
||||
If the timeout given by
|
||||
.Fa timo
|
||||
or
|
||||
.Fa sbt
|
||||
is based on an absolute real-time clock value,
|
||||
then the thread should copy the global
|
||||
.Va rtc_generation
|
||||
into its
|
||||
.Va td_rtcgen
|
||||
member before reading the RTC.
|
||||
If the real-time clock is adjusted, these functions will set
|
||||
.Va td_rtcgen
|
||||
to zero and return zero.
|
||||
The caller should reconsider its orientation with the new RTC value.
|
||||
.Sh RETURN VALUES
|
||||
When awakened by a call to
|
||||
.Fn wakeup
|
||||
|
@ -298,6 +313,9 @@ the
|
|||
.Fn msleep_spin ,
|
||||
.Fn tsleep ,
|
||||
and locking primitive sleep functions return 0.
|
||||
Zero can also be returned when the real-time clock is adjusted;
|
||||
see above regarding
|
||||
.Va td_rtcgen .
|
||||
Otherwise, a non-zero error code is returned.
|
||||
.Sh ERRORS
|
||||
.Fn msleep ,
|
||||
|
|
|
@ -1269,6 +1269,15 @@ static bool
|
|||
sleeping_on_old_rtc(struct thread *td)
|
||||
{
|
||||
|
||||
/*
|
||||
* td_rtcgen is modified by curthread when it is running,
|
||||
* and by other threads in this function. By finding the thread
|
||||
* on a sleepqueue and holding the lock on the sleepqueue
|
||||
* chain, we guarantee that the thread is not running and that
|
||||
* modifying td_rtcgen is safe. Setting td_rtcgen to zero informs
|
||||
* the thread that it was woken due to a real-time clock adjustment.
|
||||
* (The declaration of td_rtcgen refers to this comment.)
|
||||
*/
|
||||
if (td->td_rtcgen != 0 && td->td_rtcgen != rtc_generation) {
|
||||
td->td_rtcgen = 0;
|
||||
return (true);
|
||||
|
@ -1299,6 +1308,7 @@ tc_setclock(struct timespec *ts)
|
|||
/* XXX fiddle all the little crinkly bits around the fiords... */
|
||||
tc_windup(&bt);
|
||||
mtx_unlock_spin(&tc_setclock_mtx);
|
||||
|
||||
/* Avoid rtc_generation == 0, since td_rtcgen == 0 is special. */
|
||||
atomic_add_rel_int(&rtc_generation, 2);
|
||||
sleepq_chains_remove_matching(sleeping_on_old_rtc);
|
||||
|
|
|
@ -561,9 +561,21 @@ sleepq_switch(void *wchan, int pri)
|
|||
/*
|
||||
* If TDF_TIMEOUT is set, then our sleep has been timed out
|
||||
* already but we are still on the sleep queue, so dequeue the
|
||||
* thread and return. Do the same if the real-time clock has
|
||||
* been adjusted since this thread calculated its timeout
|
||||
* based on that clock.
|
||||
* thread and return.
|
||||
*
|
||||
* Do the same if the real-time clock has been adjusted since this
|
||||
* thread calculated its timeout based on that clock. This handles
|
||||
* the following race:
|
||||
* - The Ts thread needs to sleep until an absolute real-clock time.
|
||||
* It copies the global rtc_generation into curthread->td_rtcgen,
|
||||
* reads the RTC, and calculates a sleep duration based on that time.
|
||||
* See umtxq_sleep() for an example.
|
||||
* - The Tc thread adjusts the RTC, bumps rtc_generation, and wakes
|
||||
* threads that are sleeping until an absolute real-clock time.
|
||||
* See tc_setclock() and the POSIX specification of clock_settime().
|
||||
* - Ts reaches the code below. It holds the sleepqueue chain lock,
|
||||
* so Tc has finished waking, so this thread must test td_rtcgen.
|
||||
* (The declaration of td_rtcgen refers to this comment.)
|
||||
*/
|
||||
rtc_changed = td->td_rtcgen != 0 && td->td_rtcgen != rtc_generation;
|
||||
if ((td->td_flags & TDF_TIMEOUT) || rtc_changed) {
|
||||
|
@ -899,6 +911,7 @@ sleepq_signal(void *wchan, int flags, int pri, int queue)
|
|||
static bool
|
||||
match_any(struct thread *td __unused)
|
||||
{
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ struct pargs {
|
|||
* o - ktrace lock
|
||||
* q - td_contested lock
|
||||
* r - p_peers lock
|
||||
* s - by curthread, or by others when curthread is on sleepqueue
|
||||
* s - see sleepq_switch(), sleeping_on_old_rtc(), and sleep(9)
|
||||
* t - thread lock
|
||||
* u - process stat lock
|
||||
* w - process timer lock
|
||||
|
|
Loading…
Reference in a new issue