Date: Fri, 21 Dec 2012 11:08:45 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r244533 - in projects/calloutng: share/man/man9 sys/dev/atkbdc sys/dev/random sys/dev/syscons sys/kern sys/sys Message-ID: <201212211108.qBLB8jwa047382@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Fri Dec 21 11:08:44 2012 New Revision: 244533 URL: http://svnweb.freebsd.org/changeset/base/244533 Log: Make callout_reset_bt() handle both relative and absolute struct bintime arguments. That allows to remove ticks argument and simplify consumers code in some cases. Add new flags to specify absolute time and alignment to hardclock() calls. Refactor the rest of APIs to reflect above change. X_flags() functions are not required any more, so APIs are more compact. Simplify poll() and select() code using above relative bintime support. Rewrite kevent() timeout implementation using absolute bintime. Modified: projects/calloutng/share/man/man9/Makefile projects/calloutng/share/man/man9/condvar.9 projects/calloutng/share/man/man9/sleep.9 projects/calloutng/share/man/man9/sleepqueue.9 projects/calloutng/share/man/man9/timeout.9 projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c projects/calloutng/sys/dev/random/randomdev_soft.c projects/calloutng/sys/dev/syscons/syscons.c projects/calloutng/sys/kern/kern_condvar.c projects/calloutng/sys/kern/kern_event.c projects/calloutng/sys/kern/kern_resource.c projects/calloutng/sys/kern/kern_synch.c projects/calloutng/sys/kern/kern_tc.c projects/calloutng/sys/kern/kern_time.c projects/calloutng/sys/kern/kern_timeout.c projects/calloutng/sys/kern/subr_log.c projects/calloutng/sys/kern/subr_param.c projects/calloutng/sys/kern/subr_sleepqueue.c projects/calloutng/sys/kern/sys_generic.c projects/calloutng/sys/sys/callout.h projects/calloutng/sys/sys/condvar.h projects/calloutng/sys/sys/mutex.h projects/calloutng/sys/sys/rwlock.h projects/calloutng/sys/sys/sleepqueue.h projects/calloutng/sys/sys/sx.h projects/calloutng/sys/sys/systm.h projects/calloutng/sys/sys/time.h Modified: projects/calloutng/share/man/man9/Makefile ============================================================================== --- projects/calloutng/share/man/man9/Makefile Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/share/man/man9/Makefile Fri Dec 21 11:08:44 2012 (r244533) @@ -1197,15 +1197,12 @@ MLINKS+=signal.9 cursig.9 \ signal.9 trapsignal.9 MLINKS+=sleep.9 msleep.9 \ sleep.9 msleep_bt.9 \ - sleep.9 msleep_flags.9 \ sleep.9 msleep_spin.9 \ - sleep.9 msleep_spin_flags.9 \ + sleep.9 msleep_spin_bt.9 \ sleep.9 pause.9 \ sleep.9 pause_bt.9 \ - sleep.9 pause_flags.9 \ sleep.9 tsleep.9 \ sleep.9 tsleep_bt.9 \ - sleep.9 tsleep_flags.9 \ sleep.9 wakeup.9 \ sleep.9 wakeup_one.9 MLINKS+=sleepqueue.9 init_sleepqueues.9 \ @@ -1221,7 +1218,6 @@ MLINKS+=sleepqueue.9 init_sleepqueues.9 sleepqueue.9 sleepq_remove.9 \ sleepqueue.9 sleepq_set_timeout.9 \ sleepqueue.9 sleepq_set_timeout_bt.9 \ - sleepqueue.9 sleepq_set_timeout_flags.9 \ sleepqueue.9 sleepq_signal.9 \ sleepqueue.9 sleepq_timedwait.9 \ sleepqueue.9 sleepq_timedwait_sig.9 \ @@ -1345,10 +1341,8 @@ MLINKS+=timeout.9 callout.9 \ timeout.9 callout_pending.9 \ timeout.9 callout_reset.9 \ timeout.9 callout_reset_bt.9 \ - timeout.9 callout_reset_flags.9 \ timeout.9 callout_reset_on.9 \ timeout.9 callout_reset_bt_on.9 \ - timeout.9 callout_reset_flags_on.9 \ timeout.9 callout_schedule.9 \ timeout.9 callout_stop.9 \ timeout.9 untimeout.9 Modified: projects/calloutng/share/man/man9/condvar.9 ============================================================================== --- projects/calloutng/share/man/man9/condvar.9 Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/share/man/man9/condvar.9 Fri Dec 21 11:08:44 2012 (r244533) @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 14, 2012 +.Dd December 21, 2012 .Dt CONDVAR 9 .Os .Sh NAME @@ -38,10 +38,8 @@ .Nm cv_wait_unlock , .Nm cv_timedwait , .Nm cv_timedwait_bt , -.Nm cv_timedwait_flags , .Nm cv_timedwait_sig , .Nm cv_timedwait_sig_bt , -.Nm cv_timedwait_sig_flags , .Nm cv_signal , .Nm cv_broadcast , .Nm cv_broadcastpri , @@ -64,16 +62,13 @@ .Ft int .Fn cv_timedwait "struct cv *cvp" "lock" "int timo" .Ft int -.Fn cv_timedwait_bt "struct cv *cvp" "lock" "struct bintime *bt" "int flags" -.Ft int -.Fn cv_timedwait_flags "struct cv *cvp" "lock" "int timo" "int flags" +.Fn cv_timedwait_bt "struct cv *cvp" "lock" "struct bintime bt" \ +"struct bintime pr" "int flags" .Ft int .Fn cv_timedwait_sig "struct cv *cvp" "lock" "int timo" .Ft int -.Fn cv_timedwait_sig_bt "struct cv *cvp" "lock" "struct bintime *bt" \ -"struct bintime *pr" -.Ft int -.Fn cv_timedwait_sig_flags "struct cv *cvp" "lock" "int timo" "int flags" +.Fn cv_timedwait_sig_bt "struct cv *cvp" "lock" "struct bintime bt" \ +"struct bintime pr" "int flags" .Ft void .Fn cv_signal "struct cv *cvp" .Ft void Modified: projects/calloutng/share/man/man9/sleep.9 ============================================================================== --- projects/calloutng/share/man/man9/sleep.9 Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/share/man/man9/sleep.9 Fri Dec 21 11:08:44 2012 (r244533) @@ -25,20 +25,17 @@ .\" .\" $FreeBSD$ .\" -.Dd December 16, 2012 +.Dd December 21, 2012 .Dt SLEEP 9 .Os .Sh NAME .Nm msleep , -.Nm msleep_flags , .Nm msleep_bt , .Nm msleep_spin , -.Nm msleep_spin_flags , +.Nm msleep_spin_bt , .Nm pause , -.Nm pause_flags , .Nm pause_bt , .Nm tsleep , -.Nm tsleep_flags , .Nm tsleep_bt , .Nm wakeup .Nd wait for events @@ -49,30 +46,23 @@ .Ft int .Fn msleep "void *chan" "struct mtx *mtx" "int priority" "const char *wmesg" "int timo" .Ft int -.Fn msleep_flags "void *chan" "struct mtx *mtx" "int priority" \ -"const char *wmesg" "int timo" "int flags" -.Ft int .Fn msleep_bt "void *chan" "struct mtx *mtx" "int priority" \ -"const char *wmesg" "struct bintime *bt" "struct bintime *pr" +"const char *wmesg" "struct bintime bt" "struct bintime pr" "int flags" .Ft int .Fn msleep_spin "void *chan" "struct mtx *mtx" "const char *wmesg" "int timo" .Ft int -.Fn msleep_spin_flags "void *chan" "struct mtx *mtx" "const char *wmesg" \ -"int timo" "int flags" +.Fn msleep_spin_bt "void *chan" "struct mtx *mtx" "const char *wmesg" \ +"struct bintime bt" "struct bintime pr" "int flags" .Ft void .Fn pause "const char *wmesg" "int timo" .Ft void -.Fn pause_flags "const char *wmesg" "int timo" "int flags" -.Ft void -.Fn pause_bt "const char *wmesg" "struct bintime *bt" "struct bintime *pr" +.Fn pause_bt "const char *wmesg" "struct bintime bt" "struct bintime pr" \ + "int flags" .Ft int .Fn tsleep "void *chan" "int priority" "const char *wmesg" "int timo" .Ft int -.Fn tsleep_flags "void *chan" "int priority" "const char *wmesg" "int timo" \ -"int flags" -.Ft int .Fn tsleep_bt "void *chan" "int priority" "const char *wmesg" \ -"struct bintime *bt" "struct bintime *pr" +"struct bintime bt" "struct bintime pr" "int flags" .Ft void .Fn wakeup "void *chan" .Ft void @@ -177,8 +167,8 @@ then the sleep function will return The parameter .Fa flags allows to pass additional -.Fn callout_reset_flags -flags to specify relative event precision. +.Fn callout_reset_bt +flags. .Pp .Fn msleep_bt , .Fn pause_bt Modified: projects/calloutng/share/man/man9/sleepqueue.9 ============================================================================== --- projects/calloutng/share/man/man9/sleepqueue.9 Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/share/man/man9/sleepqueue.9 Fri Dec 21 11:08:44 2012 (r244533) @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 14, 2012 +.Dd December 21, 2012 .Dt SLEEPQUEUE 9 .Os .Sh NAME @@ -41,7 +41,6 @@ .Nm sleepq_remove , .Nm sleepq_signal , .Nm sleepq_set_timeout , -.Nm sleepq_set_timeout_flags , .Nm sleepq_set_timeout_bt , .Nm sleepq_sleepcnt , .Nm sleepq_timedwait , @@ -82,10 +81,8 @@ .Ft void .Fn sleepq_set_timeout "void *wchan" "int timo" .Ft void -.Fn sleepq_set_timeout_flags "void *wchan" "int timo" "int flags" -.Ft void -.Fn sleepq_set_timeout_bt "void *wchan" "struct bintime *bt" \ -"struct bintime *pr" +.Fn sleepq_set_timeout_bt "void *wchan" "struct bintime bt" \ +"struct bintime pr" "int flags" .Ft u_int .Fn sleepq_sleepcnt "void *wchan" "int queue" .Ft int Modified: projects/calloutng/share/man/man9/timeout.9 ============================================================================== --- projects/calloutng/share/man/man9/timeout.9 Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/share/man/man9/timeout.9 Fri Dec 21 11:08:44 2012 (r244533) @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 16, 2012 +.Dd December 21, 2012 .Dt TIMEOUT 9 .Os .Sh NAME @@ -42,11 +42,11 @@ .Nm callout_stop , .Nm callout_drain , .Nm callout_reset , -.Nm callout_reset_flags , .Nm callout_reset_on , -.Nm callout_reset_flags_on , -.Nm callout_reset_bt_on , .Nm callout_reset_curcpu , +.Nm callout_reset_bt , +.Nm callout_reset_bt_on , +.Nm callout_reset_bt_curcpu , .Nm callout_schedule , .Nm callout_schedule_on , .Nm callout_schedule_curcpu , @@ -82,17 +82,11 @@ struct callout_handle handle = CALLOUT_H .Ft int .Fn callout_reset "struct callout *c" "int ticks" "timeout_t *func" "void *arg" .Ft int -.Fn callout_reset_flags "struct callout *c" "int ticks" "timeout_t *func" \ -"void *arg" "int flags" -.Ft int .Fn callout_reset_on "struct callout *c" "int ticks" "timeout_t *func" \ "void *arg" "int cpu" .Ft int -.Fn callout_reset_flags_on "struct callout *c" "int ticks" "timeout_t *func" \ -"void *arg" "int cpu" "int flags" -.Ft int -.Fn callout_reset_bt_on "struct callout *c" "struct bintime *bt" \ -"struct bintime *pr" "timeout_t *func" "void *arg" "int cpu" "int flags" +.Fn callout_reset_bt_on "struct callout *c" "struct bintime bt" \ +"struct bintime pr" "timeout_t *func" "void *arg" "int cpu" "int flags" .Ft int .Fn callout_reset_curcpu "struct callout *c" "int ticks" "timeout_t *func" \ "void *arg" @@ -339,38 +333,38 @@ and but take an extra parameter specifying the target CPU for the callout. .Pp The function -.Fn callout_reset_flags_on -is equivalent to -.Fn callout_reset_on -but takes an extra parameter -.Fa flags . +.Fn callout_reset_bt_on +allows to get higher time resolution, taking absolute time since boot +in form of struct bintime *, as returned by +.Fn binuptime +or +.Fn getbinuptime +functions, and precision, instead of relative ticks count. +If specified time is in past, it will be silently converted to present +to run handler as soon as possible. +.Pp The following .Fa flags may be specified: .Bl -tag -width ".Dv C_DIRECT_EXEC" +.It Dv C_ALSOLUTE +Handle the +.Fa bt +argument as absolute time of the event since boot, as returned by +.Fn binuptime +function. .It Dv C_DIRECT_EXEC Run handler directly from hardware interrupt context instead of softclock swi. It is faster, but puts more constraints on handlers. Handlers may use only spin mutexes for locking, and they must be fast because they run with absolute priority. -.It Fn C_PRELSET +.It Fn C_PREL Specifies relative event time precision as binary logarithm of time interval divided by acceptable time deviation: 1 -- 1/2, 2 -- 1/4, etc. Smaller value allows to aggregate more events in one timer interrupt to reduce processing overhead and power consumption. .El .Pp -The function -.Fn callout_reset_bt_on -allows to get higher time resolution, taking absolute time since boot -in form of struct bintime *, as returned by -.Fn binuptime -or -.Fn getbinuptime -functions, and precision, instead of relative ticks count. -If specified time is in past, it will be silently converted to present -to run handler as soon as possible. -.Pp The functions .Fn callout_reset_curcpu and Modified: projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c ============================================================================== --- projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c Fri Dec 21 11:08:44 2012 (r244533) @@ -198,7 +198,8 @@ atkbdtimeout(void *arg) if (kbdd_check_char(kbd)) kbdd_intr(kbd, NULL); } - callout_reset_flags(&sc->callout, hz, atkbdtimeout, dev, C_PRELSET(0)); + callout_reset_bt(&sc->callout, ticks2bintime(hz), zero_bt, + atkbdtimeout, dev, C_PREL(0) | C_HARDCLOCK); } DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0); Modified: projects/calloutng/sys/dev/random/randomdev_soft.c ============================================================================== --- projects/calloutng/sys/dev/random/randomdev_soft.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/dev/random/randomdev_soft.c Fri Dec 21 11:08:44 2012 (r244533) @@ -282,8 +282,9 @@ random_kthread(void *arg __unused) random_kthread_control = 0; /* Work done, so don't belabour the issue */ - msleep_spin_flags(&random_kthread_control, &harvest_mtx, - "-", hz / 10, C_PRELSET(1)); + msleep_spin_bt(&random_kthread_control, &harvest_mtx, + "-", ticks2bintime(hz / 10), zero_bt, + C_PREL(1) | C_HARDCLOCK); } mtx_unlock_spin(&harvest_mtx); Modified: projects/calloutng/sys/dev/syscons/syscons.c ============================================================================== --- projects/calloutng/sys/dev/syscons/syscons.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/dev/syscons/syscons.c Fri Dec 21 11:08:44 2012 (r244533) @@ -1899,8 +1899,8 @@ done: rate = 2; else rate = 30; - callout_reset_flags(&sc->ctimeout, hz / rate, scrn_timer, sc, - C_PRELSET(1)); + callout_reset_bt(&sc->ctimeout, ticks2bintime(hz / rate), zero_bt, + scrn_timer, sc, C_PREL(1) | C_HARDCLOCK); } } @@ -3845,8 +3845,8 @@ blink_screen(void *arg) (*scp->rndr->draw)(scp, 0, scp->xsize*scp->ysize, scp->sc->blink_in_progress & 1); scp->sc->blink_in_progress--; - callout_reset_flags(&scp->sc->cblink, hz / 15, blink_screen, scp, - C_PRELSET(0)); + callout_reset_bt(&scp->sc->cblink, ticks2bintime(hz / 15), zero_bt, + blink_screen, scp, C_PREL(0) | C_HARDCLOCK); } } Modified: projects/calloutng/sys/kern/kern_condvar.c ============================================================================== --- projects/calloutng/sys/kern/kern_condvar.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_condvar.c Fri Dec 21 11:08:44 2012 (r244533) @@ -274,8 +274,8 @@ _cv_wait_sig(struct cv *cvp, struct lock * cv_signal or cv_broadcast, EWOULDBLOCK if the timeout expires. */ int -_cv_timedwait(struct cv *cvp, struct lock_object *lock, struct bintime *bt, - struct bintime *precision, int timo, int flags) +_cv_timedwait_bt(struct cv *cvp, struct lock_object *lock, struct bintime bt, + struct bintime pr, int flags) { WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; @@ -311,10 +311,7 @@ _cv_timedwait(struct cv *cvp, struct loc DROP_GIANT(); sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR, 0); - if (bt == NULL) - sleepq_set_timeout_flags(cvp, timo, flags); - else - sleepq_set_timeout_bt(cvp, bt, precision); + sleepq_set_timeout_bt(cvp, bt, pr, flags); if (lock != &Giant.lock_object) { if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); @@ -345,8 +342,8 @@ _cv_timedwait(struct cv *cvp, struct loc * or ERESTART if a signal was caught. */ int -_cv_timedwait_sig(struct cv *cvp, struct lock_object *lock, - struct bintime *bt, struct bintime *precision, int timo, int flags) +_cv_timedwait_sig_bt(struct cv *cvp, struct lock_object *lock, + struct bintime bt, struct bintime pr, int flags) { WITNESS_SAVE_DECL(lock_witness); struct lock_class *class; @@ -383,10 +380,7 @@ _cv_timedwait_sig(struct cv *cvp, struct sleepq_add(cvp, lock, cvp->cv_description, SLEEPQ_CONDVAR | SLEEPQ_INTERRUPTIBLE, 0); - if (bt == NULL) - sleepq_set_timeout_flags(cvp, timo, flags); - else - sleepq_set_timeout_bt(cvp, bt, precision); + sleepq_set_timeout_bt(cvp, bt, pr, flags); if (lock != &Giant.lock_object) { if (class->lc_flags & LC_SLEEPABLE) sleepq_release(cvp); Modified: projects/calloutng/sys/kern/kern_event.c ============================================================================== --- projects/calloutng/sys/kern/kern_event.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_event.c Fri Dec 21 11:08:44 2012 (r244533) @@ -520,19 +520,16 @@ knote_fork(struct knlist *list, int pid) static struct bintime timer2bintime(intptr_t data) { - struct bintime bt, pbt; + struct bintime bt; - getbinuptime(&pbt); bt.sec = data / 1000; - bt.frac = (data % 1000) * (uint64_t)1844674407309552ULL; - bintime_add(&bt, &pbt); + bt.frac = (data % 1000) * (((uint64_t)1 << 63) / 500); return bt; } static void filt_timerexpire(void *knx) { - struct bintime bt; struct callout *calloutp; struct knote *kn; @@ -548,10 +545,10 @@ filt_timerexpire(void *knx) * when we're delayed. */ if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) { - bt = timer2bintime(kn->kn_sdata); calloutp = (struct callout *)kn->kn_hook; - callout_reset_bt_on(calloutp, &bt, NULL, filt_timerexpire, kn, - PCPU_GET(cpuid), 0); + callout_reset_bt_on(calloutp, + timer2bintime(kn->kn_sdata), zero_bt /* 1ms? */, + filt_timerexpire, kn, PCPU_GET(cpuid), 0); } } @@ -561,7 +558,6 @@ filt_timerexpire(void *knx) static int filt_timerattach(struct knote *kn) { - struct bintime bt; struct callout *calloutp; atomic_add_int(&kq_ncallouts, 1); @@ -576,9 +572,9 @@ filt_timerattach(struct knote *kn) calloutp = malloc(sizeof(*calloutp), M_KQUEUE, M_WAITOK); callout_init(calloutp, CALLOUT_MPSAFE); kn->kn_hook = calloutp; - bt = timer2bintime(kn->kn_sdata); - callout_reset_bt_on(calloutp, &bt, NULL, filt_timerexpire, kn, - PCPU_GET(cpuid), 0); + callout_reset_bt_on(calloutp, + timer2bintime(kn->kn_sdata), zero_bt /* 1ms? */, + filt_timerexpire, kn, PCPU_GET(cpuid), 0); return (0); } @@ -1323,9 +1319,9 @@ kqueue_scan(struct kqueue *kq, int maxev const struct timespec *tsp, struct kevent *keva, struct thread *td) { struct kevent *kevp; - struct timeval atv, rtv, ttv; + struct bintime abt, rbt; struct knote *kn, *marker; - int count, timeout, nkev, error, influx; + int count, nkev, error, influx; int haskqglobal, touch; count = maxevents; @@ -1337,22 +1333,24 @@ kqueue_scan(struct kqueue *kq, int maxev goto done_nl; if (tsp != NULL) { - TIMESPEC_TO_TIMEVAL(&atv, tsp); - if (itimerfix(&atv)) { + if (tsp->tv_sec < 0 || tsp->tv_nsec < 0 || + tsp->tv_nsec > 1000000000) { error = EINVAL; goto done_nl; } - if (tsp->tv_sec == 0 && tsp->tv_nsec == 0) - timeout = -1; - else - timeout = atv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&atv); - getmicrouptime(&rtv); - timevaladd(&atv, &rtv); + if (timespecisset(tsp)) { + timespec2bintime(tsp, &rbt); + if (TIMESEL(&abt, &rbt)) + bintime_add(&abt, &tc_tick_bt); + bintime_add(&abt, &rbt); + bintime_shift(&rbt, -tc_timeexp); + } else { + abt.sec = -1; + abt.frac = 0; + } } else { - atv.tv_sec = 0; - atv.tv_usec = 0; - timeout = 0; + abt.sec = 0; + abt.frac = 0; } marker = knote_alloc(1); if (marker == NULL) { @@ -1361,28 +1359,16 @@ kqueue_scan(struct kqueue *kq, int maxev } marker->kn_status = KN_MARKER; KQ_LOCK(kq); - goto start; retry: - if (atv.tv_sec || atv.tv_usec) { - getmicrouptime(&rtv); - if (timevalcmp(&rtv, &atv, >=)) - goto done; - ttv = atv; - timevalsub(&ttv, &rtv); - timeout = ttv.tv_sec > 24 * 60 * 60 ? - 24 * 60 * 60 * hz : tvtohz(&ttv); - } - -start: kevp = keva; if (kq->kq_count == 0) { - if (timeout < 0) { + if (abt.sec < 0) { error = EWOULDBLOCK; } else { kq->kq_state |= KQ_SLEEP; - error = msleep(kq, &kq->kq_lock, PSOCK | PCATCH, - "kqread", timeout); + error = msleep_bt(kq, &kq->kq_lock, PSOCK | PCATCH, + "kqread", abt, rbt, C_ABSOLUTE); } if (error == 0) goto retry; Modified: projects/calloutng/sys/kern/kern_resource.c ============================================================================== --- projects/calloutng/sys/kern/kern_resource.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_resource.c Fri Dec 21 11:08:44 2012 (r244533) @@ -645,7 +645,8 @@ lim_cb(void *arg) } } if ((p->p_flag & P_WEXIT) == 0) - callout_reset_flags(&p->p_limco, hz, lim_cb, p, C_PRELSET(1)); + callout_reset_bt(&p->p_limco, ticks2bintime(hz), zero_bt, + lim_cb, p, C_PREL(1) | C_HARDCLOCK); } int @@ -697,8 +698,8 @@ kern_proc_setrlimit(struct thread *td, s case RLIMIT_CPU: if (limp->rlim_cur != RLIM_INFINITY && p->p_cpulimit == RLIM_INFINITY) - callout_reset_flags(&p->p_limco, hz, lim_cb, p, - C_PRELSET(1)); + callout_reset_bt(&p->p_limco, ticks2bintime(hz), zero_bt, + lim_cb, p, C_PREL(1) | C_HARDCLOCK); p->p_cpulimit = limp->rlim_cur; break; case RLIMIT_DATA: @@ -1138,7 +1139,8 @@ lim_fork(struct proc *p1, struct proc *p p2->p_limit = lim_hold(p1->p_limit); callout_init_mtx(&p2->p_limco, &p2->p_mtx, 0); if (p1->p_cpulimit != RLIM_INFINITY) - callout_reset_flags(&p2->p_limco, hz, lim_cb, p2, C_PRELSET(1)); + callout_reset_bt(&p2->p_limco, ticks2bintime(hz), zero_bt, + lim_cb, p2, C_PREL(1) | C_HARDCLOCK); } void Modified: projects/calloutng/sys/kern/kern_synch.c ============================================================================== --- projects/calloutng/sys/kern/kern_synch.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_synch.c Fri Dec 21 11:08:44 2012 (r244533) @@ -146,8 +146,7 @@ sleepinit(void) */ int _sleep(void *ident, struct lock_object *lock, int priority, - const char *wmesg, int timo, struct bintime *bt, - struct bintime *precision, int flags) + const char *wmesg, struct bintime bt, struct bintime pr, int flags) { struct thread *td; struct proc *p; @@ -163,7 +162,7 @@ _sleep(void *ident, struct lock_object * #endif WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, "Sleeping on \"%s\"", wmesg); - KASSERT(timo != 0 || bt != NULL || mtx_owned(&Giant) || lock != NULL, + KASSERT(bintime_isset(&bt) || mtx_owned(&Giant) || lock != NULL, ("sleeping without a lock")); KASSERT(p != NULL, ("msleep1")); KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep")); @@ -233,19 +232,17 @@ _sleep(void *ident, struct lock_object * * return from cursig(). */ sleepq_add(ident, lock, wmesg, sleepq_flags, 0); - if (bt) - sleepq_set_timeout_bt(ident, bt, precision); - else if (timo) - sleepq_set_timeout_flags(ident, timo, flags); + if (bintime_isset(&bt)) + sleepq_set_timeout_bt(ident, bt, pr, flags); if (lock != NULL && class->lc_flags & LC_SLEEPABLE) { sleepq_release(ident); WITNESS_SAVE(lock, lock_witness); lock_state = class->lc_unlock(lock); sleepq_lock(ident); } - if ((timo != 0 || bt != NULL) && catch) + if (bintime_isset(&bt) && catch) rval = sleepq_timedwait_sig(ident, pri); - else if (timo != 0 || bt != NULL) + else if (bintime_isset(&bt)) rval = sleepq_timedwait(ident, pri); else if (catch) rval = sleepq_wait_sig(ident, pri); @@ -266,8 +263,8 @@ _sleep(void *ident, struct lock_object * } int -msleep_spin_flags(void *ident, struct mtx *mtx, const char *wmesg, int timo, - int flags) +msleep_spin_bt(void *ident, struct mtx *mtx, const char *wmesg, + struct bintime bt, struct bintime pr, int flags) { struct thread *td; struct proc *p; @@ -305,8 +302,8 @@ msleep_spin_flags(void *ident, struct mt * We put ourselves on the sleep queue and start our timeout. */ sleepq_add(ident, &mtx->lock_object, wmesg, SLEEPQ_SLEEP, 0); - if (timo) - sleepq_set_timeout_flags(ident, timo, flags); + if (bintime_isset(&bt)) + sleepq_set_timeout_bt(ident, bt, pr, flags); /* * Can't call ktrace with any spin locks held so it can lock the @@ -328,7 +325,7 @@ msleep_spin_flags(void *ident, struct mt wmesg); sleepq_lock(ident); #endif - if (timo) + if (bintime_isset(&bt)) rval = sleepq_timedwait(ident, 0); else { sleepq_wait(ident, 0); @@ -352,37 +349,28 @@ msleep_spin_flags(void *ident, struct mt * to a "timo" value of one. */ int -_pause(const char *wmesg, int timo, struct bintime *bt, struct bintime *pr, - int flags) +pause_bt(const char *wmesg, struct bintime bt, struct bintime pr, int flags) { - struct bintime now, bt2; - KASSERT(timo >= 0, ("pause: timo must be >= 0")); + KASSERT(bt.sec >= 0, ("pause: timo must be >= 0")); /* silently convert invalid timeouts */ - if (timo < 1) - timo = 1; + if (!bintime_isset(&bt)) + bt = tick_bt; if (cold) { - if (bt != NULL) { - binuptime(&now); - bt2 = *bt; - bintime_sub(&bt2, &now); - timo = bt2.sec * hz + ((bt2.frac >> 32) * hz >> 32); - } /* - * We delay one HZ at a time to avoid overflowing the + * We delay one second at a time to avoid overflowing the * system specific DELAY() function(s): */ - while (timo >= hz) { + while (bt.sec > 0) { DELAY(1000000); - timo -= hz; + bt.sec--; } - if (timo > 0) - DELAY(timo * tick); + DELAY(bt.frac >> 44); return (0); } - return (_sleep(&pause_wchan, NULL, 0, wmesg, timo, bt, pr, flags)); + return (_sleep(&pause_wchan, NULL, 0, wmesg, bt, pr, flags)); } /* @@ -573,9 +561,9 @@ loadav(void *arg) * random variation to avoid synchronisation with processes that * run at regular intervals. */ - callout_reset_flags(&loadav_callout, - hz * 4 + (int)(random() % (hz * 2 + 1)), - loadav, NULL, C_DIRECT_EXEC); + callout_reset_bt(&loadav_callout, + ticks2bintime(hz * 4 + (int)(random() % (hz * 2 + 1))), zero_bt, + loadav, NULL, C_DIRECT_EXEC | C_HARDCLOCK); } /* ARGSUSED */ Modified: projects/calloutng/sys/kern/kern_tc.c ============================================================================== --- projects/calloutng/sys/kern/kern_tc.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_tc.c Fri Dec 21 11:08:44 2012 (r244533) @@ -121,11 +121,11 @@ SYSCTL_INT(_kern_timecounter, OID_AUTO, ×tepwarnings, 0, "Log time steps"); struct bintime bt_timethreshold; +struct bintime bt_tickthreshold; struct bintime tc_tick_bt; int tc_timeexp; int tc_timepercentage = TC_DEFAULTPERC; TUNABLE_INT("kern.timecounter.alloweddeviation", &tc_timepercentage); -int tc_timethreshold; static int sysctl_kern_timecounter_adjprecision(SYSCTL_HANDLER_ARGS); SYSCTL_PROC(_kern_timecounter, OID_AUTO, alloweddeviation, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, @@ -1721,22 +1721,20 @@ tc_ticktock(int cnt) static void __inline tc_adjprecision(void) { - struct timespec ts; - int tick_rate, t; + int t; - tick_rate = hz / tc_tick; if (tc_timepercentage > 0) { - tc_timethreshold = - (1000000000 / (tick_rate * tc_timepercentage)) * 100; t = (99 + tc_timepercentage) / tc_timepercentage; tc_timeexp = fls(t + (t >> 1)) - 1; + FREQ2BT(hz / tc_tick, &bt_timethreshold); + FREQ2BT(hz, &bt_tickthreshold); + bintime_shift(&bt_timethreshold, tc_timeexp); + bintime_shift(&bt_tickthreshold, tc_timeexp); } else { - tc_timethreshold = INT_MAX; tc_timeexp = 31; + bintime_clear(&bt_timethreshold); + bintime_clear(&bt_tickthreshold); } - ts.tv_sec = tc_timethreshold / 1000000000; - ts.tv_nsec = tc_timethreshold % 1000000000; - timespec2bintime(&ts, &bt_timethreshold); } static int Modified: projects/calloutng/sys/kern/kern_time.c ============================================================================== --- projects/calloutng/sys/kern/kern_time.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_time.c Fri Dec 21 11:08:44 2012 (r244533) @@ -492,15 +492,16 @@ kern_nanosleep(struct thread *td, struct return (0); timespec2bintime(rqt, &tmp); bt_prec = tmp; - bintime_divpow2(&bt_prec, tc_timeexp); + bintime_shift(&bt_prec, -tc_timeexp); if (TIMESEL(&bt, &tmp)) bintime_add(&bt, &tc_tick_bt); bintime_add(&bt, &tmp); - error = tsleep_bt(&nanowait, PWAIT | PCATCH, "nanslp", &bt, &bt_prec); - TIMESEL(&btt, &tmp); + error = tsleep_bt(&nanowait, PWAIT | PCATCH, "nanslp", bt, bt_prec, + C_ABSOLUTE); if (error != EWOULDBLOCK) { if (error == ERESTART) error = EINTR; + TIMESEL(&btt, &tmp); if (rmt != NULL) { tmp = bt; bintime_sub(&tmp, &btt); Modified: projects/calloutng/sys/kern/kern_timeout.c ============================================================================== --- projects/calloutng/sys/kern/kern_timeout.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/kern_timeout.c Fri Dec 21 11:08:44 2012 (r244533) @@ -896,44 +896,47 @@ DPCPU_DECLARE(struct bintime, hardclockt * callout_deactivate() - marks the callout as having been serviced */ int -_callout_reset_on(struct callout *c, struct bintime *bt, - struct bintime *precision, int to_ticks, void (*ftn)(void *), - void *arg, int cpu, int flags) +callout_reset_bt_on(struct callout *c, struct bintime bt, struct bintime pr, + void (*ftn)(void *), void *arg, int cpu, int flags) { - struct bintime to_bt, pr; + struct bintime to_bt, pr1; struct callout_cpu *cc; int bucket, cancelled, direct; cancelled = 0; - if (bt == NULL) { + if (flags & C_ABSOLUTE) { + to_bt = bt; + } else { + if ((flags & C_HARDCLOCK) || #ifdef NO_EVENTTIMERS - getbinuptime(&to_bt); - /* Add safety belt for the case of hz > 1000. */ - bintime_addx(&to_bt, tc_tick_bt.frac - tick_bt.frac); + bintime_cmp(&bt, &bt_timethreshold, >=)) { + getbinuptime(&to_bt); + /* Add safety belt for the case of hz > 1000. */ + bintime_addx(&to_bt, tc_tick_bt.frac - tick_bt.frac); #else - /* - * Obtain the time of the last hardclock() call on this CPU - * directly from the kern_clocksource.c. This value is - * per-CPU, but it is equal for all active ones. - */ - spinlock_enter(); - to_bt = DPCPU_GET(hardclocktime); - spinlock_exit(); + bintime_cmp(&bt, &bt_tickthreshold, >=)) { + /* + * Obtain the time of the last hardclock() call on + * this CPU directly from the kern_clocksource.c. + * This value is per-CPU, but it is equal for all + * active ones. + */ + spinlock_enter(); + to_bt = DPCPU_GET(hardclocktime); + spinlock_exit(); #endif - pr = tick_bt; - if (to_ticks > 1) - bintime_mul(&pr, to_ticks); - bintime_add(&to_bt, &pr); + if ((flags & C_HARDCLOCK) == 0) + bintime_addx(&to_bt, tick_bt.frac); + } else + binuptime(&to_bt); + bintime_add(&to_bt, &bt); + pr1 = bt; if (C_PRELGET(flags) < 0) - bintime_clear(&pr); - else - bintime_divpow2(&pr, C_PRELGET(flags)); - } else { - to_bt = *bt; - if (precision != NULL) - pr = *precision; + bintime_shift(&pr1, -tc_timeexp); else - bintime_clear(&pr); + bintime_shift(&pr1, -C_PRELGET(flags)); + if (bintime_cmp(&pr1, &pr, >)) + pr = pr1; } /* * Don't allow migration of pre-allocated callouts lest they Modified: projects/calloutng/sys/kern/subr_log.c ============================================================================== --- projects/calloutng/sys/kern/subr_log.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/subr_log.c Fri Dec 21 11:08:44 2012 (r244533) @@ -117,8 +117,9 @@ logopen(struct cdev *dev, int flags, int return (EBUSY); } log_open = 1; - callout_reset_flags(&logsoftc.sc_callout, hz / log_wakeups_per_second, - logtimeout, NULL, C_PRELSET(1)); + callout_reset_bt(&logsoftc.sc_callout, + ticks2bintime(hz / log_wakeups_per_second), zero_bt, + logtimeout, NULL, C_PREL(1) | C_HARDCLOCK); mtx_unlock(&msgbuf_lock); fsetown(td->td_proc->p_pid, &logsoftc.sc_sigio); /* signal process only */ @@ -246,8 +247,9 @@ done: printf("syslog wakeup is less than one. Adjusting to 1.\n"); log_wakeups_per_second = 1; } - callout_reset_flags(&logsoftc.sc_callout, hz / log_wakeups_per_second, - logtimeout, NULL, C_PRELSET(1)); + callout_reset_bt(&logsoftc.sc_callout, + ticks2bintime(hz / log_wakeups_per_second), zero_bt, + logtimeout, NULL, C_PREL(1) | C_HARDCLOCK); } /*ARGSUSED*/ Modified: projects/calloutng/sys/kern/subr_param.c ============================================================================== --- projects/calloutng/sys/kern/subr_param.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/subr_param.c Fri Dec 21 11:08:44 2012 (r244533) @@ -84,6 +84,7 @@ static int sysctl_kern_vm_guest(SYSCTL_H int hz; /* system clock's frequency */ int tick; /* usec per tick (1000000 / hz) */ struct bintime tick_bt; /* bintime per tick (1s / hz) */ +struct bintime zero_bt = { 0, 0 }; /* bintime per tick (1s / hz) */ int maxusers; /* base tunable */ int maxproc; /* maximum # of processes */ int maxprocperuid; /* max # of procs per user */ Modified: projects/calloutng/sys/kern/subr_sleepqueue.c ============================================================================== --- projects/calloutng/sys/kern/subr_sleepqueue.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/subr_sleepqueue.c Fri Dec 21 11:08:44 2012 (r244533) @@ -363,8 +363,8 @@ sleepq_add(void *wchan, struct lock_obje * sleep queue after timo ticks if the thread has not already been awakened. */ void -_sleepq_set_timeout(void *wchan, struct bintime *bt, struct bintime *precision, - int timo, int flags) +sleepq_set_timeout_bt(void *wchan, struct bintime bt, struct bintime pr, + int flags) { struct sleepqueue_chain *sc; @@ -376,12 +376,8 @@ _sleepq_set_timeout(void *wchan, struct MPASS(TD_ON_SLEEPQ(td)); MPASS(td->td_sleepqueue == NULL); MPASS(wchan != NULL); - if (bt == NULL) - callout_reset_flags_on(&td->td_slpcallout, timo, - sleepq_timeout, td, PCPU_GET(cpuid), flags | C_DIRECT_EXEC); - else - callout_reset_bt_on(&td->td_slpcallout, bt, precision, - sleepq_timeout, td, PCPU_GET(cpuid), flags | C_DIRECT_EXEC); + callout_reset_bt_on(&td->td_slpcallout, bt, pr, + sleepq_timeout, td, PCPU_GET(cpuid), flags | C_DIRECT_EXEC); } /* Modified: projects/calloutng/sys/kern/sys_generic.c ============================================================================== --- projects/calloutng/sys/kern/sys_generic.c Fri Dec 21 10:09:45 2012 (r244532) +++ projects/calloutng/sys/kern/sys_generic.c Fri Dec 21 11:08:44 2012 (r244533) @@ -102,7 +102,7 @@ static int dofilewrite(struct thread *, off_t, int); static void doselwakeup(struct selinfo *, int); static void seltdinit(struct thread *); -static int seltdwait(struct thread *, struct bintime *, struct bintime *); +static int seltdwait(struct thread *, struct bintime); static void seltdclear(struct thread *); /* @@ -902,12 +902,11 @@ kern_select(struct thread *td, int nd, f */ fd_mask s_selbits[howmany(2048, NFDBITS)]; fd_mask *ibits[3], *obits[3], *selbits, *sbp; - struct bintime abt, precision, rbt; - struct timeval atv; + struct bintime rbt; + struct timeval rtv; int error, lf, ndu; u_int nbufbytes, ncpbytes, ncpubytes, nfdbits; - timevalclear(&atv); if (nd < 0) return (EINVAL); fdp = td->td_proc->p_fd; @@ -997,43 +996,26 @@ kern_select(struct thread *td, int nd, f bzero(selbits, nbufbytes / 2); if (tvp != NULL) { - atv = *tvp; - if (atv.tv_sec < 0 || atv.tv_usec < 0 || - atv.tv_usec >= 1000000) { + rtv = *tvp; + if (rtv.tv_sec < 0 || rtv.tv_usec < 0 || + rtv.tv_usec >= 1000000) { error = EINVAL; goto done; } - timeval2bintime(&atv, &abt); - precision = abt; - bintime_divpow2(&precision, tc_timeexp); - if (TIMESEL(&rbt, &abt)) - bintime_add(&abt, &tc_tick_bt); - bintime_add(&abt, &rbt); + timeval2bintime(&rtv, &rbt); } else { - abt.sec = 0; - abt.frac = 0; + rbt.sec = -1; + rbt.frac = 0; } seltdinit(td); - /* Iterate until the timeout expires or descriptors become ready. */ - for (;;) { - error = selscan(td, ibits, obits, nd); - if (error || td->td_retval[0] != 0) - break; - if (abt.sec || abt.frac) { - TIMESEL(&rbt, &abt); - if (bintime_cmp(&rbt, &abt, >=)) - break; - error = seltdwait(td, &abt, &precision); - } - else { - error = seltdwait(td, NULL, NULL); - } - if (error) - break; - error = selrescan(td, ibits, obits); - if (error || td->td_retval[0] != 0) - break; - } + error = selscan(td, ibits, obits, nd); + if (error || td->td_retval[0] != 0) + goto done1; + error = seltdwait(td, rbt); + if (error) + goto done1; + error = selrescan(td, ibits, obits); +done1: seltdclear(td); done: @@ -1259,13 +1241,11 @@ sys_poll(td, uap) { struct pollfd *bits; struct pollfd smallbits[32]; - struct bintime abt, precision, rbt; - struct timeval atv; + struct bintime rbt; int error; u_int nfds; size_t ni; - timevalclear(&atv); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212211108.qBLB8jwa047382>