summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/kern_tc.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src/kern_tc.c')
-rw-r--r--cpukit/score/src/kern_tc.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c
index 81c2131008..fa53fcd085 100644
--- a/cpukit/score/src/kern_tc.c
+++ b/cpukit/score/src/kern_tc.c
@@ -1418,6 +1418,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);
@@ -1461,6 +1470,7 @@ _Timecounter_Set_clock(const struct bintime *_bt,
#ifndef __rtems__
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);