From d91f738bd8d93aa6befa2a8d07581040607a512a Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Mon, 21 Sep 2015 13:07:55 +0000 Subject: [PATCH] Kernel: export clock information on kernel page Please note that this information is for use by system services only! The clock facility is not ready to be used directly by userland, and thus, this kernel page extension is NOT part of the userland ABI. For service programmers' convenience, change the prototype of the getticks(3) to return the uptime clock value directly, since the call can no longer fail. Correct the sys_times(2) reply message to use the right field type for the boot time. Restructure the kernel internals a bit so as to have all the clock stuff closer together. Change-Id: Ifc050b7bd253aecbe46e3bd7d7cc75bd86e45555 --- minix/drivers/net/dpeth/3c501.c | 4 +- minix/drivers/net/dpeth/3c509.c | 4 +- minix/drivers/storage/fbd/fbd.c | 10 +-- minix/drivers/storage/filter/util.c | 4 +- minix/fs/procfs/root.c | 5 +- minix/fs/procfs/tree.c | 4 +- minix/include/minix/ipc.h | 4 +- minix/include/minix/sysutil.h | 2 +- minix/include/minix/type.h | 30 ++++++-- minix/kernel/arch/earm/memory.c | 1 + minix/kernel/arch/i386/memory.c | 1 + minix/kernel/clock.c | 103 ++++++++++++++++------------ minix/kernel/glo.h | 5 +- minix/kernel/main.c | 14 +--- minix/kernel/proto.h | 3 + minix/kernel/system/do_settime.c | 14 ++-- minix/kernel/system/do_stime.c | 2 +- minix/kernel/system/do_times.c | 2 +- minix/kernel/usermapped_data.c | 2 +- minix/lib/libddekit/src/timer.c | 16 +---- minix/lib/liblwip/sys_arch.c | 7 +- minix/lib/libsys/arch/earm/spin.c | 4 +- minix/lib/libsys/arch/i386/spin.c | 4 +- minix/lib/libsys/clock_time.c | 12 ++-- minix/lib/libsys/getticks.c | 20 +++--- minix/lib/libsys/getuptime.c | 32 ++++----- minix/lib/libsys/sef.c | 4 +- minix/lib/libsys/timers.c | 9 +-- minix/net/inet/clock.c | 5 +- minix/servers/is/dmp_pm.c | 2 +- minix/servers/pm/alarm.c | 4 +- minix/servers/rs/main.c | 4 +- minix/servers/rs/manager.c | 4 +- minix/servers/rs/request.c | 4 +- minix/servers/rs/update.c | 4 +- minix/servers/rs/utility.c | 2 +- minix/tests/blocktest/blocktest.c | 7 +- 37 files changed, 175 insertions(+), 183 deletions(-) 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 ((r = getticks(&uptime)) != OK) - panic("getuptime failed (%d)\n", r); + if (fbd_buf == NULL) + panic("unable to allocate buffer"); - 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); -- 2.44.0