diff --git a/minix/drivers/net/dpeth/3c501.c b/minix/drivers/net/dpeth/3c501.c index d74600279..2fd87e5f3 100644 --- a/minix/drivers/net/dpeth/3c501.c +++ b/minix/drivers/net/dpeth/3c501.c @@ -133,7 +133,7 @@ static int el1_send(dpeth_t *dep, struct netdriver_data *data, size_t size) clock_t now; if (dep->de_flags & DEF_XMIT_BUSY) { - getticks(&now); + now = getticks(); if ((now - dep->de_xmit_start) > 4) { /* Transmitter timed out */ DEBUG(printf("3c501: transmitter timed out ... \n")); @@ -171,7 +171,7 @@ static int el1_send(dpeth_t *dep, struct netdriver_data *data, size_t size) outw_el1(dep, EL1_XMITPTR, (EL1_BFRSIZ - size)); outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_XMIT); /* There it goes... */ - getticks(&dep->de_xmit_start); + dep->de_xmit_start = getticks(); return OK; } diff --git a/minix/drivers/net/dpeth/3c509.c b/minix/drivers/net/dpeth/3c509.c index d1b6dc4c2..debcb2f2c 100644 --- a/minix/drivers/net/dpeth/3c509.c +++ b/minix/drivers/net/dpeth/3c509.c @@ -194,7 +194,7 @@ static int el3_send(dpeth_t *dep, struct netdriver_data *data, size_t size) short int TxStatus; size_t padding; - getticks(&now); + now = getticks(); if ((dep->de_flags & DEF_XMIT_BUSY) && (now - dep->de_xmit_start) > 4) { @@ -217,7 +217,7 @@ static int el3_send(dpeth_t *dep, struct netdriver_data *data, size_t size) padding = size; while ((padding++ % sizeof(long)) != 0) outb(dep->de_data_port, 0x00); - getticks(&dep->de_xmit_start); + dep->de_xmit_start = getticks(); dep->de_flags |= DEF_XMIT_BUSY; if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) { /* Tx has enough room for a packet of maximum size */ diff --git a/minix/drivers/storage/fbd/fbd.c b/minix/drivers/storage/fbd/fbd.c index ee216b663..9861d3b21 100644 --- a/minix/drivers/storage/fbd/fbd.c +++ b/minix/drivers/storage/fbd/fbd.c @@ -50,8 +50,6 @@ static struct optset optset_table[] = { *===========================================================================*/ static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) { - clock_t uptime; - int r; /* Parse the given parameters. */ if (env_argc > 1) @@ -74,12 +72,10 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info)) /* Initialize resources. */ fbd_buf = alloc_contig(BUF_SIZE, 0, NULL); - assert(fbd_buf != NULL); + if (fbd_buf == NULL) + panic("unable to allocate buffer"); - if ((r = getticks(&uptime)) != OK) - panic("getuptime failed (%d)\n", r); - - srand48(uptime); + srand48(getticks()); /* Announce we are up! */ blockdriver_announce(type); diff --git a/minix/drivers/storage/filter/util.c b/minix/drivers/storage/filter/util.c index ff33f5c3b..474783cea 100644 --- a/minix/drivers/storage/filter/util.c +++ b/minix/drivers/storage/filter/util.c @@ -60,9 +60,7 @@ clock_t flt_alarm(clock_t dt) } else { if(next_alarm) panic("overwriting alarm: %d", r); - if ((r = getticks(&next_alarm)) != OK) - panic("getuptime failed: %d", r); - next_alarm += dt; + next_alarm = getticks() + dt; } return next_alarm; diff --git a/minix/fs/procfs/root.c b/minix/fs/procfs/root.c index 83aec45d6..b75307789 100644 --- a/minix/fs/procfs/root.c +++ b/minix/fs/procfs/root.c @@ -74,12 +74,9 @@ root_loadavg(void) static void root_uptime(void) { - clock_t ticks; ldiv_t division; - if (getticks(&ticks) != OK) - return; - division = ldiv(100L * ticks / sys_hz(), 100L); + division = ldiv(100L * getticks() / sys_hz(), 100L); buf_printf("%ld.%0.2ld\n", division.quot, division.rem); } diff --git a/minix/fs/procfs/tree.c b/minix/fs/procfs/tree.c index 4e859c71f..d6a673aec 100644 --- a/minix/fs/procfs/tree.c +++ b/minix/fs/procfs/tree.c @@ -426,14 +426,12 @@ lookup_hook(struct inode * parent, char * name, cbdata_t __unused cbdata) { static clock_t last_update = 0; clock_t now; - int r; /* * Update lazily for lookups, as this gets too expensive otherwise. * Alternative: pull in only PM's table? */ - if ((r = getticks(&now)) != OK) - panic("unable to get uptime: %d", r); + now = getticks(); if (last_update != now) { update_tables(); diff --git a/minix/include/minix/ipc.h b/minix/include/minix/ipc.h index 9e2eeff42..068d43d20 100644 --- a/minix/include/minix/ipc.h +++ b/minix/include/minix/ipc.h @@ -305,11 +305,11 @@ _ASSERT_MSG_SIZE(mess_krn_lsys_sys_irqctl); typedef struct { clock_t real_ticks; clock_t boot_ticks; - clock_t boot_time; clock_t user_time; clock_t system_time; + time_t boot_time; - uint8_t padding[36]; + uint8_t padding[32]; } mess_krn_lsys_sys_times; _ASSERT_MSG_SIZE(mess_krn_lsys_sys_times); diff --git a/minix/include/minix/sysutil.h b/minix/include/minix/sysutil.h index 45a756044..9d561cadd 100644 --- a/minix/include/minix/sysutil.h +++ b/minix/include/minix/sysutil.h @@ -55,7 +55,7 @@ __dead void panic(const char *fmt, ...) void panic_hook(void); void __panic_hook(void); int getuptime(clock_t *ticks, clock_t *realtime, time_t *boottime); -int getticks(clock_t *ticks); +clock_t getticks(void); int tickdelay(clock_t ticks); int tsc_calibrate(void); u32_t sys_hz(void); diff --git a/minix/include/minix/type.h b/minix/include/minix/type.h index 88cb3d705..599e2a86a 100644 --- a/minix/include/minix/type.h +++ b/minix/include/minix/type.h @@ -2,6 +2,7 @@ #define _TYPE_H #include +#include #include @@ -91,6 +92,24 @@ struct loadinfo { clock_t last_clock; }; +struct kclockinfo { + time_t boottime; /* number of seconds since UNIX epoch */ +#if BYTE_ORDER == LITTLE_ENDIAN + clock_t uptime; /* number of clock ticks since system boot */ + uint32_t _rsvd1; /* reserved for 64-bit uptime */ + clock_t realtime; /* real time in clock ticks since boot */ + uint32_t _rsvd2; /* reserved for 64-bit real time */ +#elif BYTE_ORDER == BIG_ENDIAN + uint32_t _rsvd1; /* reserved for 64-bit uptime */ + clock_t uptime; /* number of clock ticks since system boot */ + uint32_t _rsvd2; /* reserved for 64-bit real time */ + clock_t realtime; /* real time in clock ticks since boot */ +#else +#error "unknown endianness" +#endif + uint32_t hz; /* clock frequency in ticks per second */ +}; + struct machine { unsigned processors_count; /* how many cpus are available */ unsigned bsp_id; /* id of the bootstrap cpu */ @@ -174,15 +193,16 @@ struct minix_kerninfo { u32_t kerninfo_magic; u32_t minix_feature_flags; /* features in minix kernel */ u32_t ki_flags; /* what is present in this struct */ - u32_t minix_frclock_tcrr; + u32_t minix_frclock_tcrr; /* NOT userland ABI */ u32_t flags_unused3; u32_t flags_unused4; struct kinfo *kinfo; - struct machine *machine; - struct kmessages *kmessages; - struct loadinfo *loadinfo; + struct machine *machine; /* NOT userland ABI */ + struct kmessages *kmessages; /* NOT userland ABI */ + struct loadinfo *loadinfo; /* NOT userland ABI */ struct minix_ipcvecs *minix_ipcvecs; - u64_t minix_arm_frclock_hz; /* minix_frclock_tcrr frequency */ + u64_t minix_arm_frclock_hz; /* minix_frclock_tcrr frequency !ABI */ + volatile struct kclockinfo *kclockinfo; /* NOT userland ABI */ } __packed; #define MINIX_KIF_IPCVECS (1L << 0) diff --git a/minix/kernel/arch/earm/memory.c b/minix/kernel/arch/earm/memory.c index 743886a33..acc3a8257 100644 --- a/minix/kernel/arch/earm/memory.c +++ b/minix/kernel/arch/earm/memory.c @@ -714,6 +714,7 @@ int arch_phys_map_reply(const int index, const vir_bytes addr) ASSIGN(machine); ASSIGN(kmessages); ASSIGN(loadinfo); + ASSIGN(kclockinfo); /* adjust the pointers of the functions and the struct * itself to the user-accessible mapping diff --git a/minix/kernel/arch/i386/memory.c b/minix/kernel/arch/i386/memory.c index 57ca4ce9c..cabd73ff9 100644 --- a/minix/kernel/arch/i386/memory.c +++ b/minix/kernel/arch/i386/memory.c @@ -879,6 +879,7 @@ int arch_phys_map_reply(const int index, const vir_bytes addr) ASSIGN(machine); ASSIGN(kmessages); ASSIGN(loadinfo); + ASSIGN(kclockinfo); /* select the right set of IPC routines to map into processes */ if(minix_feature_flags & MKF_I386_INTEL_SYSENTER) { diff --git a/minix/kernel/clock.c b/minix/kernel/clock.c index 0c71d701c..00c3da834 100644 --- a/minix/kernel/clock.c +++ b/minix/kernel/clock.c @@ -1,9 +1,8 @@ -/* This file contains the clock task, which handles time related functions. - * Important events that are handled by the CLOCK include setting and - * monitoring alarm timers and deciding when to (re)schedule processes. - * The CLOCK offers a direct interface to kernel processes. System services - * can access its services through system calls, such as sys_setalarm(). The - * CLOCK task thus is hidden from the outside world. +/* This file contains the architecture-independent clock functionality, which + * handles time related functions. Important events that are handled here + * include setting and monitoring alarm timers and deciding when to + * (re)schedule processes. System services can access its services through + * system calls, such as sys_setalarm(). * * Changes: * Aug 18, 2006 removed direct hardware access etc, MinixPPC (Ingmar Alting) @@ -11,29 +10,12 @@ * Mar 18, 2004 clock interface moved to SYSTEM task (Jorrit N. Herder) * Sep 30, 2004 source code documentation updated (Jorrit N. Herder) * Sep 24, 2004 redesigned alarm timers (Jorrit N. Herder) - * - * Clock task is notified by the clock's interrupt handler when a timer - * has expired. - * - * 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_realtime: get wall time since boot in clock ticks - * set_realtime: set wall time since boot in clock ticks - * set_adjtime_delta: set the number of ticks to adjust realtime - * get_monotonic: get monotonic time since boot in clock ticks - * set_kernel_timer: set a watchdog timer (+) - * reset_kernel_timer: reset a watchdog timer (+) - * read_clock: read the counter of channel 0 of the 8253A timer - * - * (+) The CLOCK task keeps tracks of watchdog timers for the entire kernel. - * It is crucial that watchdog functions not block, or the CLOCK task may - * be blocked. Do not send() a message when the receiver is not expecting it. - * Instead, notify(), which always returns, should be used. */ #include "kernel/kernel.h" #include +#include +#include #include #include "clock.h" @@ -56,19 +38,34 @@ static void load_update(void); static minix_timer_t *clock_timers; /* queue of CLOCK timers */ 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 monotonic = 0; - -/* Reflects the wall time and may be slowed/sped up by using adjclock() - */ -static clock_t realtime = 0; - /* Number of ticks to adjust realtime by. A negative value implies slowing * down realtime, a positive value implies speeding it up. */ static int32_t adjtime_delta = 0; +/* + * Initialize the clock variables. + */ +void +init_clock(void) +{ + char *value; + int i; + + /* Initialize clock information structure. */ + memset(&kclockinfo, 0, sizeof(kclockinfo)); + + /* Get clock tick frequency. */ + value = env_get("hz"); + if (value != NULL) + kclockinfo.hz = atoi(value); + if (value == NULL || kclockinfo.hz < 2 || kclockinfo.hz > 50000) + kclockinfo.hz = DEFAULT_HZ; + + /* Load average data initialization. */ + memset(&kloadinfo, 0, sizeof(kloadinfo)); +} + /* * The boot processor's timer interrupt handler. In addition to non-boot cpus * it keeps real time and notifies the clock task if need be. @@ -95,17 +92,17 @@ int timer_int_handler(void) #endif if (cpu_is_bsp(cpuid)) { - monotonic++; + kclockinfo.uptime++; /* if adjtime_delta has ticks remaining, apply one to realtime. * limit changes to every other interrupt. */ - if (adjtime_delta != 0 && monotonic & 0x1) { + if (adjtime_delta != 0 && kclockinfo.uptime & 0x1) { /* go forward or stay behind */ - realtime += (adjtime_delta > 0) ? 2 : 0; + kclockinfo.realtime += (adjtime_delta > 0) ? 2 : 0; adjtime_delta += (adjtime_delta > 0) ? -1 : +1; } else { - realtime++; + kclockinfo.realtime++; } } @@ -158,8 +155,8 @@ int timer_int_handler(void) if (cpu_is_bsp(cpuid)) { /* if a timer expired, notify the clock task */ - if ((next_timeout <= monotonic)) { - tmrs_exptimers(&clock_timers, monotonic, NULL); + if ((next_timeout <= kclockinfo.uptime)) { + tmrs_exptimers(&clock_timers, kclockinfo.uptime, NULL); next_timeout = (clock_timers == NULL) ? TMR_NEVER : clock_timers->tmr_exp_time; } @@ -182,7 +179,7 @@ int timer_int_handler(void) clock_t get_realtime(void) { /* Get and return the current wall time in ticks since boot. */ - return(realtime); + return(kclockinfo.realtime); } /*===========================================================================* @@ -190,7 +187,7 @@ clock_t get_realtime(void) *===========================================================================*/ void set_realtime(clock_t newrealtime) { - realtime = newrealtime; + kclockinfo.realtime = newrealtime; } /*===========================================================================* @@ -207,7 +204,24 @@ void set_adjtime_delta(int32_t ticks) clock_t get_monotonic(void) { /* Get and return the number of ticks since boot. */ - return(monotonic); + return(kclockinfo.uptime); +} + +/*===========================================================================* + * set_boottime * + *===========================================================================*/ +void set_boottime(time_t newboottime) +{ + kclockinfo.boottime = newboottime; +} + +/*===========================================================================* + * get_boottime * + *===========================================================================*/ +time_t get_boottime(void) +{ + /* Get and return the number of seconds since the UNIX epoch. */ + return(kclockinfo.boottime); } /*===========================================================================* @@ -256,7 +270,8 @@ static void load_update(void) * be made of the load average over variable periods, in the * user library (see getloadavg(3)). */ - slot = (monotonic / system_hz / _LOAD_UNIT_SECS) % _LOAD_HISTORY; + slot = (kclockinfo.uptime / system_hz / _LOAD_UNIT_SECS) % + _LOAD_HISTORY; if(slot != kloadinfo.proc_last_slot) { kloadinfo.proc_load_history[slot] = 0; kloadinfo.proc_last_slot = slot; @@ -273,7 +288,7 @@ static void load_update(void) kloadinfo.proc_load_history[slot] += enqueued; /* Up-to-dateness. */ - kloadinfo.last_clock = monotonic; + kloadinfo.last_clock = kclockinfo.uptime; } int boot_cpu_init_timer(unsigned freq) diff --git a/minix/kernel/glo.h b/minix/kernel/glo.h index ace161e9f..666655387 100644 --- a/minix/kernel/glo.h +++ b/minix/kernel/glo.h @@ -23,6 +23,7 @@ extern struct kinfo kinfo; /* kernel information for users */ extern struct machine machine; /* machine information for users */ extern struct kmessages kmessages; /* diagnostic messages in kernel */ extern struct loadinfo loadinfo; /* status of load average */ +extern struct kclockinfo kclockinfo; /* clock information */ extern struct minix_kerninfo minix_kerninfo; EXTERN struct k_randomness krandom; /* gather kernel random information */ @@ -32,6 +33,8 @@ EXTERN vir_bytes minix_kerninfo_user; #define kmess kmessages #define kloadinfo loadinfo +#define system_hz (kclockinfo.hz) /* HZ value (alias) */ + /* Process scheduling information and the kernel reentry count. */ EXTERN struct proc *vmrequest; /* first process on vmrequest queue */ EXTERN unsigned lost_ticks; /* clock ticks counted outside clock task */ @@ -43,10 +46,8 @@ EXTERN struct proc *kbill_ipc; /* process that invoked ipc */ EXTERN irq_hook_t irq_hooks[NR_IRQ_HOOKS]; /* hooks for general use */ EXTERN int irq_actids[NR_IRQ_VECTORS]; /* IRQ ID bits active */ EXTERN int irq_use; /* map of all in-use irq's */ -EXTERN u32_t system_hz; /* HZ value */ /* Miscellaneous. */ -EXTERN time_t boottime; EXTERN int verboseboot; /* verbose boot, init'ed in cstart */ #if DEBUG_TRACE diff --git a/minix/kernel/main.c b/minix/kernel/main.c index b02b86d5b..58865c59f 100644 --- a/minix/kernel/main.c +++ b/minix/kernel/main.c @@ -410,7 +410,6 @@ void cstart() * determined with help of the environment strings passed by MINIX' loader. */ register char *value; /* value in key=value pair */ - int h; /* low-level initialization */ prot_init(); @@ -419,12 +418,8 @@ void cstart() if ((value = env_get(VERBOSEBOOTVARNAME))) verboseboot = atoi(value); - /* Get clock tick frequency. */ - value = env_get("hz"); - if(value) - system_hz = atoi(value); - if(!value || system_hz < 2 || system_hz > 50000) /* sanity check */ - system_hz = DEFAULT_HZ; + /* Initialize clock variables. */ + init_clock(); /* Get memory parameters. */ value = env_get("ac_layout"); @@ -441,11 +436,6 @@ void cstart() strlcpy(kinfo.release, OS_RELEASE, sizeof(kinfo.release)); strlcpy(kinfo.version, OS_VERSION, sizeof(kinfo.version)); - /* Load average data initialization. */ - kloadinfo.proc_last_slot = 0; - for(h = 0; h < _LOAD_HISTORY; h++) - kloadinfo.proc_load_history[h] = 0; - #ifdef USE_APIC value = env_get("no_apic"); if(value) diff --git a/minix/kernel/proto.h b/minix/kernel/proto.h index d7cf57728..08129f418 100644 --- a/minix/kernel/proto.h +++ b/minix/kernel/proto.h @@ -16,10 +16,13 @@ struct proc; struct ipc_filter_s; /* clock.c */ +void init_clock(void); clock_t get_realtime(void); void set_realtime(clock_t); void set_adjtime_delta(int32_t); clock_t get_monotonic(void); +void set_boottime(time_t); +time_t get_boottime(void); void set_kernel_timer(minix_timer_t *tp, clock_t t, tmr_func_t f); void reset_kernel_timer(minix_timer_t *tp); void ser_dump_proc(void); diff --git a/minix/kernel/system/do_settime.c b/minix/kernel/system/do_settime.c index b57ed8089..198058717 100644 --- a/minix/kernel/system/do_settime.c +++ b/minix/kernel/system/do_settime.c @@ -19,19 +19,23 @@ int do_settime(struct proc * caller, message * m_ptr) { clock_t newclock; int32_t ticks; - time_t timediff, timediff_ticks; + time_t boottime, timediff, timediff_ticks; - if (m_ptr->m_lsys_krn_sys_settime.clock_id != CLOCK_REALTIME) /* only realtime can change */ + /* only realtime can change */ + if (m_ptr->m_lsys_krn_sys_settime.clock_id != CLOCK_REALTIME) return EINVAL; - if (m_ptr->m_lsys_krn_sys_settime.now == 0) { /* user just wants to adjtime() */ + /* user just wants to adjtime() */ + if (m_ptr->m_lsys_krn_sys_settime.now == 0) { /* convert delta value from seconds and nseconds to ticks */ ticks = (m_ptr->m_lsys_krn_sys_settime.sec * system_hz) + - (m_ptr->m_lsys_krn_sys_settime.nsec/(1000000000/system_hz)); + (m_ptr->m_lsys_krn_sys_settime.nsec/(1000000000/system_hz)); set_adjtime_delta(ticks); return(OK); } /* else user wants to set the time */ + boottime = get_boottime(); + timediff = m_ptr->m_lsys_krn_sys_settime.sec - boottime; timediff_ticks = timediff * system_hz; @@ -39,7 +43,7 @@ int do_settime(struct proc * caller, message * m_ptr) if (m_ptr->m_lsys_krn_sys_settime.sec <= boottime || timediff_ticks < LONG_MIN/2 || timediff_ticks > LONG_MAX/2) { /* boottime was likely wrong, try to correct it. */ - boottime = m_ptr->m_lsys_krn_sys_settime.sec; + set_boottime(m_ptr->m_lsys_krn_sys_settime.sec); set_realtime(1); return(OK); } diff --git a/minix/kernel/system/do_stime.c b/minix/kernel/system/do_stime.c index 2347f3652..8a5ae929c 100644 --- a/minix/kernel/system/do_stime.c +++ b/minix/kernel/system/do_stime.c @@ -14,6 +14,6 @@ *===========================================================================*/ int do_stime(struct proc * caller, message * m_ptr) { - boottime = m_ptr->m_lsys_krn_sys_stime.boot_time; + set_boottime(m_ptr->m_lsys_krn_sys_stime.boot_time); return(OK); } diff --git a/minix/kernel/system/do_times.c b/minix/kernel/system/do_times.c index 3a8c0d5d3..d2bac1b73 100644 --- a/minix/kernel/system/do_times.c +++ b/minix/kernel/system/do_times.c @@ -39,7 +39,7 @@ int do_times(struct proc * caller, message * m_ptr) } m_ptr->m_krn_lsys_sys_times.boot_ticks = get_monotonic(); m_ptr->m_krn_lsys_sys_times.real_ticks = get_realtime(); - m_ptr->m_krn_lsys_sys_times.boot_time = boottime; + m_ptr->m_krn_lsys_sys_times.boot_time = get_boottime(); return(OK); } diff --git a/minix/kernel/usermapped_data.c b/minix/kernel/usermapped_data.c index 4ee09f622..d3862ad1c 100644 --- a/minix/kernel/usermapped_data.c +++ b/minix/kernel/usermapped_data.c @@ -8,4 +8,4 @@ struct kinfo kinfo __section(".usermapped"); /* kernel information for users */ struct machine machine __section(".usermapped"); /* machine information for users */ struct kmessages kmessages __section(".usermapped"); /* diagnostic messages in kernel */ struct loadinfo loadinfo __section(".usermapped"); /* status of load average */ - +struct kclockinfo kclockinfo __section(".usermapped"); /* clock information */ diff --git a/minix/lib/libddekit/src/timer.c b/minix/lib/libddekit/src/timer.c index da75b2347..631b920fd 100644 --- a/minix/lib/libddekit/src/timer.c +++ b/minix/lib/libddekit/src/timer.c @@ -43,7 +43,6 @@ static ddekit_lock_t lock; static void lock_timer(void); static void unlock_timer(void); -static clock_t get_current_clock(void); static void remove_timer(int id); static int insert_timer(struct ddekit_timer_s *t); static struct ddekit_timer_s * get_next( myclock_t exp ); @@ -69,17 +68,6 @@ static void unlock_timer() ddekit_lock_unlock(&lock); } -/***************************************************************************** - * get_current_clock * - ****************************************************************************/ -static myclock_t get_current_clock() -{ - /* returns the current clock tick */ - myclock_t ret; - getticks(&ret); - return ret; -} - /***************************************************************************** * remove_timer * ****************************************************************************/ @@ -251,7 +239,7 @@ void ddekit_init_timers(void) if (!first_time) { ddekit_lock_init(&lock); - jiffies = get_current_clock(); + jiffies = getticks(); HZ = sys_hz(); pending_timer_ints = ddekit_sem_init(0); th = ddekit_thread_create(ddekit_timer_thread, 0, "timer"); @@ -277,7 +265,7 @@ ddekit_thread_t *ddekit_get_timer_thread(void) ****************************************************************************/ void _ddekit_timer_interrupt(void) { - jiffies = get_current_clock(); + jiffies = getticks(); DDEBUG_MSG_VERBOSE("now: %d", jiffies); ddekit_sem_up(pending_timer_ints); } diff --git a/minix/lib/liblwip/sys_arch.c b/minix/lib/liblwip/sys_arch.c index c197efc10..197447ad3 100644 --- a/minix/lib/liblwip/sys_arch.c +++ b/minix/lib/liblwip/sys_arch.c @@ -6,12 +6,7 @@ u32_t sys_jiffies(void) { - clock_t ticks; - - if (getticks(&ticks) == OK) - return ticks; - else - panic("getuptime() failed\n"); + return getticks(); } u32_t sys_now(void) diff --git a/minix/lib/libsys/arch/earm/spin.c b/minix/lib/libsys/arch/earm/spin.c index 967f2a68d..e65816647 100644 --- a/minix/lib/libsys/arch/earm/spin.c +++ b/minix/lib/libsys/arch/earm/spin.c @@ -70,14 +70,14 @@ int spin_check(spin_t *s) if (micro_delta >= TSC_SPIN) { s->s_usecs -= micro_delta; - getticks(&s->s_base_uptime); + s->s_base_uptime = getticks(); s->s_state = STATE_UPTIME; } break; case STATE_UPTIME: - getticks(&now); + now = getticks(); /* We assume that sys_hz() caches its return value. */ micro_delta = ((now - s->s_base_uptime) * 1000 / sys_hz()) * diff --git a/minix/lib/libsys/arch/i386/spin.c b/minix/lib/libsys/arch/i386/spin.c index e379d8bdf..57a00018f 100644 --- a/minix/lib/libsys/arch/i386/spin.c +++ b/minix/lib/libsys/arch/i386/spin.c @@ -72,14 +72,14 @@ int spin_check(spin_t *s) if (micro_delta >= TSC_SPIN) { s->s_usecs -= micro_delta; - getticks(&s->s_base_uptime); + s->s_base_uptime = getticks(); s->s_state = STATE_UPTIME; } break; case STATE_UPTIME: - getticks(&now); + now = getticks(); /* We assume that sys_hz() caches its return value. */ micro_delta = ((now - s->s_base_uptime) * 1000 / sys_hz()) * diff --git a/minix/lib/libsys/clock_time.c b/minix/lib/libsys/clock_time.c index 2bea82f96..80c82e560 100644 --- a/minix/lib/libsys/clock_time.c +++ b/minix/lib/libsys/clock_time.c @@ -12,15 +12,17 @@ time_t clock_time(struct timespec *tv) { + struct minix_kerninfo *minix_kerninfo; uint32_t system_hz; - clock_t uptime, realtime; + clock_t realtime; time_t boottime, sec; - int r; - if ((r = getuptime(&uptime, &realtime, &boottime)) != OK) - panic("clock_time: getuptime failed: %d", r); + minix_kerninfo = get_minix_kerninfo(); - system_hz = sys_hz(); /* sys_hz() caches its return value */ + /* We assume atomic 32-bit field retrieval. TODO: 64-bit support. */ + boottime = minix_kerninfo->kclockinfo->boottime; + realtime = minix_kerninfo->kclockinfo->realtime; + system_hz = minix_kerninfo->kclockinfo->hz; sec = boottime + realtime / system_hz; diff --git a/minix/lib/libsys/getticks.c b/minix/lib/libsys/getticks.c index 873716b33..af0b11dad 100644 --- a/minix/lib/libsys/getticks.c +++ b/minix/lib/libsys/getticks.c @@ -1,17 +1,13 @@ #include "sysutil.h" -/*===========================================================================* - * getuptime * - *===========================================================================*/ -int getticks(ticks) -clock_t *ticks; /* monotonic time in ticks */ +/* + * Return the number of clock ticks since system boot. Note that the value may + * wrap on overflow. + */ +clock_t +getticks(void) { - message m; - int s; - m.m_type = SYS_TIMES; /* request time information */ - m.m_lsys_krn_sys_times.endpt = NONE; /* ignore process times */ - s = _kernel_call(SYS_TIMES, &m); - *ticks = m.m_krn_lsys_sys_times.boot_ticks; - return(s); + /* We assume atomic 32-bit field retrieval. TODO: 64-bit support. */ + return get_minix_kerninfo()->kclockinfo->uptime; } diff --git a/minix/lib/libsys/getuptime.c b/minix/lib/libsys/getuptime.c index 0a977997c..6b7f68770 100644 --- a/minix/lib/libsys/getuptime.c +++ b/minix/lib/libsys/getuptime.c @@ -1,21 +1,21 @@ #include "sysutil.h" -/*===========================================================================* - * getuptime * - *===========================================================================*/ -int getuptime(ticks, realtime, boottime) -clock_t *ticks; /* monotonic time in ticks */ -clock_t *realtime; /* wall time in ticks */ -time_t *boottime; +/* + * Retrieve the system's uptime (number of clock ticks since system boot), + * real time (corrected number of clock ticks since system boot), and + * boot time (in number of seconds since the UNIX epoch). + */ +int +getuptime(clock_t * uptime, clock_t * realtime, time_t * boottime) { - message m; - int s; + struct minix_kerninfo *minix_kerninfo; - m.m_type = SYS_TIMES; /* request time information */ - m.m_lsys_krn_sys_times.endpt = NONE; /* ignore process times */ - s = _kernel_call(SYS_TIMES, &m); - *ticks = m.m_krn_lsys_sys_times.boot_ticks; - *realtime = m.m_krn_lsys_sys_times.real_ticks; - *boottime = m.m_krn_lsys_sys_times.boot_time; - return(s); + minix_kerninfo = get_minix_kerninfo(); + + /* We assume atomic 32-bit field retrieval. TODO: 64-bit support. */ + *uptime = minix_kerninfo->kclockinfo->uptime; + *realtime = minix_kerninfo->kclockinfo->realtime; + *boottime = minix_kerninfo->kclockinfo->boottime; + + return OK; } diff --git a/minix/lib/libsys/sef.c b/minix/lib/libsys/sef.c index b575804d8..0c5938939 100644 --- a/minix/lib/libsys/sef.c +++ b/minix/lib/libsys/sef.c @@ -302,9 +302,7 @@ void sef_cancel(void) *===========================================================================*/ int sef_getrndseed(void) { - clock_t uptime; - sys_times(SELF, NULL, NULL, &uptime, NULL); - return (int) uptime; + return (int)getticks(); } /*===========================================================================* diff --git a/minix/lib/libsys/timers.c b/minix/lib/libsys/timers.c index 178286fba..c66f485f9 100644 --- a/minix/lib/libsys/timers.c +++ b/minix/lib/libsys/timers.c @@ -31,15 +31,12 @@ void init_timer(minix_timer_t *tp) *===========================================================================*/ void set_timer(minix_timer_t *tp, int ticks, tmr_func_t watchdog, int arg) { - int r; - clock_t now, prev_time = 0, next_time; - - if ((r = getticks(&now)) != OK) - panic("set_timer: couldn't get uptime"); + clock_t prev_time = 0, next_time; /* Set timer argument and add timer to the list. */ tmr_arg(tp)->ta_int = arg; - prev_time = tmrs_settimer(&timers, tp, now+ticks, watchdog, &next_time); + prev_time = tmrs_settimer(&timers, tp, getticks() + ticks, watchdog, + &next_time); /* Reschedule our synchronous alarm if necessary. */ if (expiring == 0 && (! prev_time || prev_time > next_time)) { diff --git a/minix/net/inet/clock.c b/minix/net/inet/clock.c index fa51929db..d7d98b70a 100644 --- a/minix/net/inet/clock.c +++ b/minix/net/inet/clock.c @@ -35,9 +35,8 @@ time_t get_time() { if (!curr_time) { - if (getticks(&curr_time) != OK) - ip_panic(("can't read clock")); - assert(curr_time >= prev_time); + curr_time = getticks(); + assert(curr_time >= prev_time); /* XXX */ } return curr_time; } diff --git a/minix/servers/is/dmp_pm.c b/minix/servers/is/dmp_pm.c index 596c78095..a2c9d15fb 100644 --- a/minix/servers/is/dmp_pm.c +++ b/minix/servers/is/dmp_pm.c @@ -81,7 +81,7 @@ void sigaction_dmp() printf("Error obtaining table from PM. Perhaps recompile IS?\n"); return; } - getticks(&uptime); + uptime = getticks(); printf("Process manager (PM) signal action dump\n"); printf("-process- -nr- --ignore- --catch- --block- -pending- -alarm---\n"); diff --git a/minix/servers/pm/alarm.c b/minix/servers/pm/alarm.c index d496e9db2..746e8eb82 100644 --- a/minix/servers/pm/alarm.c +++ b/minix/servers/pm/alarm.c @@ -252,12 +252,10 @@ struct itimerval *value; clock_t exptime; /* time at which alarm will expire */ clock_t uptime; /* current system time */ clock_t remaining; /* time left on alarm */ - int s; /* First determine remaining time, in ticks, of previous alarm, if set. */ if (rmp->mp_flags & ALARM_ON) { - if ( (s = getticks(&uptime)) != OK) - panic("get_realtimer couldn't get uptime: %d", s); + uptime = getticks(); exptime = *tmr_exp_time(&rmp->mp_timer); remaining = exptime - uptime; diff --git a/minix/servers/rs/main.c b/minix/servers/rs/main.c index 4f8ee4d3f..5fb6f8ec2 100644 --- a/minix/servers/rs/main.c +++ b/minix/servers/rs/main.c @@ -329,7 +329,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) rp->r_next_rp = NULL; /* no next replica yet */ rp->r_uid = 0; /* root */ rp->r_check_tm = 0; /* not checked yet */ - getticks(&rp->r_alive_tm); /* currently alive */ + rp->r_alive_tm = getticks(); /* currently alive */ rp->r_stop_tm = 0; /* not exiting yet */ rp->r_asr_count = 0; /* no ASR updates yet */ rp->r_restarts = 0; /* no restarts so far */ @@ -815,7 +815,7 @@ endpoint_t endpoint; /* Mark the slot as no longer initializing. */ rp->r_flags &= ~RS_INITIALIZING; rp->r_check_tm = 0; - getticks(&rp->r_alive_tm); + rp->r_alive_tm = getticks(); } /*===========================================================================* diff --git a/minix/servers/rs/manager.c b/minix/servers/rs/manager.c index 218074a75..2ff1c6b0b 100644 --- a/minix/servers/rs/manager.c +++ b/minix/servers/rs/manager.c @@ -601,7 +601,7 @@ struct rproc *rp; rpub->endpoint = child_proc_nr_e; /* set child endpoint */ rp->r_pid = child_pid; /* set child pid */ rp->r_check_tm = 0; /* not checked yet */ - getticks(&rp->r_alive_tm); /* currently alive */ + rp->r_alive_tm = getticks(); /* currently alive */ rp->r_stop_tm = 0; /* not exiting yet */ rp->r_backoff = 0; /* not to be restarted */ rproc_ptr[child_proc_nr_n] = rp; /* mapping for fast access */ @@ -1014,7 +1014,7 @@ void stop_service(struct rproc *rp,int how) rp->r_flags |= how; /* what to on exit? */ sys_kill(rpub->endpoint, signo); /* first try friendly */ - getticks(&rp->r_stop_tm); /* record current time */ + rp->r_stop_tm = getticks(); /* record current time */ } /*===========================================================================* diff --git a/minix/servers/rs/request.c b/minix/servers/rs/request.c index 2163c0b07..e022bcde0 100644 --- a/minix/servers/rs/request.c +++ b/minix/servers/rs/request.c @@ -508,7 +508,7 @@ int do_init_ready(message *m_ptr) /* Mark the slot as no longer initializing. */ rp->r_flags &= ~RS_INITIALIZING; rp->r_check_tm = 0; - getticks(&rp->r_alive_tm); + rp->r_alive_tm = getticks(); /* Reply and unblock the service before doing anything else. */ m.m_type = OK; @@ -842,7 +842,7 @@ int do_update(message *m_ptr) /* Fill the new update descriptor and add it to the update chain. */ rpupd->prepare_state = prepare_state; rpupd->state_endpoint = state_endpoint; - getticks(&rpupd->prepare_tm); + rpupd->prepare_tm = getticks(); rpupd->prepare_maxtime = prepare_maxtime; rupdate_add_upd(rpupd); diff --git a/minix/servers/rs/update.c b/minix/servers/rs/update.c index 8d75fac34..be93ce8c4 100644 --- a/minix/servers/rs/update.c +++ b/minix/servers/rs/update.c @@ -194,7 +194,7 @@ void request_prepare_update_service_debug(char *file, int line, if(state != SEF_LU_STATE_NULL) { struct rprocupd *rpupd = &rp->r_upd; - getticks(&rpupd->prepare_tm); + rpupd->prepare_tm = getticks(); if(!UPD_IS_PREPARING_ONLY(rpupd)) { assert(rp->r_new_rp); rp->r_flags |= RS_UPDATING; @@ -965,7 +965,7 @@ void end_srv_update(struct rprocupd *rpupd, int result, int reply_flag) exiting_rp = (result == OK ? old_rp : new_rp); surviving_rp->r_flags &= ~RS_INITIALIZING; surviving_rp->r_check_tm = 0; - getticks(&surviving_rp->r_alive_tm); + surviving_rp->r_alive_tm = getticks(); /* Keep track of the surviving process in the update descriptor from now on. */ rpupd->rp = surviving_rp; diff --git a/minix/servers/rs/utility.c b/minix/servers/rs/utility.c index 8f109e121..812d9be48 100644 --- a/minix/servers/rs/utility.c +++ b/minix/servers/rs/utility.c @@ -22,7 +22,7 @@ int init_service(struct rproc *rp, int type, int flags) endpoint_t old_endpoint; rp->r_flags |= RS_INITIALIZING; /* now initializing */ - getticks(&rp->r_alive_tm); + rp->r_alive_tm = getticks(); rp->r_check_tm = rp->r_alive_tm + 1; /* expect reply within period */ /* In case of RS initialization, we are done. */ diff --git a/minix/tests/blocktest/blocktest.c b/minix/tests/blocktest/blocktest.c index 5935a2b2f..136bbefa6 100644 --- a/minix/tests/blocktest/blocktest.c +++ b/minix/tests/blocktest/blocktest.c @@ -2674,8 +2674,6 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) { /* Initialize. */ - int r; - clock_t now; if (env_argc > 1) optset_parse(optset_table, env_argv[1]); @@ -2689,10 +2687,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) if (driver_minor > 255) panic("invalid or no driver minor given"); - if ((r = getticks(&now)) != OK) - panic("unable to get uptime: %d", r); - - srand48(now); + srand48(getticks()); output("BLOCKTEST: driver label '%s' (endpt %d), minor %d\n", driver_label, driver_endpt, driver_minor);