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); }