Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_time.c
Show First 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | |||||
#define MAX_CLOCKS (CLOCK_MONOTONIC+1) | #define MAX_CLOCKS (CLOCK_MONOTONIC+1) | ||||
#define CPUCLOCK_BIT 0x80000000 | #define CPUCLOCK_BIT 0x80000000 | ||||
#define CPUCLOCK_PROCESS_BIT 0x40000000 | #define CPUCLOCK_PROCESS_BIT 0x40000000 | ||||
#define CPUCLOCK_ID_MASK (~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT)) | #define CPUCLOCK_ID_MASK (~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT)) | ||||
#define MAKE_THREAD_CPUCLOCK(tid) (CPUCLOCK_BIT|(tid)) | #define MAKE_THREAD_CPUCLOCK(tid) (CPUCLOCK_BIT|(tid)) | ||||
#define MAKE_PROCESS_CPUCLOCK(pid) \ | #define MAKE_PROCESS_CPUCLOCK(pid) \ | ||||
(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid)) | (CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid)) | ||||
#define NS_PER_SEC 1000000000 | |||||
kib: The 'L' suffix is not needed, I believe. | |||||
static struct kclock posix_clocks[MAX_CLOCKS]; | static struct kclock posix_clocks[MAX_CLOCKS]; | ||||
static uma_zone_t itimer_zone = NULL; | static uma_zone_t itimer_zone = NULL; | ||||
/* | /* | ||||
* Time of day and interval timer support. | * Time of day and interval timer support. | ||||
* | * | ||||
* These routines provide the kernel entry points to get and set | * These routines provide the kernel entry points to get and set | ||||
* the time-of-day and per-process interval timers. Subroutines | * the time-of-day and per-process interval timers. Subroutines | ||||
▲ Show 20 Lines • Show All 320 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct timeval atv; | struct timeval atv; | ||||
int error; | int error; | ||||
if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0) | if ((error = priv_check(td, PRIV_CLOCK_SETTIME)) != 0) | ||||
return (error); | return (error); | ||||
if (clock_id != CLOCK_REALTIME) | if (clock_id != CLOCK_REALTIME) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (ats->tv_nsec < 0 || ats->tv_nsec >= 1000000000 || | if (ats->tv_nsec < 0 || ats->tv_nsec >= NS_PER_SEC || ats->tv_sec < 0) | ||||
ats->tv_sec < 0) | |||||
return (EINVAL); | return (EINVAL); | ||||
if (!allow_insane_settime && | if (!allow_insane_settime && | ||||
(ats->tv_sec > 8000ULL * 365 * 24 * 60 * 60 || | (ats->tv_sec > 8000ULL * 365 * 24 * 60 * 60 || | ||||
ats->tv_sec < utc_offset())) | ats->tv_sec < utc_offset())) | ||||
return (EINVAL); | return (EINVAL); | ||||
/* XXX Don't convert nsec->usec and back */ | /* XXX Don't convert nsec->usec and back */ | ||||
TIMESPEC_TO_TIMEVAL(&atv, ats); | TIMESPEC_TO_TIMEVAL(&atv, ats); | ||||
error = settime(td, &atv); | error = settime(td, &atv); | ||||
Show All 36 Lines | kern_clock_getres(struct thread *td, clockid_t clock_id, struct timespec *ts) | ||||
case CLOCK_UPTIME: | case CLOCK_UPTIME: | ||||
case CLOCK_UPTIME_FAST: | case CLOCK_UPTIME_FAST: | ||||
case CLOCK_UPTIME_PRECISE: | case CLOCK_UPTIME_PRECISE: | ||||
/* | /* | ||||
* Round up the result of the division cheaply by adding 1. | * Round up the result of the division cheaply by adding 1. | ||||
* Rounding up is especially important if rounding down | * Rounding up is especially important if rounding down | ||||
* would give 0. Perfect rounding is unimportant. | * would give 0. Perfect rounding is unimportant. | ||||
*/ | */ | ||||
ts->tv_nsec = 1000000000 / tc_getfrequency() + 1; | ts->tv_nsec = NS_PER_SEC / tc_getfrequency() + 1; | ||||
break; | break; | ||||
case CLOCK_VIRTUAL: | case CLOCK_VIRTUAL: | ||||
case CLOCK_PROF: | case CLOCK_PROF: | ||||
/* Accurately round up here because we can do so cheaply. */ | /* Accurately round up here because we can do so cheaply. */ | ||||
ts->tv_nsec = howmany(1000000000, hz); | ts->tv_nsec = howmany(NS_PER_SEC, hz); | ||||
break; | break; | ||||
case CLOCK_SECOND: | case CLOCK_SECOND: | ||||
ts->tv_sec = 1; | ts->tv_sec = 1; | ||||
ts->tv_nsec = 0; | ts->tv_nsec = 0; | ||||
break; | break; | ||||
case CLOCK_THREAD_CPUTIME_ID: | case CLOCK_THREAD_CPUTIME_ID: | ||||
case CLOCK_PROCESS_CPUTIME_ID: | case CLOCK_PROCESS_CPUTIME_ID: | ||||
cputime: | cputime: | ||||
Show All 25 Lines | kern_clock_nanosleep(struct thread *td, clockid_t clock_id, int flags, | ||||
const struct timespec *rqt, struct timespec *rmt) | const struct timespec *rqt, struct timespec *rmt) | ||||
{ | { | ||||
struct timespec ts, now; | struct timespec ts, now; | ||||
sbintime_t sbt, sbtt, prec, tmp; | sbintime_t sbt, sbtt, prec, tmp; | ||||
time_t over; | time_t over; | ||||
int error; | int error; | ||||
bool is_abs_real; | bool is_abs_real; | ||||
if (rqt->tv_nsec < 0 || rqt->tv_nsec >= 1000000000) | if (rqt->tv_nsec < 0 || rqt->tv_nsec >= NS_PER_SEC) | ||||
return (EINVAL); | return (EINVAL); | ||||
if ((flags & ~TIMER_ABSTIME) != 0) | if ((flags & ~TIMER_ABSTIME) != 0) | ||||
return (EINVAL); | return (EINVAL); | ||||
switch (clock_id) { | switch (clock_id) { | ||||
case CLOCK_REALTIME: | case CLOCK_REALTIME: | ||||
case CLOCK_REALTIME_PRECISE: | case CLOCK_REALTIME_PRECISE: | ||||
case CLOCK_REALTIME_FAST: | case CLOCK_REALTIME_FAST: | ||||
case CLOCK_SECOND: | case CLOCK_SECOND: | ||||
▲ Show 20 Lines • Show All 1,124 Lines • ▼ Show 20 Lines | itimer_accept(struct proc *p, int timerid, ksiginfo_t *ksi) | ||||
} | } | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
static int | static int | ||||
itimespecfix(struct timespec *ts) | itimespecfix(struct timespec *ts) | ||||
{ | { | ||||
if (ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= 1000000000) | if (ts->tv_sec < 0 || ts->tv_nsec < 0 || ts->tv_nsec >= NS_PER_SEC) | ||||
return (EINVAL); | return (EINVAL); | ||||
if ((UINT64_MAX - ts->tv_nsec) / NS_PER_SEC < ts->tv_sec) | |||||
return (EINVAL); | |||||
if (ts->tv_sec == 0 && ts->tv_nsec != 0 && ts->tv_nsec < tick * 1000) | if (ts->tv_sec == 0 && ts->tv_nsec != 0 && ts->tv_nsec < tick * 1000) | ||||
ts->tv_nsec = tick * 1000; | ts->tv_nsec = tick * 1000; | ||||
return (0); | return (0); | ||||
} | } | ||||
#define timespectons(tsp) \ | #define timespectons(tsp) \ | ||||
((uint64_t)(tsp)->tv_sec * 1000000000 + (tsp)->tv_nsec) | ((uint64_t)(tsp)->tv_sec * NS_PER_SEC + (tsp)->tv_nsec) | ||||
#define timespecfromns(ns) (struct timespec){ \ | #define timespecfromns(ns) (struct timespec){ \ | ||||
.tv_sec = (ns) / 1000000000, \ | .tv_sec = (ns) / NS_PER_SEC, \ | ||||
.tv_nsec = (ns) % 1000000000 \ | .tv_nsec = (ns) % NS_PER_SEC \ | ||||
} | } | ||||
static void | static void | ||||
realtimer_expire_l(struct itimer *it, bool proc_locked) | realtimer_expire_l(struct itimer *it, bool proc_locked) | ||||
{ | { | ||||
struct timespec cts, ts; | struct timespec cts, ts; | ||||
struct timeval tv; | struct timeval tv; | ||||
struct proc *p; | struct proc *p; | ||||
▲ Show 20 Lines • Show All 169 Lines • Show Last 20 Lines |
The 'L' suffix is not needed, I believe.