Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_tc.c
Show First 20 Lines • Show All 1,347 Lines • ▼ Show 20 Lines | |||||
* Initialize the next struct timehands in the ring and make | * Initialize the next struct timehands in the ring and make | ||||
* it the active timehands. Along the way we might switch to a different | * it the active timehands. Along the way we might switch to a different | ||||
* timecounter and/or do seconds processing in NTP. Slightly magic. | * timecounter and/or do seconds processing in NTP. Slightly magic. | ||||
*/ | */ | ||||
static void | static void | ||||
tc_windup(struct bintime *new_boottimebin) | tc_windup(struct bintime *new_boottimebin) | ||||
{ | { | ||||
struct bintime bt; | struct bintime bt; | ||||
struct timecounter *tc; | |||||
struct timehands *th, *tho; | struct timehands *th, *tho; | ||||
u_int delta, ncount, ogen; | u_int delta, ncount, ogen; | ||||
int i; | int i; | ||||
time_t t; | time_t t; | ||||
/* | /* | ||||
* Make the next timehands a copy of the current one, but do | * Make the next timehands a copy of the current one, but do | ||||
* not overwrite the generation or next pointer. While we | * not overwrite the generation or next pointer. While we | ||||
Show All 12 Lines | tc_windup(struct bintime *new_boottimebin) | ||||
if (new_boottimebin != NULL) | if (new_boottimebin != NULL) | ||||
th->th_boottime = *new_boottimebin; | th->th_boottime = *new_boottimebin; | ||||
/* | /* | ||||
* Capture a timecounter delta on the current timecounter and if | * Capture a timecounter delta on the current timecounter and if | ||||
* changing timecounters, a counter value from the new timecounter. | * changing timecounters, a counter value from the new timecounter. | ||||
* Update the offset fields accordingly. | * Update the offset fields accordingly. | ||||
*/ | */ | ||||
tc = atomic_load_ptr(&timecounter); | |||||
delta = tc_delta(th); | delta = tc_delta(th); | ||||
if (th->th_counter != timecounter) | if (th->th_counter != tc) | ||||
ncount = timecounter->tc_get_timecount(timecounter); | ncount = tc->tc_get_timecount(tc); | ||||
else | else | ||||
ncount = 0; | ncount = 0; | ||||
#ifdef FFCLOCK | #ifdef FFCLOCK | ||||
ffclock_windup(delta); | ffclock_windup(delta); | ||||
#endif | #endif | ||||
th->th_offset_count += delta; | th->th_offset_count += delta; | ||||
th->th_offset_count &= th->th_counter->tc_counter_mask; | th->th_offset_count &= th->th_counter->tc_counter_mask; | ||||
while (delta > th->th_counter->tc_frequency) { | while (delta > th->th_counter->tc_frequency) { | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
/* Update the UTC timestamps used by the get*() functions. */ | /* Update the UTC timestamps used by the get*() functions. */ | ||||
th->th_bintime = bt; | th->th_bintime = bt; | ||||
bintime2timeval(&bt, &th->th_microtime); | bintime2timeval(&bt, &th->th_microtime); | ||||
bintime2timespec(&bt, &th->th_nanotime); | bintime2timespec(&bt, &th->th_nanotime); | ||||
/* Now is a good time to change timecounters. */ | /* Now is a good time to change timecounters. */ | ||||
if (th->th_counter != timecounter) { | if (th->th_counter != tc) { | ||||
#ifndef __arm__ | #ifndef __arm__ | ||||
if ((timecounter->tc_flags & TC_FLAGS_C2STOP) != 0) | if ((tc->tc_flags & TC_FLAGS_C2STOP) != 0) | ||||
cpu_disable_c2_sleep++; | cpu_disable_c2_sleep++; | ||||
if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0) | if ((th->th_counter->tc_flags & TC_FLAGS_C2STOP) != 0) | ||||
cpu_disable_c2_sleep--; | cpu_disable_c2_sleep--; | ||||
#endif | #endif | ||||
th->th_counter = timecounter; | th->th_counter = tc; | ||||
th->th_offset_count = ncount; | th->th_offset_count = ncount; | ||||
tc_min_ticktock_freq = max(1, timecounter->tc_frequency / | tc_min_ticktock_freq = max(1, tc->tc_frequency / | ||||
(((uint64_t)timecounter->tc_counter_mask + 1) / 3)); | (((uint64_t)tc->tc_counter_mask + 1) / 3)); | ||||
recalculate_scaling_factor_and_large_delta(th); | recalculate_scaling_factor_and_large_delta(th); | ||||
#ifdef FFCLOCK | #ifdef FFCLOCK | ||||
ffclock_change_tc(th); | ffclock_change_tc(th); | ||||
#endif | #endif | ||||
} | } | ||||
/* | /* | ||||
* Now that the struct timehands is again consistent, set the new | * Now that the struct timehands is again consistent, set the new | ||||
▲ Show 20 Lines • Show All 798 Lines • Show Last 20 Lines |