From 5142b1f3888d0f2ee8e9bbe76460dbcb386f31aa Mon Sep 17 00:00:00 2001 From: Thomas Cort Date: Fri, 29 Mar 2013 19:34:29 +0000 Subject: [PATCH] kernel: rename realtime to monotonic, add realtime Old realtime was used for both timers (where an accurate count of all ticks is needed) and the system time. In order to implement adjtime(2), these duties must be separated as changing the time of day by a small amount shouldn't affect timers in any way nor should it change the boot time. Following the naming of the clocks used by clock_gettime(2). The clock named 'realtime' will represent the best guess at the current wall clock time, and the clock named 'monotonic' will represent the absolute time the system has been running. Use monotonic for timers in kernel and in drivers. Use realtime for determining time of day, dates, etc. This commit simply renames realtime to monotonic and adds a new tick counter named realtime. There are no functional changes in this commit. It just lays the foundation for future work. --- kernel/clock.c | 41 ++++++++++++++++++++++++++----------- kernel/debug.c | 2 +- kernel/main.c | 2 +- kernel/proc.c | 2 +- kernel/proto.h | 3 ++- kernel/system/do_setalarm.c | 4 ++-- kernel/system/do_times.c | 2 +- 7 files changed, 37 insertions(+), 19 deletions(-) diff --git a/kernel/clock.c b/kernel/clock.c index 6ae05665e..a0b796bcc 100644 --- a/kernel/clock.c +++ b/kernel/clock.c @@ -18,7 +18,8 @@ * In addition to the main clock_task() entry point, which starts the main * loop, there are several other minor entry points: * clock_stop: called just before MINIX shutdown - * get_uptime: get realtime since boot in clock ticks + * get_realtime: get wall time since boot in clock ticks + * get_monotonic: get monotonic time since boot in clock ticks * set_timer: set a watchdog timer (+) * reset_timer: reset a watchdog timer (+) * read_clock: read the counter of channel 0 of the 8253A timer @@ -51,11 +52,15 @@ static void load_update(void); * When a timer expires its watchdog function is run by the CLOCK task. */ static timer_t *clock_timers; /* queue of CLOCK timers */ -static clock_t next_timeout; /* realtime that next timer expires */ +static clock_t next_timeout; /* monotonic time that next timer expires */ /* The time is incremented by the interrupt handler on each clock tick. */ -static clock_t realtime = 0; /* real time clock */ +static clock_t monotonic = 0; + +/* Reflects the wall time and may be slowed/sped up by using adjclock() + */ +static clock_t realtime = 0; /* * The boot processor's timer interrupt handler. In addition to non-boot cpus @@ -82,8 +87,10 @@ int timer_int_handler(void) watchdog_local_timer_ticks++; #endif - if (cpu_is_bsp(cpuid)) + if (cpu_is_bsp(cpuid)) { + monotonic++; realtime++; + } /* Update user and system accounting times. Charge the current process * for user time. If the current process is not billable, that is, if a @@ -133,8 +140,8 @@ int timer_int_handler(void) if (cpu_is_bsp(cpuid)) { /* if a timer expired, notify the clock task */ - if ((next_timeout <= realtime)) { - tmrs_exptimers(&clock_timers, realtime, NULL); + if ((next_timeout <= monotonic)) { + tmrs_exptimers(&clock_timers, monotonic, NULL); next_timeout = (clock_timers == NULL) ? TMR_NEVER : clock_timers->tmr_exp_time; } @@ -152,20 +159,30 @@ int timer_int_handler(void) } /*===========================================================================* - * get_uptime * + * get_realtime * *===========================================================================*/ -clock_t get_uptime(void) +clock_t get_realtime(void) { - /* Get and return the current clock uptime in ticks. */ + /* Get and return the current wall time in ticks since boot. */ return(realtime); } + +/*===========================================================================* + * get_monotonic * + *===========================================================================*/ +clock_t get_monotonic(void) +{ + /* Get and return the number of ticks since boot. */ + return(monotonic); +} + /*===========================================================================* * set_timer * *===========================================================================*/ void set_timer(tp, exp_time, watchdog) struct timer *tp; /* pointer to timer structure */ -clock_t exp_time; /* expiration realtime */ +clock_t exp_time; /* expiration monotonic time */ tmr_func_t watchdog; /* watchdog to be called */ { /* Insert the new timer in the active timers list. Always update the @@ -206,7 +223,7 @@ static void load_update(void) * be made of the load average over variable periods, in the * user library (see getloadavg(3)). */ - slot = (realtime / system_hz / _LOAD_UNIT_SECS) % _LOAD_HISTORY; + slot = (monotonic / system_hz / _LOAD_UNIT_SECS) % _LOAD_HISTORY; if(slot != kloadinfo.proc_last_slot) { kloadinfo.proc_load_history[slot] = 0; kloadinfo.proc_last_slot = slot; @@ -223,7 +240,7 @@ static void load_update(void) kloadinfo.proc_load_history[slot] += enqueued; /* Up-to-dateness. */ - kloadinfo.last_clock = realtime; + kloadinfo.last_clock = monotonic; } int boot_cpu_init_timer(unsigned freq) diff --git a/kernel/debug.c b/kernel/debug.c index 4029f5ca5..45db4f705 100644 --- a/kernel/debug.c +++ b/kernel/debug.c @@ -456,7 +456,7 @@ static void statmsg(message *msg, struct proc *srcp, struct proc *dstp) messages[src][dst]++; /* Print something? */ - now = get_uptime(); + now = get_monotonic(); dt = now - lastprint; secs = dt/system_hz; if(secs >= 30) { diff --git a/kernel/main.c b/kernel/main.c index 732d7a6de..288ba24e7 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -340,7 +340,7 @@ void prepare_shutdown(const int how) */ printf("MINIX will now be shut down ...\n"); tmr_arg(&shutdown_timer)->ta_int = how; - set_timer(&shutdown_timer, get_uptime() + system_hz, minix_shutdown); + set_timer(&shutdown_timer, get_monotonic() + system_hz, minix_shutdown); } /*===========================================================================* diff --git a/kernel/proc.c b/kernel/proc.c index 3e597a5ab..8fb066dcd 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -99,7 +99,7 @@ static void set_idle_name(char * name, int n) #define BuildNotifyMessage(m_ptr, src, dst_ptr) \ (m_ptr)->m_type = NOTIFY_MESSAGE; \ - (m_ptr)->NOTIFY_TIMESTAMP = get_uptime(); \ + (m_ptr)->NOTIFY_TIMESTAMP = get_monotonic(); \ switch (src) { \ case HARDWARE: \ (m_ptr)->NOTIFY_ARG = priv(dst_ptr)->s_int_pending; \ diff --git a/kernel/proto.h b/kernel/proto.h index fc0207b39..77e53d8b6 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -15,7 +15,8 @@ struct proc; struct timer; /* clock.c */ -clock_t get_uptime(void); +clock_t get_realtime(void); +clock_t get_monotonic(void); void set_timer(struct timer *tp, clock_t t, tmr_func_t f); void reset_timer(struct timer *tp); void ser_dump_proc(void); diff --git a/kernel/system/do_setalarm.c b/kernel/system/do_setalarm.c index d384421ef..bcfde2fda 100644 --- a/kernel/system/do_setalarm.c +++ b/kernel/system/do_setalarm.c @@ -38,7 +38,7 @@ int do_setalarm(struct proc * caller, message * m_ptr) tp->tmr_func = cause_alarm; /* Return the ticks left on the previous alarm. */ - uptime = get_uptime(); + uptime = get_monotonic(); if ((tp->tmr_exp_time != TMR_NEVER) && (uptime < tp->tmr_exp_time) ) { m_ptr->ALRM_TIME_LEFT = (tp->tmr_exp_time - uptime); } else { @@ -49,7 +49,7 @@ int do_setalarm(struct proc * caller, message * m_ptr) if (exp_time == 0) { reset_timer(tp); } else { - tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_uptime(); + tp->tmr_exp_time = (use_abs_time) ? exp_time : exp_time + get_monotonic(); set_timer(tp, tp->tmr_exp_time, tp->tmr_func); } return(OK); diff --git a/kernel/system/do_times.c b/kernel/system/do_times.c index 16a646a1d..9d388cc22 100644 --- a/kernel/system/do_times.c +++ b/kernel/system/do_times.c @@ -35,7 +35,7 @@ int do_times(struct proc * caller, message * m_ptr) m_ptr->T_USER_TIME = rp->p_user_time; m_ptr->T_SYSTEM_TIME = rp->p_sys_time; } - m_ptr->T_BOOT_TICKS = get_uptime(); + m_ptr->T_BOOT_TICKS = get_monotonic(); m_ptr->T_BOOTTIME = boottime; return(OK); } -- 2.44.0