Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_time.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
static void itimers_alloc(struct proc *); | static void itimers_alloc(struct proc *); | ||||
static int realtimer_create(struct itimer *); | static int realtimer_create(struct itimer *); | ||||
static int realtimer_gettime(struct itimer *, struct itimerspec *); | static int realtimer_gettime(struct itimer *, struct itimerspec *); | ||||
static int realtimer_settime(struct itimer *, int, | static int realtimer_settime(struct itimer *, int, | ||||
struct itimerspec *, struct itimerspec *); | struct itimerspec *, struct itimerspec *); | ||||
static int realtimer_delete(struct itimer *); | static int realtimer_delete(struct itimer *); | ||||
static void realtimer_clocktime(clockid_t, struct timespec *); | static void realtimer_clocktime(clockid_t, struct timespec *); | ||||
static void realtimer_expire(void *); | static void realtimer_expire(void *); | ||||
static void realtimer_expire_l(struct itimer *it, bool proc_locked); | |||||
static int register_posix_clock(int, const struct kclock *); | static int register_posix_clock(int, const struct kclock *); | ||||
static void itimer_fire(struct itimer *it); | static void itimer_fire(struct itimer *it); | ||||
static int itimespecfix(struct timespec *ts); | static int itimespecfix(struct timespec *ts); | ||||
#define CLOCK_CALL(clock, call, arglist) \ | #define CLOCK_CALL(clock, call, arglist) \ | ||||
((*posix_clocks[clock].call) arglist) | ((*posix_clocks[clock].call) arglist) | ||||
▲ Show 20 Lines • Show All 798 Lines • ▼ Show 20 Lines | for (id = 3; id < TIMER_MAX; id++) { | ||||
it = p->p_itimers->its_timers[id]; | it = p->p_itimers->its_timers[id]; | ||||
if (it == NULL) | if (it == NULL) | ||||
continue; | continue; | ||||
if ((it->it_flags & ITF_PSTOPPED) != 0) { | if ((it->it_flags & ITF_PSTOPPED) != 0) { | ||||
ITIMER_LOCK(it); | ITIMER_LOCK(it); | ||||
if ((it->it_flags & ITF_PSTOPPED) != 0) { | if ((it->it_flags & ITF_PSTOPPED) != 0) { | ||||
it->it_flags &= ~ITF_PSTOPPED; | it->it_flags &= ~ITF_PSTOPPED; | ||||
if ((it->it_flags & ITF_DELETING) == 0) | if ((it->it_flags & ITF_DELETING) == 0) | ||||
realtimer_expire(it); | realtimer_expire_l(it, true); | ||||
} | } | ||||
ITIMER_UNLOCK(it); | ITIMER_UNLOCK(it); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 727 Lines • ▼ Show 20 Lines | |||||
#define timespectons(tsp) \ | #define timespectons(tsp) \ | ||||
((uint64_t)(tsp)->tv_sec * 1000000000 + (tsp)->tv_nsec) | ((uint64_t)(tsp)->tv_sec * 1000000000 + (tsp)->tv_nsec) | ||||
#define timespecfromns(ns) (struct timespec){ \ | #define timespecfromns(ns) (struct timespec){ \ | ||||
.tv_sec = (ns) / 1000000000, \ | .tv_sec = (ns) / 1000000000, \ | ||||
.tv_nsec = (ns) % 1000000000 \ | .tv_nsec = (ns) % 1000000000 \ | ||||
} | } | ||||
/* Timeout callback for realtime timer */ | |||||
static void | static void | ||||
realtimer_expire(void *arg) | realtimer_expire_l(struct itimer *it, bool proc_locked) | ||||
{ | { | ||||
struct timespec cts, ts; | struct timespec cts, ts; | ||||
struct timeval tv; | struct timeval tv; | ||||
struct itimer *it; | |||||
struct proc *p; | struct proc *p; | ||||
uint64_t interval, now, overruns, value; | uint64_t interval, now, overruns, value; | ||||
it = (struct itimer *)arg; | |||||
realtimer_clocktime(it->it_clockid, &cts); | realtimer_clocktime(it->it_clockid, &cts); | ||||
/* Only fire if time is reached. */ | /* Only fire if time is reached. */ | ||||
if (timespeccmp(&cts, &it->it_time.it_value, >=)) { | if (timespeccmp(&cts, &it->it_time.it_value, >=)) { | ||||
if (timespecisset(&it->it_time.it_interval)) { | if (timespecisset(&it->it_time.it_interval)) { | ||||
timespecadd(&it->it_time.it_value, | timespecadd(&it->it_time.it_value, | ||||
&it->it_time.it_interval, | &it->it_time.it_interval, | ||||
&it->it_time.it_value); | &it->it_time.it_value); | ||||
Show All 17 Lines | if (timespecisset(&it->it_time.it_interval)) { | ||||
value = | value = | ||||
now + interval - (now - value) % interval; | now + interval - (now - value) % interval; | ||||
it->it_time.it_value = timespecfromns(value); | it->it_time.it_value = timespecfromns(value); | ||||
} | } | ||||
} else { | } else { | ||||
/* single shot timer ? */ | /* single shot timer ? */ | ||||
timespecclear(&it->it_time.it_value); | timespecclear(&it->it_time.it_value); | ||||
} | } | ||||
if (timespecisset(&it->it_time.it_value)) { | |||||
p = it->it_proc; | p = it->it_proc; | ||||
if (timespecisset(&it->it_time.it_value)) { | |||||
if (P_SHOULDSTOP(p) || P_KILLED(p)) { | if (P_SHOULDSTOP(p) || P_KILLED(p)) { | ||||
it->it_flags |= ITF_PSTOPPED; | it->it_flags |= ITF_PSTOPPED; | ||||
} else { | } else { | ||||
timespecsub(&it->it_time.it_value, &cts, &ts); | timespecsub(&it->it_time.it_value, &cts, &ts); | ||||
TIMESPEC_TO_TIMEVAL(&tv, &ts); | TIMESPEC_TO_TIMEVAL(&tv, &ts); | ||||
callout_reset(&it->it_callout, tvtohz(&tv), | callout_reset(&it->it_callout, tvtohz(&tv), | ||||
realtimer_expire, it); | realtimer_expire, it); | ||||
} | } | ||||
} | } | ||||
itimer_enter(it); | itimer_enter(it); | ||||
ITIMER_UNLOCK(it); | ITIMER_UNLOCK(it); | ||||
if (proc_locked) | |||||
PROC_UNLOCK(p); | |||||
itimer_fire(it); | itimer_fire(it); | ||||
if (proc_locked) | |||||
PROC_LOCK(p); | |||||
ITIMER_LOCK(it); | ITIMER_LOCK(it); | ||||
itimer_leave(it); | itimer_leave(it); | ||||
} else if (timespecisset(&it->it_time.it_value)) { | } else if (timespecisset(&it->it_time.it_value)) { | ||||
p = it->it_proc; | p = it->it_proc; | ||||
if (P_SHOULDSTOP(p) || P_KILLED(p)) { | if (P_SHOULDSTOP(p) || P_KILLED(p)) { | ||||
it->it_flags |= ITF_PSTOPPED; | it->it_flags |= ITF_PSTOPPED; | ||||
} else { | } else { | ||||
ts = it->it_time.it_value; | ts = it->it_time.it_value; | ||||
timespecsub(&ts, &cts, &ts); | timespecsub(&ts, &cts, &ts); | ||||
TIMESPEC_TO_TIMEVAL(&tv, &ts); | TIMESPEC_TO_TIMEVAL(&tv, &ts); | ||||
callout_reset(&it->it_callout, tvtohz(&tv), | callout_reset(&it->it_callout, tvtohz(&tv), | ||||
realtimer_expire, it); | realtimer_expire, it); | ||||
} | } | ||||
} | } | ||||
} | |||||
/* Timeout callback for realtime timer */ | |||||
static void | |||||
realtimer_expire(void *arg) | |||||
{ | |||||
realtimer_expire_l(arg, false); | |||||
} | } | ||||
static void | static void | ||||
itimer_fire(struct itimer *it) | itimer_fire(struct itimer *it) | ||||
{ | { | ||||
struct proc *p = it->it_proc; | struct proc *p = it->it_proc; | ||||
struct thread *td; | struct thread *td; | ||||
▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines |