Project

General

Profile

Bug #1351 ยป kern_time.patch

mokamaru, 04/28/2009 04:07 PM

View differences:

sys/kern/kern_time.c
* timers when they expire.
*/
static int nanosleep1 (struct timespec *rqt,
struct timespec *rmt);
static int settime (struct timeval *);
static void timevalfix (struct timeval *);
static int nanosleep1(struct timespec *rqt, struct timespec *rmt);
static int settime(struct timeval *);
static void timevalfix(struct timeval *);
static int sleep_hard_us = 100;
SYSCTL_INT(_kern, OID_AUTO, sleep_hard_us, CTLFLAG_RW, &sleep_hard_us, 0, "")
......
return (0);
}
/* ARGSUSED */
int
sys_clock_gettime(struct clock_gettime_args *uap)
kern_clock_gettime(clockid_t clock_id, struct timespec *ats)
{
struct timespec ats;
switch(uap->clock_id) {
switch(clock_id) {
case CLOCK_REALTIME:
nanotime(&ats);
return (copyout(&ats, uap->tp, sizeof(ats)));
nanotime(ats);
case CLOCK_MONOTONIC:
nanouptime(&ats);
return (copyout(&ats, uap->tp, sizeof(ats)));
nanouptime(ats);
default:
return (EINVAL);
}
return (0);
}
/* ARGSUSED */
int
sys_clock_settime(struct clock_settime_args *uap)
sys_clock_gettime(struct clock_gettime_args *uap)
{
struct timespec ats;
int error;
error = kern_clock_gettime(uap->clock_id, &ats);
if (error == 0)
error = copyout(&ats, uap->tp, sizeof(ats))
return (error);
}
int
kern_clock_settime(clockid_t clock_id, struct timespec *ats)
{
struct thread *td = curthread;
struct timeval atv;
struct timespec ats;
int error;
if ((error = priv_check(td, PRIV_ROOT)) != 0)
return (error);
switch(uap->clock_id) {
case CLOCK_REALTIME:
if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
return (error);
if (ats.tv_nsec < 0 || ats.tv_nsec >= 1000000000)
return (EINVAL);
/* XXX Don't convert nsec->usec and back */
TIMESPEC_TO_TIMEVAL(&atv, &ats);
error = settime(&atv);
return (error);
default:
if (clock_id != CLOCK_REALTIME)
return (EINVAL);
}
if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000)
return (EINVAL);
TIMESPEC_TO_TIMEVAL(&atv, ats);
error = settime(&atv);
return (error);
}
/* ARGSUSED */
int
sys_clock_getres(struct clock_getres_args *uap)
sys_clock_settime(struct clock_settime_args *uap)
{
struct timespec ts;
struct timespec ats;
int error;
if ((error = copyin(uap->tp, &ats, sizeof(ats))) != 0)
return (error);
return (kern_clock_settime(uap->clock_id, &ats));
}
switch(uap->clock_id) {
int
kern_clock_getres(clockid_t clock_id, struct timespec *ts)
{
switch(clock_id) {
case CLOCK_REALTIME:
case CLOCK_MONOTONIC:
/*
......
* if rounding down would give 0. Perfect rounding
* is unimportant.
*/
ts.tv_sec = 0;
ts.tv_nsec = 1000000000 / sys_cputimer->freq + 1;
return(copyout(&ts, uap->tp, sizeof(ts)));
ts->tv_sec = 0;
ts->tv_nsec = 1000000000 / sys_cputimer->freq + 1;
default:
return(EINVAL);
}
return (0);
}
int
sys_clock_getres(struct clock_getres_args *uap)
{
int error;
struct timespec ts;
error = kern_clock_getres(uap->clock_id, &ts);
if (error == 0)
error = copyout(&ts, uap->tp, sizeof(ts));
return (error);
}
/*
sys/sys/time.h
void set_timeofday(struct timespec *ts);
void kern_adjtime(int64_t, int64_t *);
void kern_reladjtime(int64_t);
int kern_clock_gettime(clockid_t, struct timespec *);
int kern_clock_settime(clockid_t, struct timespec *);
int kern_clock_getres(clockid_t, struct timespec *);
void timevaladd (struct timeval *, const struct timeval *);
void timevalsub (struct timeval *, const struct timeval *);
int tvtohz_high (struct timeval *);
    (1-1/1)