libc: add clock_getres()/clock_gettime() system calls.

In order to make it more clear that ticks should be used for timers
and realtime should be used for timestamps / displaying the date/time,
getuptime() was renamed to getticks() and getuptime2() was renamed to
getuptime().

Servers, drivers, libraries, tests, etc that use getuptime()/getuptime2()
have been updated. In instances where a realtime was calculated, the
calculation was changed to use realtime.

System calls clock_getres() and clock_gettime() were added to PM/libc.
This commit is contained in:
Thomas Cort 2013-03-29 21:48:22 +00:00 committed by Ben Gras
parent 5142b1f388
commit e67fc5771d
44 changed files with 182 additions and 62 deletions

View file

@ -169,7 +169,7 @@ static void el1_send(dpeth_t * dep, int from_int, int pktsize)
if ((dep->de_flags & DEF_XMIT_BUSY)) {
if (from_int) panic("should not be sending ");
getuptime(&now);
getticks(&now);
if ((now - dep->de_xmit_start) > 4) {
/* Transmitter timed out */
DEBUG(printf("3c501: transmitter timed out ... \n"));
@ -206,7 +206,7 @@ static void el1_send(dpeth_t * dep, int from_int, int pktsize)
outb_el1(dep, EL1_CSR, ECSR_RIDE | ECSR_XMIT); /* There it goes... */
unlock();
getuptime(&dep->de_xmit_start);
getticks(&dep->de_xmit_start);
dep->de_flags &= NOT(DEF_SENDING);
}
return;

View file

@ -238,7 +238,7 @@ static void el3_send(dpeth_t * dep, int from_int, int count)
int ix;
short int TxStatus;
getuptime(&now);
getticks(&now);
if ((dep->de_flags & DEF_XMIT_BUSY) &&
(now - dep->de_xmit_start) > 4) {
@ -258,7 +258,7 @@ static void el3_send(dpeth_t * dep, int from_int, int count)
/* Writes packet */
el3_write_fifo(dep, count);
getuptime(&dep->de_xmit_start);
getticks(&dep->de_xmit_start);
dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND);
if (inw_el3(dep, REG_TxFree) > ETH_MAX_PACK_SIZE) {
/* Tx has enough room for a packet of maximum size */

View file

@ -83,7 +83,7 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *UNUSED(info))
assert(fbd_buf != NULL);
if ((r = getuptime(&uptime)) != OK)
if ((r = getticks(&uptime)) != OK)
panic("getuptime failed (%d)\n", r);
srand48(uptime);

View file

@ -60,7 +60,7 @@ clock_t flt_alarm(clock_t dt)
} else {
if(next_alarm)
panic("overwriting alarm: %d", r);
if ((r = getuptime(&next_alarm)) != OK)
if ((r = getticks(&next_alarm)) != OK)
panic("getuptime failed: %d", r);
next_alarm += dt;
}

View file

@ -346,7 +346,7 @@ static void or_reset() {
t_or *orp;
int i, r;
if (OK != (r = getuptime(&now)))
if (OK != (r = getticks(&now)))
panic("orinoco: getuptime() failed: %d", r);
if(now - last_reset < system_hz * 10) {

View file

@ -1,4 +1,4 @@
#define NCALLS 114 /* number of system calls allowed */
#define NCALLS 116 /* number of system calls allowed */
/* In case it isn't obvious enough: this list is sorted numerically. */
#define EXIT 1
@ -102,6 +102,8 @@
#define GCOV_FLUSH 112 /* flush gcov data from server to gcov files */
#define PM_GETSID 113 /* PM getsid() */
#define CLOCK_GETRES 114 /* clock_getres() */
#define CLOCK_GETTIME 115 /* clock_gettime() */
#define TASK_REPLY 121 /* to VFS: reply code from drivers, not
* really a standalone call.

View file

@ -488,7 +488,8 @@
#define T_USER_TIME m4_l1 /* user time consumed by process */
#define T_SYSTEM_TIME m4_l2 /* system time consumed by process */
#define T_BOOTTIME m4_l3 /* Boottime in seconds (also for SYS_STIME) */
#define T_BOOT_TICKS m4_l5 /* number of clock ticks since boot time */
#define T_REAL_TICKS m4_l4 /* number of wall clock ticks since boottime */
#define T_BOOT_TICKS m4_l5 /* number of hard clock ticks since boottime */
/* Field names for SYS_TRACE, SYS_PRIVCTL, SYS_STATECTL. */
#define CTL_ENDPT m2_i1 /* process number of the caller */

View file

@ -49,8 +49,8 @@ int fkey_ctl(int req, int *fkeys, int *sfkeys);
int printf(const char *fmt, ...);
void kputc(int c);
__dead void panic(const char *fmt, ...);
int getuptime(clock_t *ticks);
int getuptime2(clock_t *ticks, time_t *boottime);
int getuptime(clock_t *ticks, clock_t *realtime, time_t *boottime);
int getticks(clock_t *ticks);
int tickdelay(clock_t ticks);
int tsc_calibrate(void);
u32_t sys_hz(void);

View file

@ -158,11 +158,11 @@ struct sigevent;
struct itimerspec;
int clock_nanosleep(clockid_t, int, const struct timespec *, struct timespec *);
#ifndef __LIBC12_SOURCE__
#ifndef __minix
int clock_getres(clockid_t, struct timespec *)
__RENAME(__clock_getres50);
int clock_gettime(clockid_t, struct timespec *)
__RENAME(__clock_gettime50);
#ifndef __minix
int clock_settime(clockid_t, const struct timespec *)
__RENAME(__clock_settime50);
#endif /* !__minix */

View file

@ -36,6 +36,7 @@ int do_times(struct proc * caller, message * m_ptr)
m_ptr->T_SYSTEM_TIME = rp->p_sys_time;
}
m_ptr->T_BOOT_TICKS = get_monotonic();
m_ptr->T_REAL_TICKS = get_realtime();
m_ptr->T_BOOTTIME = boottime;
return(OK);
}

View file

@ -4,8 +4,6 @@ adjtime
lchmod
lchown
clone
clock_getres
clock_gettime
clock_settime
extattr_*
fhopen

View file

@ -2,6 +2,7 @@
SRCS+= accept.c access.c bind.c brk.c sbrk.c m_closefrom.c getsid.c \
chdir.c chmod.c fchmod.c chown.c fchown.c chroot.c close.c \
clock_getres.c clock_gettime.c \
connect.c dup.c dup2.c execve.c fcntl.c flock.c fpathconf.c fork.c \
fstatfs.c fstatvfs.c fsync.c ftruncate.c getdents.c getegid.c getgid.c \
getgroups.c getitimer.c setitimer.c __getlogin.c getpeername.c \

View file

@ -0,0 +1,25 @@
#include <sys/cdefs.h>
#include <lib.h>
#include "namespace.h"
#include <sys/time.h>
#ifdef __weak_alias
__weak_alias(clock_getres, __clock_getres50);
#endif
int clock_getres(clockid_t clock_id, struct timespec *res)
{
message m;
m.m2_l1 = (clockid_t) clock_id;
if (_syscall(PM_PROC_NR, CLOCK_GETRES, &m) < 0)
return -1;
res->tv_sec = (time_t) m.m2_l1;
res->tv_nsec = (long) m.m2_l2;
return 0;
}

View file

@ -0,0 +1,25 @@
#include <sys/cdefs.h>
#include <lib.h>
#include "namespace.h"
#include <sys/time.h>
#ifdef __weak_alias
__weak_alias(clock_gettime, __clock_gettime50);
#endif
int clock_gettime(clockid_t clock_id, struct timespec *res)
{
message m;
m.m2_l1 = (clockid_t) clock_id;
if (_syscall(PM_PROC_NR, CLOCK_GETTIME, &m) < 0)
return -1;
res->tv_sec = (time_t) m.m2_l1;
res->tv_nsec = (long) m.m2_l2;
return 0;
}

View file

@ -76,7 +76,7 @@ static myclock_t get_current_clock()
{
/* returns the current clock tick */
myclock_t ret;
getuptime(&ret);
getticks(&ret);
return ret;
}

View file

@ -6,7 +6,7 @@ u32_t sys_jiffies(void)
{
clock_t ticks;
if (getuptime(&ticks) == OK)
if (getticks(&ticks) == OK)
return ticks;
else
panic("getuptime() failed\n");
@ -20,6 +20,7 @@ u32_t sys_now(void)
if (!hz)
hz = sys_hz();
/* use ticks not realtime as sys_now() is used to calculate timers */
jiffs = sys_jiffies();
return jiffs * (1000 / hz);

View file

@ -46,12 +46,13 @@ time_t clock_time()
register int k;
clock_t uptime;
clock_t realtime;
time_t boottime;
if ((k=getuptime2(&uptime, &boottime)) != OK)
if ((k=getuptime(&uptime, &realtime, &boottime)) != OK)
panic("clock_time: getuptme2 failed: %d", k);
return( (time_t) (boottime + (uptime/sys_hz())));
return( (time_t) (boottime + (realtime/sys_hz())));
}

View file

@ -15,9 +15,9 @@ SRCS+= \
env_parse.c \
env_prefix.c \
fkey_ctl.c \
getticks.c \
getsysinfo.c \
getuptime.c \
getuptime2.c \
input.c \
kernel_call.c \
kprintf.c \

View file

@ -70,14 +70,14 @@ int spin_check(spin_t *s)
if (micro_delta >= TSC_SPIN) {
s->s_usecs -= micro_delta;
getuptime(&s->s_base_uptime);
getticks(&s->s_base_uptime);
s->s_state = STATE_UPTIME;
}
break;
case STATE_UPTIME:
getuptime(&now);
getticks(&now);
/* We assume that sys_hz() caches its return value. */
micro_delta = ((now - s->s_base_uptime) * 1000 / sys_hz()) *

View file

@ -72,14 +72,14 @@ int spin_check(spin_t *s)
if (micro_delta >= TSC_SPIN) {
s->s_usecs -= micro_delta;
getuptime(&s->s_base_uptime);
getticks(&s->s_base_uptime);
s->s_state = STATE_UPTIME;
}
break;
case STATE_UPTIME:
getuptime(&now);
getticks(&now);
/* We assume that sys_hz() caches its return value. */
micro_delta = ((now - s->s_base_uptime) * 1000 / sys_hz()) *

View file

@ -1,11 +1,10 @@
#include "sysutil.h"
/*===========================================================================*
* getuptime2 *
* getuptime *
*===========================================================================*/
int getuptime2(ticks, boottime)
clock_t *ticks; /* uptime in ticks */
time_t *boottime;
int getticks(ticks)
clock_t *ticks; /* monotonic time in ticks */
{
message m;
int s;
@ -14,7 +13,6 @@ time_t *boottime;
m.T_ENDPT = NONE; /* ignore process times */
s = _kernel_call(SYS_TIMES, &m);
*ticks = m.T_BOOT_TICKS;
*boottime = m.T_BOOTTIME;
return(s);
}

View file

@ -3,8 +3,10 @@
/*===========================================================================*
* getuptime *
*===========================================================================*/
int getuptime(ticks)
clock_t *ticks; /* uptime in ticks */
int getuptime(ticks, realtime, boottime)
clock_t *ticks; /* monotonic time in ticks */
clock_t *realtime; /* wall time in ticks */
time_t *boottime;
{
message m;
int s;
@ -13,6 +15,8 @@ clock_t *ticks; /* uptime in ticks */
m.T_ENDPT = NONE; /* ignore process times */
s = _kernel_call(SYS_TIMES, &m);
*ticks = m.T_BOOT_TICKS;
*realtime = m.T_REAL_TICKS;
*boottime = m.T_BOOTTIME;
return(s);
}

View file

@ -34,7 +34,7 @@ void set_timer(timer_t *tp, int ticks, tmr_func_t watchdog, int arg)
int r;
clock_t now, prev_time = 0, next_time;
if ((r = getuptime(&now)) != OK)
if ((r = getticks(&now)) != OK)
panic("set_timer: couldn't get uptime");
/* Set timer argument and add timer to the list. */

View file

@ -63,12 +63,13 @@ time_t clock_time()
register int k;
clock_t uptime;
clock_t realtime;
time_t boottime;
if ( (k=getuptime2(&uptime, &boottime)) != OK)
if ( (k=getuptime(&uptime, &realtime, &boottime)) != OK)
panic("clock_time: getuptme2 failed: %d", k);
return( (time_t) (boottime + (uptime/sys_hz())));
return( (time_t) (boottime + (realtime/sys_hz())));
}

View file

@ -35,7 +35,7 @@ time_t get_time()
{
if (!curr_time)
{
if (getuptime(&curr_time) != OK)
if (getticks(&curr_time) != OK)
ip_panic(("can't read clock"));
assert(curr_time >= prev_time);
}

View file

@ -83,7 +83,7 @@ void sigaction_dmp()
printf("Error obtaining table from PM. Perhaps recompile IS?\n");
return;
}
getuptime(&uptime);
getticks(&uptime);
printf("Process manager (PM) signal action dump\n");
printf("-process- -nr- --ignore- --catch- --block- -pending- -alarm---\n");

View file

@ -33,4 +33,3 @@ EXTERN int unmountdone;
EXTERN dev_t fs_dev; /* the device that is handled by this FS proc */
EXTERN char fs_dev_label[16]; /* Name of the device driver that is handled */
EXTERN int use_getuptime2; /* Should be removed togetherwith boottime */

View file

@ -59,12 +59,13 @@ time_t clock_time()
register int k;
clock_t uptime;
clock_t realtime;
time_t boottime;
if ( (k=getuptime2(&uptime, &boottime)) != OK)
if ( (k=getuptime(&uptime, &realtime, &boottime)) != OK)
panic("clock_time: getuptme2 failed: %d", k);
return( (time_t) (boottime + (uptime/sys_hz())));
return( (time_t) (boottime + (realtime/sys_hz())));
}

View file

@ -24,10 +24,11 @@ time_t clock_time()
int r;
clock_t uptime; /* Uptime in ticks */
clock_t realtime;
time_t boottime;
if ((r = getuptime2(&uptime, &boottime)) != OK)
if ((r = getuptime(&uptime, &realtime, &boottime)) != OK)
panic("clock_time: getuptme2 failed: %d", r);
return( (time_t) (boottime + (uptime/sys_hz())));
return( (time_t) (boottime + (realtime/sys_hz())));
}

View file

@ -283,7 +283,7 @@ struct itimerval *value;
/* First determine remaining time, in ticks, of previous alarm, if set. */
if (rmp->mp_flags & ALARM_ON) {
if ( (s = getuptime(&uptime)) != OK)
if ( (s = getticks(&uptime)) != OK)
panic("get_realtimer couldn't get uptime: %d", s);
exptime = *tmr_exp_time(&rmp->mp_timer);

View file

@ -30,6 +30,7 @@
#define svrctl_req m2_i1
#define svrctl_argp m2_p1
#define stime m2_l1
#define clk_id m2_l1
#define memsize m4_l1
#define membase m4_l2
#define sysuname_req m1_i1
@ -46,6 +47,7 @@
#define reply_trace m2_l2
#define reply_time m2_l1
#define reply_utime m2_l2
#define reply_ntime m2_l2
#define reply_t1 m4_l1
#define reply_t2 m4_l2
#define reply_t3 m4_l3

View file

@ -86,6 +86,8 @@ void vm_notify_sig_wrapper(endpoint_t ep);
int do_stime(void);
int do_time(void);
int do_times(void);
int do_getres(void);
int do_gettime(void);
/* trace.c */
int do_trace(void);

View file

@ -125,6 +125,8 @@ int (*call_vec[])(void) = {
do_srv_kill, /* 111 = srv_kill */
no_sys, /* 112 = gcov_flush */
do_get, /* 113 = getsid */
do_getres, /* 114 = clock_getres */
do_gettime, /* 115 = clock_gettime */
};
/* This should not fail with "array size is negative": */
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];

View file

@ -1,6 +1,8 @@
/* This file takes care of those system calls that deal with time.
*
* The entry points into this file are
* do_getres: perform the CLOCK_GETRES system call
* do_gettime: perform the CLOCK_GETTIME system call
* do_time: perform the TIME system call
* do_stime: perform the STIME system call
* do_times: perform the TIMES system call
@ -10,9 +12,56 @@
#include <minix/callnr.h>
#include <minix/com.h>
#include <signal.h>
#include <sys/time.h>
#include "mproc.h"
#include "param.h"
/*===========================================================================*
* do_gettime *
*===========================================================================*/
int do_gettime()
{
clock_t ticks, realtime, clock;
time_t boottime;
int s;
if ( (s=getuptime(&ticks, &realtime, &boottime)) != OK)
panic("do_time couldn't get uptime: %d", s);
switch (m_in.clk_id) {
case CLOCK_REALTIME:
clock = realtime;
break;
case CLOCK_MONOTONIC:
clock = ticks;
break;
default:
return EINVAL; /* invalid/unsupported clock_id */
}
mp->mp_reply.reply_time = (time_t) (boottime + (clock / system_hz));
mp->mp_reply.reply_ntime = (clock % system_hz) * 1000000000 / system_hz;
return(OK);
}
/*===========================================================================*
* do_getres *
*===========================================================================*/
int do_getres()
{
switch (m_in.clk_id) {
case CLOCK_REALTIME:
case CLOCK_MONOTONIC:
/* tv_sec is always 0 since system_hz is an int */
mp->mp_reply.reply_time = (time_t) 0;
mp->mp_reply.reply_ntime = 1000000000 / system_hz;
return(OK);
default:
return EINVAL; /* invalid/unsupported clock_id */
}
}
/*===========================================================================*
* do_time *
*===========================================================================*/
@ -23,14 +72,15 @@ int do_time()
* rotates at a constant rate and that such things as leap seconds do not
* exist.
*/
clock_t uptime, boottime;
clock_t ticks, realtime;
time_t boottime;
int s;
if ( (s=getuptime2(&uptime, &boottime)) != OK)
if ( (s=getuptime(&ticks, &realtime, &boottime)) != OK)
panic("do_time couldn't get uptime: %d", s);
mp->mp_reply.reply_time = (time_t) (boottime + (uptime/system_hz));
mp->mp_reply.reply_utime = (uptime%system_hz)*1000000/system_hz;
mp->mp_reply.reply_time = (time_t) (boottime + (realtime / system_hz));
mp->mp_reply.reply_utime = (realtime % system_hz) * 1000000 / system_hz;
return(OK);
}
@ -42,15 +92,16 @@ int do_stime()
/* Perform the stime(tp) system call. Retrieve the system's uptime (ticks
* since boot) and pass the new time in seconds at system boot to the kernel.
*/
clock_t uptime, boottime;
clock_t uptime, realtime;
time_t boottime;
int s;
if (mp->mp_effuid != SUPER_USER) {
return(EPERM);
}
if ( (s=getuptime(&uptime)) != OK)
if ( (s=getuptime(&uptime, &realtime, &boottime)) != OK)
panic("do_stime couldn't get uptime: %d", s);
boottime = (long) m_in.stime - (uptime/system_hz);
boottime = (long) m_in.stime - (realtime/system_hz);
s= sys_stime(boottime); /* Tell kernel about boottime */
if (s != OK)

View file

@ -81,7 +81,7 @@ static void root_uptime(void)
clock_t ticks;
ldiv_t division;
if (getuptime(&ticks) != OK)
if (getticks(&ticks) != OK)
return;
division = ldiv(100L * ticks / sys_hz(), 100L);

View file

@ -440,7 +440,7 @@ int lookup_hook(struct inode *parent, char *name,
/* Update lazily for lookups, as this gets too expensive otherwise.
* Alternative: pull in only PM's table?
*/
if ((r = getuptime(&now)) != OK)
if ((r = getticks(&now)) != OK)
panic(__FILE__, "unable to get uptime", r);
if (last_update != now) {

View file

@ -328,7 +328,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 */
getuptime(&rp->r_alive_tm); /* currently alive */
getticks(&rp->r_alive_tm); /* currently alive */
rp->r_stop_tm = 0; /* not exiting yet */
rp->r_restarts = 0; /* no restarts so far */
rp->r_period = 0; /* no period yet */
@ -669,7 +669,7 @@ endpoint_t endpoint;
/* Mark the slot as no longer initializing. */
rp->r_flags &= ~RS_INITIALIZING;
rp->r_check_tm = 0;
getuptime(&rp->r_alive_tm);
getticks(&rp->r_alive_tm);
}
/*===========================================================================*

View file

@ -496,7 +496,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 */
getuptime(&rp->r_alive_tm); /* currently alive */
getticks(&rp->r_alive_tm); /* 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 */
@ -867,7 +867,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 */
getuptime(&rp->r_stop_tm); /* record current time */
getticks(&rp->r_stop_tm); /* record current time */
}
/*===========================================================================*

View file

@ -431,7 +431,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;
getuptime(&rp->r_alive_tm);
getticks(&rp->r_alive_tm);
/* Reply and unblock the service before doing anything else. */
m.m_type = OK;
@ -597,7 +597,7 @@ int do_update(message *m_ptr)
rp->r_flags |= RS_UPDATING;
rp->r_new_rp->r_flags |= RS_UPDATING;
rupdate.flags |= RS_UPDATING;
getuptime(&rupdate.prepare_tm);
getticks(&rupdate.prepare_tm);
rupdate.prepare_maxtime = prepare_maxtime;
rupdate.rp = rp;

View file

@ -129,6 +129,8 @@ int (*call_vec[])(void) = {
no_sys, /* 111 = (srv_kill) */
do_gcov_flush, /* 112 = gcov_flush */
no_sys, /* 113 = (getsid) */
no_sys, /* 114 = (clock_getres) */
no_sys, /* 115 = (clock_gettime) */
};
/* This should not fail with "array size is negative": */
extern int dummy[sizeof(call_vec) == NCALLS * sizeof(call_vec[0]) ? 1 : -1];

View file

@ -152,13 +152,14 @@ time_t clock_time()
register int r;
clock_t uptime;
clock_t realtime;
time_t boottime;
r = getuptime2(&uptime, &boottime);
r = getuptime(&uptime, &realtime, &boottime);
if (r != OK)
panic("clock_time err: %d", r);
return( (time_t) (boottime + (uptime/system_hz)));
return( (time_t) (boottime + (realtime/system_hz)));
}
/*===========================================================================*

View file

@ -315,7 +315,7 @@ void blockstats(void)
clock_t ticks;
int s;
s = getuptime(&ticks);
s = getticks(&ticks);
assert(s == OK);

View file

@ -248,11 +248,12 @@ struct itimerspec {
struct timespec it_value;
};
#ifndef __minix
#define CLOCK_REALTIME 0
#define CLOCK_MONOTONIC 3
#ifndef __minix
#define CLOCK_VIRTUAL 1
#define CLOCK_PROF 2
#define CLOCK_MONOTONIC 3
#endif
#if defined(_NETBSD_SOURCE)

View file

@ -2632,7 +2632,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 = getuptime(&now)) != OK)
if ((r = getticks(&now)) != OK)
panic("unable to get uptime: %d", r);
srand48(now);