]> Zhao Yanbai Git Server - minix.git/commitdiff
Kernel: export clock information on kernel page 77/3177/2
authorDavid van Moolenbroek <david@minix3.org>
Mon, 21 Sep 2015 13:07:55 +0000 (13:07 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 23 Sep 2015 12:00:46 +0000 (12:00 +0000)
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

37 files changed:
minix/drivers/net/dpeth/3c501.c
minix/drivers/net/dpeth/3c509.c
minix/drivers/storage/fbd/fbd.c
minix/drivers/storage/filter/util.c
minix/fs/procfs/root.c
minix/fs/procfs/tree.c
minix/include/minix/ipc.h
minix/include/minix/sysutil.h
minix/include/minix/type.h
minix/kernel/arch/earm/memory.c
minix/kernel/arch/i386/memory.c
minix/kernel/clock.c
minix/kernel/glo.h
minix/kernel/main.c
minix/kernel/proto.h
minix/kernel/system/do_settime.c
minix/kernel/system/do_stime.c
minix/kernel/system/do_times.c
minix/kernel/usermapped_data.c
minix/lib/libddekit/src/timer.c
minix/lib/liblwip/sys_arch.c
minix/lib/libsys/arch/earm/spin.c
minix/lib/libsys/arch/i386/spin.c
minix/lib/libsys/clock_time.c
minix/lib/libsys/getticks.c
minix/lib/libsys/getuptime.c
minix/lib/libsys/sef.c
minix/lib/libsys/timers.c
minix/net/inet/clock.c
minix/servers/is/dmp_pm.c
minix/servers/pm/alarm.c
minix/servers/rs/main.c
minix/servers/rs/manager.c
minix/servers/rs/request.c
minix/servers/rs/update.c
minix/servers/rs/utility.c
minix/tests/blocktest/blocktest.c

index d74600279d14b5d0673c220262b2b9b87a0b18ad..2fd87e5f36d32706ed35cb4dcd852b1d580dfda9 100644 (file)
@@ -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;
 }
index d1b6dc4c2029c2be78e4b4f4c3a7578c608a9516..debcb2f2cbc496878c334b6494986f5489bede71 100644 (file)
@@ -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 */
index ee216b663637e9619e71c629559daa0491222511..9861d3b2101298c42c84e6bc6faa471027a6db23 100644 (file)
@@ -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);
index ff33f5c3bc1aac52d66f6de13127843f5c73971b..474783ceabb2fc56020389b713d0e02e7743890e 100644 (file)
@@ -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;
index 83aec45d6f3a4d7c450faecedda9794160b407b0..b753077890bd826e4996138d77bb9a755ee9f6ce 100644 (file)
@@ -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);
 }
index 4e859c71f262c8a145a7058e3278805042be1583..d6a673aecc943669bf6075be0c419cfc825736b4 100644 (file)
@@ -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();
index 9e2eeff4217443f9290fb65f12481fbbf2035723..068d43d201e5525d72f7f0cd4ee0e9670c374801 100644 (file)
@@ -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);
 
index 45a7560442aca97ead0fe6a44b52c090242a49e5..9d561cadd0a0b36114e23a6034b7b5a13d9c134e 100644 (file)
@@ -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);
index 88cb3d705fe4a081f2427b0127d0cccbf71ad2fb..599e2a86a97dba0830e6883454ac77905b9fb2a3 100644 (file)
@@ -2,6 +2,7 @@
 #define _TYPE_H
 
 #include <sys/types.h>
+#include <sys/endian.h>
 
 #include <machine/multiboot.h>
 
@@ -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)
index 743886a330a157ffa90d4c26229458df2a9b976c..acc3a8257277685d9c6684e57e73b2e2e5164362 100644 (file)
@@ -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
index 57ca4ce9c89c8f99da142b0bf9c5a099a2a856b3..cabd73ff9ef6123d6e5427aeebc5dd62907f52d0 100644 (file)
@@ -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) {
index 0c71d701cdae9163fcd83bd30aaddc3ed881525a..00c3da83418e5df6fbbf729113ceeca579833bb2 100644 (file)
@@ -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)
  *   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 <minix/endpoint.h>
+#include <stdlib.h>
+#include <string.h>
 #include <assert.h>
 
 #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)
index ace161e9fb8a3a6fc469628b95f03b73ff772235..666655387b3eded73ebb02968464dcc11f344000 100644 (file)
@@ -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
index b02b86d5b314687e5fc44b1d60d6a0588522096c..58865c59f2fcdbe455cd7eb3acf17e27919a0713 100644 (file)
@@ -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)
index d7cf57728f37ab82797059b0ee5c7c9419a95a86..08129f41830b9a37b6bc497432bd893964bb28ff 100644 (file)
@@ -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);
index b57ed8089d044afe728802cf15dbd0fcb775be16..19805871794835e30cb4adcc35bef908433d4c54 100644 (file)
@@ -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);
   }
index 2347f365234196a957e53e116e9f1542ab5be8ea..8a5ae929c7938fece1b8f790079634ec7269dd41 100644 (file)
@@ -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);
 }
index 3a8c0d5d3c1c22551f2d6d7ed270a0272ee2a8be..d2bac1b73e5cbee5498da5c6fc7a6aed7f9e3edd 100644 (file)
@@ -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);
 }
 
index 4ee09f6221051e321bb6980e9e0518bba1f1da77..d3862ad1c6b90b033a809a5c9a6fabe3401b0641 100644 (file)
@@ -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 */
index da75b2347f5f28f3a70215aacaa0b191e7d88880..631b920fd264f48953bc86d004c9773eb31c41da 100644 (file)
@@ -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);
 }
index c197efc105a619a0523e58c60c0443b49fafb4bf..197447ad3136627f6402e937c242b1de938c3f64 100644 (file)
@@ -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)
index 967f2a68dc2157d5360ea00caff14677e218a3dc..e658166475fe5f6a25c94f876ebf4af21b22d13b 100644 (file)
@@ -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()) *
index e379d8bdfe82cbb1befc2f22b9cce719626bbc01..57a00018f856f00e69380ca254976016b412aa8d 100644 (file)
@@ -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()) *
index 2bea82f969fe82cf34c563e9d487c95434b700ad..80c82e560f723264c7b9956ecc54e18b1093fa5a 100644 (file)
 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;
 
index 873716b3327de672fd22338170d1993f5427bb2c..af0b11dad3e0930d4527caf19893c11bba5d3dab 100644 (file)
@@ -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;
 }
index 0a977997c9df0d19aba8a326788077e359f91801..6b7f687704a12114e2ce162fc2cbcdace9b3c860 100644 (file)
@@ -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;
 }
index b575804d8c91fb123b80d284c298ae324d61d3e9..0c593893972675c095c1d440305dd631eb2b3223 100644 (file)
@@ -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();
 }
 
 /*===========================================================================*
index 178286fba81449dce54a852e8e9d2c0306da6954..c66f485f9b75051a33a925b302cde757ea852356 100644 (file)
@@ -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)) {
index fa51929dbf3ebe3182779d8765fc62665bc4c12c..d7d98b70a487407de5eb83bdcb269c6cf5c67490 100644 (file)
@@ -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;
 }
index 596c780951281f37a33a6d52e511d5f5b336ed84..a2c9d15fb6ea13523a91fe2a7b605c1dc0f82bb2 100644 (file)
@@ -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");
index d496e9db2421a0fadc056c6af12f2fc1b5d9f050..746e8eb82d541d8467727128201e0a719f281895 100644 (file)
@@ -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;
index 4f8ee4d3f90bdcf7a5d9cf59282d05be28401d8d..5fb6f8ec2e3f47d24eacbae9efa217ee9e7acd11 100644 (file)
@@ -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();
 }
 
 /*===========================================================================*
index 218074a755c85f50b2e9f187a4e063b320404514..2ff1c6b0b84e0b9632897aec5ae2bcc3ceaf82d6 100644 (file)
@@ -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 */
 }
 
 /*===========================================================================*
index 2163c0b07f5feaee6b4e709144309201333d7fd3..e022bcde0c3c4f7f1fbf8594498c72d963f8f418 100644 (file)
@@ -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);
 
index 8d75fac341e65385a69a66a9dad8ebc31dc78a21..be93ce8c49143a77703ec9f18d20d61478f28524 100644 (file)
@@ -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;
index 8f109e121974737a41fbfd822354f3cd17a43c96..812d9be48fe38525667ad2eb30ae0585f878f462 100644 (file)
@@ -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. */
index 5935a2b2f32892e21e733950cc2719feac08dd8f..136bbefa6838dc445ea96da1e13c381c0e5acf84 100644 (file)
@@ -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);