diff options
Diffstat (limited to 'cpukit/score/src/kern_tc.c')
-rw-r--r-- | cpukit/score/src/kern_tc.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c index 2810fd88dd..81c2131008 100644 --- a/cpukit/score/src/kern_tc.c +++ b/cpukit/score/src/kern_tc.c @@ -56,7 +56,9 @@ __FBSDID("$FreeBSD r284178 2015-06-09T11:49:56Z$"); #include <sys/limits.h> #include <sys/lock.h> #include <sys/mutex.h> +#include <sys/proc.h> #include <sys/sbuf.h> +#include <sys/sleepqueue.h> #include <sys/sysctl.h> #include <sys/syslog.h> #include <sys/systm.h> @@ -232,6 +234,8 @@ SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation, sysctl_kern_timecounter_adjprecision, "I", "Allowed time interval deviation in percents"); +volatile int rtc_generation = 1; + static int tc_chosen; /* Non-zero if a specific tc was chosen via sysctl. */ #endif /* __rtems__ */ @@ -1410,6 +1414,17 @@ tc_getfrequency(void) return (timehands->th_counter->tc_frequency); } +static bool +sleeping_on_old_rtc(struct thread *td) +{ + + if (td->td_rtcgen != 0 && td->td_rtcgen != rtc_generation) { + td->td_rtcgen = 0; + return (true); + } + return (false); +} + static struct mtx tc_setclock_mtx; MTX_SYSINIT(tc_setclock_init, &tc_setclock_mtx, "tcsetc", MTX_SPIN); #endif /* __rtems__ */ @@ -1446,6 +1461,9 @@ _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); if (timestepwarnings) { nanotime(&taft); log(LOG_INFO, |