version 1.90.2.6, 2007/12/07 17:32:52 |
version 1.90.2.7, 2008/01/21 09:46:14 |
Line 79 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 79 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/signalvar.h> |
#include <sys/signalvar.h> |
#include <sys/syslog.h> |
#include <sys/syslog.h> |
#include <sys/timetc.h> |
#include <sys/timetc.h> |
#ifndef __HAVE_TIMECOUNTER |
|
#include <sys/timevar.h> |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
#include <sys/kauth.h> |
#include <sys/kauth.h> |
|
|
#include <sys/mount.h> |
#include <sys/mount.h> |
|
|
settime1(struct proc *p, struct timespec *ts, bool check_kauth) |
settime1(struct proc *p, struct timespec *ts, bool check_kauth) |
{ |
{ |
struct timeval delta, tv; |
struct timeval delta, tv; |
#ifdef __HAVE_TIMECOUNTER |
|
struct timeval now; |
struct timeval now; |
struct timespec ts1; |
struct timespec ts1; |
#endif /* !__HAVE_TIMECOUNTER */ |
struct bintime btdelta; |
lwp_t *l; |
lwp_t *l; |
int s; |
int s; |
|
|
Line 133 settime1(struct proc *p, struct timespec |
|
Line 129 settime1(struct proc *p, struct timespec |
|
|
|
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ |
/* WHAT DO WE DO ABOUT PENDING REAL-TIME TIMEOUTS??? */ |
s = splclock(); |
s = splclock(); |
#ifdef __HAVE_TIMECOUNTER |
|
microtime(&now); |
microtime(&now); |
timersub(&tv, &now, &delta); |
timersub(&tv, &now, &delta); |
#else /* !__HAVE_TIMECOUNTER */ |
|
timersub(&tv, &time, &delta); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
|
|
if (check_kauth && kauth_authorize_system(p->p_cred, KAUTH_SYSTEM_TIME, |
if (check_kauth && kauth_authorize_system(kauth_cred_get(), |
KAUTH_REQ_SYSTEM_TIME_SYSTEM, ts, &delta, |
KAUTH_SYSTEM_TIME, KAUTH_REQ_SYSTEM_TIME_SYSTEM, ts, &delta, |
KAUTH_ARG(check_kauth ? false : true)) != 0) { |
KAUTH_ARG(check_kauth ? false : true)) != 0) { |
splx(s); |
splx(s); |
return (EPERM); |
return (EPERM); |
Line 154 settime1(struct proc *p, struct timespec |
|
Line 146 settime1(struct proc *p, struct timespec |
|
} |
} |
#endif |
#endif |
|
|
#ifdef __HAVE_TIMECOUNTER |
|
TIMEVAL_TO_TIMESPEC(&tv, &ts1); |
TIMEVAL_TO_TIMESPEC(&tv, &ts1); |
tc_setclock(&ts1); |
tc_setclock(&ts1); |
#else /* !__HAVE_TIMECOUNTER */ |
|
time = tv; |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
|
|
timeradd(&boottime, &delta, &boottime); |
timeradd(&boottime, &delta, &boottime); |
|
|
Line 168 settime1(struct proc *p, struct timespec |
|
Line 156 settime1(struct proc *p, struct timespec |
|
* and adjusting LWP's run times. Fixing this properly means |
* and adjusting LWP's run times. Fixing this properly means |
* pausing all CPUs while we adjust the clock. |
* pausing all CPUs while we adjust the clock. |
*/ |
*/ |
|
timeval2bintime(&delta, &btdelta); |
mutex_enter(&proclist_lock); |
mutex_enter(&proclist_lock); |
LIST_FOREACH(l, &alllwp, l_list) { |
LIST_FOREACH(l, &alllwp, l_list) { |
lwp_lock(l); |
lwp_lock(l); |
timeradd(&l->l_stime, &delta, &l->l_stime); |
bintime_add(&l->l_stime, &btdelta); |
lwp_unlock(l); |
lwp_unlock(l); |
} |
} |
mutex_exit(&proclist_lock); |
mutex_exit(&proclist_lock); |
Line 189 settime(struct proc *p, struct timespec |
|
Line 178 settime(struct proc *p, struct timespec |
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_clock_gettime(struct lwp *l, void *v, register_t *retval) |
sys_clock_gettime(struct lwp *l, const struct sys_clock_gettime_args *uap, register_t *retval) |
{ |
{ |
struct sys_clock_gettime_args /* { |
/* { |
syscallarg(clockid_t) clock_id; |
syscallarg(clockid_t) clock_id; |
syscallarg(struct timespec *) tp; |
syscallarg(struct timespec *) tp; |
} */ *uap = v; |
} */ |
clockid_t clock_id; |
clockid_t clock_id; |
struct timespec ats; |
struct timespec ats; |
|
|
Line 215 sys_clock_gettime(struct lwp *l, void *v |
|
Line 204 sys_clock_gettime(struct lwp *l, void *v |
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_clock_settime(struct lwp *l, void *v, register_t *retval) |
sys_clock_settime(struct lwp *l, const struct sys_clock_settime_args *uap, register_t *retval) |
{ |
{ |
struct sys_clock_settime_args /* { |
/* { |
syscallarg(clockid_t) clock_id; |
syscallarg(clockid_t) clock_id; |
syscallarg(const struct timespec *) tp; |
syscallarg(const struct timespec *) tp; |
} */ *uap = v; |
} */ |
|
|
return clock_settime1(l->l_proc, SCARG(uap, clock_id), SCARG(uap, tp), |
return clock_settime1(l->l_proc, SCARG(uap, clock_id), SCARG(uap, tp), |
true); |
true); |
Line 252 clock_settime1(struct proc *p, clockid_t |
|
Line 241 clock_settime1(struct proc *p, clockid_t |
|
} |
} |
|
|
int |
int |
sys_clock_getres(struct lwp *l, void *v, register_t *retval) |
sys_clock_getres(struct lwp *l, const struct sys_clock_getres_args *uap, register_t *retval) |
{ |
{ |
struct sys_clock_getres_args /* { |
/* { |
syscallarg(clockid_t) clock_id; |
syscallarg(clockid_t) clock_id; |
syscallarg(struct timespec *) tp; |
syscallarg(struct timespec *) tp; |
} */ *uap = v; |
} */ |
clockid_t clock_id; |
clockid_t clock_id; |
struct timespec ts; |
struct timespec ts; |
int error = 0; |
int error = 0; |
Line 284 sys_clock_getres(struct lwp *l, void *v, |
|
Line 273 sys_clock_getres(struct lwp *l, void *v, |
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_nanosleep(struct lwp *l, void *v, register_t *retval) |
sys_nanosleep(struct lwp *l, const struct sys_nanosleep_args *uap, register_t *retval) |
{ |
{ |
struct sys_nanosleep_args/* { |
/* { |
syscallarg(struct timespec *) rqtp; |
syscallarg(struct timespec *) rqtp; |
syscallarg(struct timespec *) rmtp; |
syscallarg(struct timespec *) rmtp; |
} */ *uap = v; |
} */ |
struct timespec rmt, rqt; |
struct timespec rmt, rqt; |
int error, error1; |
int error, error1; |
|
|
Line 308 sys_nanosleep(struct lwp *l, void *v, re |
|
Line 297 sys_nanosleep(struct lwp *l, void *v, re |
|
int |
int |
nanosleep1(struct lwp *l, struct timespec *rqt, struct timespec *rmt) |
nanosleep1(struct lwp *l, struct timespec *rqt, struct timespec *rmt) |
{ |
{ |
#ifdef __HAVE_TIMECOUNTER |
|
int error, timo; |
int error, timo; |
|
|
if (itimespecfix(rqt)) |
if (itimespecfix(rqt)) |
Line 342 nanosleep1(struct lwp *l, struct timespe |
|
Line 330 nanosleep1(struct lwp *l, struct timespe |
|
} |
} |
|
|
return error; |
return error; |
#else /* !__HAVE_TIMECOUNTER */ |
|
struct timeval atv, utv; |
|
int error, s, timo; |
|
|
|
TIMESPEC_TO_TIMEVAL(&atv, rqt); |
|
if (itimerfix(&atv)) |
|
return (EINVAL); |
|
|
|
s = splclock(); |
|
timeradd(&atv,&time,&atv); |
|
timo = hzto(&atv); |
|
/* |
|
* Avoid inadvertantly sleeping forever |
|
*/ |
|
if (timo == 0) |
|
timo = 1; |
|
splx(s); |
|
|
|
error = kpause("nanoslp", true, timo, NULL); |
|
if (error == ERESTART) |
|
error = EINTR; |
|
if (error == EWOULDBLOCK) |
|
error = 0; |
|
|
|
if (rmt != NULL) { |
|
s = splclock(); |
|
utv = time; |
|
splx(s); |
|
|
|
timersub(&atv, &utv, &utv); |
|
if (utv.tv_sec < 0) |
|
timerclear(&utv); |
|
|
|
TIMEVAL_TO_TIMESPEC(&utv, rmt); |
|
} |
|
|
|
return error; |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_gettimeofday(struct lwp *l, void *v, register_t *retval) |
sys_gettimeofday(struct lwp *l, const struct sys_gettimeofday_args *uap, register_t *retval) |
{ |
{ |
struct sys_gettimeofday_args /* { |
/* { |
syscallarg(struct timeval *) tp; |
syscallarg(struct timeval *) tp; |
syscallarg(void *) tzp; really "struct timezone *" |
syscallarg(void *) tzp; really "struct timezone *"; |
} */ *uap = v; |
} */ |
struct timeval atv; |
struct timeval atv; |
int error = 0; |
int error = 0; |
struct timezone tzfake; |
struct timezone tzfake; |
Line 414 sys_gettimeofday(struct lwp *l, void *v, |
|
Line 364 sys_gettimeofday(struct lwp *l, void *v, |
|
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_settimeofday(struct lwp *l, void *v, register_t *retval) |
sys_settimeofday(struct lwp *l, const struct sys_settimeofday_args *uap, register_t *retval) |
{ |
{ |
struct sys_settimeofday_args /* { |
/* { |
syscallarg(const struct timeval *) tv; |
syscallarg(const struct timeval *) tv; |
syscallarg(const void *) tzp; really "const struct timezone *" |
syscallarg(const void *) tzp; really "const struct timezone *"; |
} */ *uap = v; |
} */ |
|
|
return settimeofday1(SCARG(uap, tv), true, SCARG(uap, tzp), l, true); |
return settimeofday1(SCARG(uap, tv), true, SCARG(uap, tzp), l, true); |
} |
} |
Line 455 settimeofday1(const struct timeval *utv, |
|
Line 405 settimeofday1(const struct timeval *utv, |
|
return settime1(l->l_proc, &ts, check_kauth); |
return settime1(l->l_proc, &ts, check_kauth); |
} |
} |
|
|
#ifndef __HAVE_TIMECOUNTER |
|
int tickdelta; /* current clock skew, us. per tick */ |
|
long timedelta; /* unapplied time correction, us. */ |
|
long bigadj = 1000000; /* use 10x skew above bigadj us. */ |
|
#endif |
|
|
|
int time_adjusted; /* set if an adjustment is made */ |
int time_adjusted; /* set if an adjustment is made */ |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_adjtime(struct lwp *l, void *v, register_t *retval) |
sys_adjtime(struct lwp *l, const struct sys_adjtime_args *uap, register_t *retval) |
{ |
{ |
struct sys_adjtime_args /* { |
/* { |
syscallarg(const struct timeval *) delta; |
syscallarg(const struct timeval *) delta; |
syscallarg(struct timeval *) olddelta; |
syscallarg(struct timeval *) olddelta; |
} */ *uap = v; |
} */ |
int error; |
int error; |
|
|
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, |
if ((error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_TIME, |
Line 486 adjtime1(const struct timeval *delta, st |
|
Line 430 adjtime1(const struct timeval *delta, st |
|
struct timeval atv; |
struct timeval atv; |
int error = 0; |
int error = 0; |
|
|
#ifdef __HAVE_TIMECOUNTER |
|
extern int64_t time_adjtime; /* in kern_ntptime.c */ |
extern int64_t time_adjtime; /* in kern_ntptime.c */ |
#else /* !__HAVE_TIMECOUNTER */ |
|
long ndelta, ntickdelta, odelta; |
|
int s; |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
|
|
#ifdef __HAVE_TIMECOUNTER |
|
if (olddelta) { |
if (olddelta) { |
atv.tv_sec = time_adjtime / 1000000; |
atv.tv_sec = time_adjtime / 1000000; |
atv.tv_usec = time_adjtime % 1000000; |
atv.tv_usec = time_adjtime % 1000000; |
Line 518 adjtime1(const struct timeval *delta, st |
|
Line 456 adjtime1(const struct timeval *delta, st |
|
/* We need to save the system time during shutdown */ |
/* We need to save the system time during shutdown */ |
time_adjusted |= 1; |
time_adjusted |= 1; |
} |
} |
#else /* !__HAVE_TIMECOUNTER */ |
|
error = copyin(delta, &atv, sizeof(struct timeval)); |
|
if (error) |
|
return (error); |
|
|
|
/* |
|
* Compute the total correction and the rate at which to apply it. |
|
* Round the adjustment down to a whole multiple of the per-tick |
|
* delta, so that after some number of incremental changes in |
|
* hardclock(), tickdelta will become zero, lest the correction |
|
* overshoot and start taking us away from the desired final time. |
|
*/ |
|
ndelta = atv.tv_sec * 1000000 + atv.tv_usec; |
|
if (ndelta > bigadj || ndelta < -bigadj) |
|
ntickdelta = 10 * tickadj; |
|
else |
|
ntickdelta = tickadj; |
|
if (ndelta % ntickdelta) |
|
ndelta = ndelta / ntickdelta * ntickdelta; |
|
|
|
/* |
|
* To make hardclock()'s job easier, make the per-tick delta negative |
|
* if we want time to run slower; then hardclock can simply compute |
|
* tick + tickdelta, and subtract tickdelta from timedelta. |
|
*/ |
|
if (ndelta < 0) |
|
ntickdelta = -ntickdelta; |
|
if (ndelta != 0) |
|
/* We need to save the system clock time during shutdown */ |
|
time_adjusted |= 1; |
|
s = splclock(); |
|
odelta = timedelta; |
|
timedelta = ndelta; |
|
tickdelta = ntickdelta; |
|
splx(s); |
|
|
|
if (olddelta) { |
|
atv.tv_sec = odelta / 1000000; |
|
atv.tv_usec = odelta % 1000000; |
|
error = copyout(&atv, olddelta, sizeof(struct timeval)); |
|
} |
|
#endif /* __HAVE_TIMECOUNTER */ |
|
|
|
return error; |
return error; |
} |
} |
Line 589 adjtime1(const struct timeval *delta, st |
|
Line 485 adjtime1(const struct timeval *delta, st |
|
|
|
/* Allocate a POSIX realtime timer. */ |
/* Allocate a POSIX realtime timer. */ |
int |
int |
sys_timer_create(struct lwp *l, void *v, register_t *retval) |
sys_timer_create(struct lwp *l, const struct sys_timer_create_args *uap, register_t *retval) |
{ |
{ |
struct sys_timer_create_args /* { |
/* { |
syscallarg(clockid_t) clock_id; |
syscallarg(clockid_t) clock_id; |
syscallarg(struct sigevent *) evp; |
syscallarg(struct sigevent *) evp; |
syscallarg(timer_t *) timerid; |
syscallarg(timer_t *) timerid; |
} */ *uap = v; |
} */ |
|
|
return timer_create1(SCARG(uap, timerid), SCARG(uap, clock_id), |
return timer_create1(SCARG(uap, timerid), SCARG(uap, clock_id), |
SCARG(uap, evp), copyin, l); |
SCARG(uap, evp), copyin, l); |
Line 676 timer_create1(timer_t *tid, clockid_t id |
|
Line 572 timer_create1(timer_t *tid, clockid_t id |
|
|
|
/* Delete a POSIX realtime timer */ |
/* Delete a POSIX realtime timer */ |
int |
int |
sys_timer_delete(struct lwp *l, void *v, register_t *retval) |
sys_timer_delete(struct lwp *l, const struct sys_timer_delete_args *uap, register_t *retval) |
{ |
{ |
struct sys_timer_delete_args /* { |
/* { |
syscallarg(timer_t) timerid; |
syscallarg(timer_t) timerid; |
} */ *uap = v; |
} */ |
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
timer_t timerid; |
timer_t timerid; |
struct ptimer *pt, *ptn; |
struct ptimer *pt, *ptn; |
Line 776 timer_settime(struct ptimer *pt) |
|
Line 672 timer_settime(struct ptimer *pt) |
|
void |
void |
timer_gettime(struct ptimer *pt, struct itimerval *aitv) |
timer_gettime(struct ptimer *pt, struct itimerval *aitv) |
{ |
{ |
#ifdef __HAVE_TIMECOUNTER |
|
struct timeval now; |
struct timeval now; |
#endif |
|
struct ptimer *ptn; |
struct ptimer *ptn; |
|
|
*aitv = pt->pt_time; |
*aitv = pt->pt_time; |
Line 791 timer_gettime(struct ptimer *pt, struct |
|
Line 685 timer_gettime(struct ptimer *pt, struct |
|
* off. |
* off. |
*/ |
*/ |
if (timerisset(&aitv->it_value)) { |
if (timerisset(&aitv->it_value)) { |
#ifdef __HAVE_TIMECOUNTER |
|
getmicrotime(&now); |
getmicrotime(&now); |
if (timercmp(&aitv->it_value, &now, <)) |
if (timercmp(&aitv->it_value, &now, <)) |
timerclear(&aitv->it_value); |
timerclear(&aitv->it_value); |
else |
else |
timersub(&aitv->it_value, &now, |
timersub(&aitv->it_value, &now, |
&aitv->it_value); |
&aitv->it_value); |
#else /* !__HAVE_TIMECOUNTER */ |
|
if (timercmp(&aitv->it_value, &time, <)) |
|
timerclear(&aitv->it_value); |
|
else |
|
timersub(&aitv->it_value, &time, |
|
&aitv->it_value); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
} |
} |
} else if (pt->pt_active) { |
} else if (pt->pt_active) { |
if (pt->pt_type == CLOCK_VIRTUAL) |
if (pt->pt_type == CLOCK_VIRTUAL) |
Line 823 timer_gettime(struct ptimer *pt, struct |
|
Line 709 timer_gettime(struct ptimer *pt, struct |
|
|
|
/* Set and arm a POSIX realtime timer */ |
/* Set and arm a POSIX realtime timer */ |
int |
int |
sys_timer_settime(struct lwp *l, void *v, register_t *retval) |
sys_timer_settime(struct lwp *l, const struct sys_timer_settime_args *uap, register_t *retval) |
{ |
{ |
struct sys_timer_settime_args /* { |
/* { |
syscallarg(timer_t) timerid; |
syscallarg(timer_t) timerid; |
syscallarg(int) flags; |
syscallarg(int) flags; |
syscallarg(const struct itimerspec *) value; |
syscallarg(const struct itimerspec *) value; |
syscallarg(struct itimerspec *) ovalue; |
syscallarg(struct itimerspec *) ovalue; |
} */ *uap = v; |
} */ |
int error; |
int error; |
struct itimerspec value, ovalue, *ovp = NULL; |
struct itimerspec value, ovalue, *ovp = NULL; |
|
|
|
|
dotimer_settime(int timerid, struct itimerspec *value, |
dotimer_settime(int timerid, struct itimerspec *value, |
struct itimerspec *ovalue, int flags, struct proc *p) |
struct itimerspec *ovalue, int flags, struct proc *p) |
{ |
{ |
#ifdef __HAVE_TIMECOUNTER |
|
struct timeval now; |
struct timeval now; |
#endif |
|
struct itimerval val, oval; |
struct itimerval val, oval; |
struct ptimer *pt; |
struct ptimer *pt; |
int s; |
int s; |
Line 885 dotimer_settime(int timerid, struct itim |
|
Line 769 dotimer_settime(int timerid, struct itim |
|
*/ |
*/ |
if (timerisset(&pt->pt_time.it_value)) { |
if (timerisset(&pt->pt_time.it_value)) { |
if (pt->pt_type == CLOCK_REALTIME) { |
if (pt->pt_type == CLOCK_REALTIME) { |
#ifdef __HAVE_TIMECOUNTER |
|
if ((flags & TIMER_ABSTIME) == 0) { |
if ((flags & TIMER_ABSTIME) == 0) { |
getmicrotime(&now); |
getmicrotime(&now); |
timeradd(&pt->pt_time.it_value, &now, |
timeradd(&pt->pt_time.it_value, &now, |
&pt->pt_time.it_value); |
&pt->pt_time.it_value); |
} |
} |
#else /* !__HAVE_TIMECOUNTER */ |
|
if ((flags & TIMER_ABSTIME) == 0) |
|
timeradd(&pt->pt_time.it_value, &time, |
|
&pt->pt_time.it_value); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
} else { |
} else { |
if ((flags & TIMER_ABSTIME) != 0) { |
if ((flags & TIMER_ABSTIME) != 0) { |
#ifdef __HAVE_TIMECOUNTER |
|
getmicrotime(&now); |
getmicrotime(&now); |
timersub(&pt->pt_time.it_value, &now, |
timersub(&pt->pt_time.it_value, &now, |
&pt->pt_time.it_value); |
&pt->pt_time.it_value); |
#else /* !__HAVE_TIMECOUNTER */ |
|
timersub(&pt->pt_time.it_value, &time, |
|
&pt->pt_time.it_value); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
if (!timerisset(&pt->pt_time.it_value) || |
if (!timerisset(&pt->pt_time.it_value) || |
pt->pt_time.it_value.tv_sec < 0) { |
pt->pt_time.it_value.tv_sec < 0) { |
pt->pt_time.it_value.tv_sec = 0; |
pt->pt_time.it_value.tv_sec = 0; |
Line 928 dotimer_settime(int timerid, struct itim |
|
Line 801 dotimer_settime(int timerid, struct itim |
|
|
|
/* Return the time remaining until a POSIX timer fires. */ |
/* Return the time remaining until a POSIX timer fires. */ |
int |
int |
sys_timer_gettime(struct lwp *l, void *v, register_t *retval) |
sys_timer_gettime(struct lwp *l, const struct sys_timer_gettime_args *uap, register_t *retval) |
{ |
{ |
struct sys_timer_gettime_args /* { |
/* { |
syscallarg(timer_t) timerid; |
syscallarg(timer_t) timerid; |
syscallarg(struct itimerspec *) value; |
syscallarg(struct itimerspec *) value; |
} */ *uap = v; |
} */ |
struct itimerspec its; |
struct itimerspec its; |
int error; |
int error; |
|
|
Line 972 dotimer_gettime(int timerid, struct proc |
|
Line 845 dotimer_gettime(int timerid, struct proc |
|
* a timer expires and a notification can be posted. |
* a timer expires and a notification can be posted. |
*/ |
*/ |
int |
int |
sys_timer_getoverrun(struct lwp *l, void *v, register_t *retval) |
sys_timer_getoverrun(struct lwp *l, const struct sys_timer_getoverrun_args *uap, register_t *retval) |
{ |
{ |
struct sys_timer_getoverrun_args /* { |
/* { |
syscallarg(timer_t) timerid; |
syscallarg(timer_t) timerid; |
} */ *uap = v; |
} */ |
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
int timerid; |
int timerid; |
struct ptimer *pt; |
struct ptimer *pt; |
Line 1004 sys_timer_getoverrun(struct lwp *l, void |
|
Line 877 sys_timer_getoverrun(struct lwp *l, void |
|
void |
void |
realtimerexpire(void *arg) |
realtimerexpire(void *arg) |
{ |
{ |
#ifdef __HAVE_TIMECOUNTER |
|
struct timeval now; |
struct timeval now; |
#endif |
|
struct ptimer *pt; |
struct ptimer *pt; |
int s; |
int s; |
|
|
Line 1018 realtimerexpire(void *arg) |
|
Line 889 realtimerexpire(void *arg) |
|
timerclear(&pt->pt_time.it_value); |
timerclear(&pt->pt_time.it_value); |
return; |
return; |
} |
} |
#ifdef __HAVE_TIMECOUNTER |
|
for (;;) { |
for (;;) { |
s = splclock(); /* XXX need spl now? */ |
s = splclock(); /* XXX need spl now? */ |
timeradd(&pt->pt_time.it_value, |
timeradd(&pt->pt_time.it_value, |
Line 1037 realtimerexpire(void *arg) |
|
Line 907 realtimerexpire(void *arg) |
|
splx(s); |
splx(s); |
pt->pt_overruns++; |
pt->pt_overruns++; |
} |
} |
#else /* !__HAVE_TIMECOUNTER */ |
|
for (;;) { |
|
s = splclock(); |
|
timeradd(&pt->pt_time.it_value, |
|
&pt->pt_time.it_interval, &pt->pt_time.it_value); |
|
if (timercmp(&pt->pt_time.it_value, &time, >)) { |
|
/* |
|
* Don't need to check hzto() return value, here. |
|
* callout_reset() does it for us. |
|
*/ |
|
callout_reset(&pt->pt_ch, hzto(&pt->pt_time.it_value), |
|
realtimerexpire, pt); |
|
splx(s); |
|
return; |
|
} |
|
splx(s); |
|
pt->pt_overruns++; |
|
} |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
} |
} |
|
|
/* BSD routine to get the value of an interval timer. */ |
/* BSD routine to get the value of an interval timer. */ |
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_getitimer(struct lwp *l, void *v, register_t *retval) |
sys_getitimer(struct lwp *l, const struct sys_getitimer_args *uap, register_t *retval) |
{ |
{ |
struct sys_getitimer_args /* { |
/* { |
syscallarg(int) which; |
syscallarg(int) which; |
syscallarg(struct itimerval *) itv; |
syscallarg(struct itimerval *) itv; |
} */ *uap = v; |
} */ |
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
struct itimerval aitv; |
struct itimerval aitv; |
int error; |
int error; |
Line 1100 dogetitimer(struct proc *p, int which, s |
|
Line 951 dogetitimer(struct proc *p, int which, s |
|
/* BSD routine to set/arm an interval timer. */ |
/* BSD routine to set/arm an interval timer. */ |
/* ARGSUSED */ |
/* ARGSUSED */ |
int |
int |
sys_setitimer(struct lwp *l, void *v, register_t *retval) |
sys_setitimer(struct lwp *l, const struct sys_setitimer_args *uap, register_t *retval) |
{ |
{ |
struct sys_setitimer_args /* { |
/* { |
syscallarg(int) which; |
syscallarg(int) which; |
syscallarg(const struct itimerval *) itv; |
syscallarg(const struct itimerval *) itv; |
syscallarg(struct itimerval *) oitv; |
syscallarg(struct itimerval *) oitv; |
} */ *uap = v; |
} */ |
struct proc *p = l->l_proc; |
struct proc *p = l->l_proc; |
int which = SCARG(uap, which); |
int which = SCARG(uap, which); |
struct sys_getitimer_args getargs; |
struct sys_getitimer_args getargs; |
Line 1135 sys_setitimer(struct lwp *l, void *v, re |
|
Line 986 sys_setitimer(struct lwp *l, void *v, re |
|
int |
int |
dosetitimer(struct proc *p, int which, struct itimerval *itvp) |
dosetitimer(struct proc *p, int which, struct itimerval *itvp) |
{ |
{ |
#ifdef __HAVE_TIMECOUNTER |
|
struct timeval now; |
struct timeval now; |
#endif |
|
struct ptimer *pt; |
struct ptimer *pt; |
int s; |
int s; |
|
|
Line 1185 dosetitimer(struct proc *p, int which, s |
|
Line 1034 dosetitimer(struct proc *p, int which, s |
|
s = splclock(); |
s = splclock(); |
if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) { |
if ((which == ITIMER_REAL) && timerisset(&pt->pt_time.it_value)) { |
/* Convert to absolute time */ |
/* Convert to absolute time */ |
#ifdef __HAVE_TIMECOUNTER |
|
/* XXX need to wrap in splclock for timecounters case? */ |
/* XXX need to wrap in splclock for timecounters case? */ |
getmicrotime(&now); |
getmicrotime(&now); |
timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); |
timeradd(&pt->pt_time.it_value, &now, &pt->pt_time.it_value); |
#else /* !__HAVE_TIMECOUNTER */ |
|
timeradd(&pt->pt_time.it_value, &time, &pt->pt_time.it_value); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
} |
} |
timer_settime(pt); |
timer_settime(pt); |
splx(s); |
splx(s); |
Line 1363 ratecheck(struct timeval *lasttime, cons |
|
Line 1208 ratecheck(struct timeval *lasttime, cons |
|
{ |
{ |
struct timeval tv, delta; |
struct timeval tv, delta; |
int rv = 0; |
int rv = 0; |
#ifndef __HAVE_TIMECOUNTER |
|
int s; |
|
#endif |
|
|
|
#ifdef __HAVE_TIMECOUNTER |
|
getmicrouptime(&tv); |
getmicrouptime(&tv); |
#else /* !__HAVE_TIMECOUNTER */ |
|
s = splclock(); |
|
tv = mono_time; |
|
splx(s); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
timersub(&tv, lasttime, &delta); |
timersub(&tv, lasttime, &delta); |
|
|
/* |
/* |
Line 1397 ppsratecheck(struct timeval *lasttime, i |
|
Line 1233 ppsratecheck(struct timeval *lasttime, i |
|
{ |
{ |
struct timeval tv, delta; |
struct timeval tv, delta; |
int rv; |
int rv; |
#ifndef __HAVE_TIMECOUNTER |
|
int s; |
|
#endif |
|
|
|
#ifdef __HAVE_TIMECOUNTER |
|
getmicrouptime(&tv); |
getmicrouptime(&tv); |
#else /* !__HAVE_TIMECOUNTER */ |
|
s = splclock(); |
|
tv = mono_time; |
|
splx(s); |
|
#endif /* !__HAVE_TIMECOUNTER */ |
|
timersub(&tv, lasttime, &delta); |
timersub(&tv, lasttime, &delta); |
|
|
/* |
/* |