-/* $OpenBSD: kern_clock.c,v 1.120 2023/10/11 15:42:44 cheloha Exp $ */
+/* $OpenBSD: kern_clock.c,v 1.121 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: kern_clock.c,v 1.34 1996/06/09 04:51:03 briggs Exp $ */
/*-
* do process and kernel statistics.
*/
void
-statclock(struct clockintr *cl, void *cf, void *arg)
+statclock(struct clockrequest *cr, void *cf, void *arg)
{
uint64_t count, i;
struct clockframe *frame = cf;
struct process *pr;
if (statclock_is_randomized) {
- count = clockintr_advance_random(cl, statclock_min,
+ count = clockrequest_advance_random(cr, statclock_min,
statclock_mask);
} else {
- count = clockintr_advance(cl, statclock_avg);
+ count = clockrequest_advance(cr, statclock_avg);
}
if (CLKF_USERMODE(frame)) {
-/* $OpenBSD: kern_clockintr.c,v 1.61 2023/10/11 15:07:04 cheloha Exp $ */
+/* $OpenBSD: kern_clockintr.c,v 1.62 2023/10/17 00:04:02 cheloha Exp $ */
/*
* Copyright (c) 2003 Dale Rahn <drahn@openbsd.org>
* Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
#include <sys/sysctl.h>
#include <sys/time.h>
-void clockintr_hardclock(struct clockintr *, void *, void *);
+void clockintr_hardclock(struct clockrequest *, void *, void *);
void clockintr_schedule_locked(struct clockintr *, uint64_t);
void clockqueue_intrclock_install(struct clockintr_queue *,
const struct intrclock *);
{
uint64_t lateness, run = 0, start;
struct cpu_info *ci = curcpu();
- struct clockintr *cl, *shadow;
+ struct clockintr *cl;
struct clockintr_queue *cq = &ci->ci_queue;
+ struct clockrequest *request = &cq->cq_request;
+ void *arg;
+ void (*func)(struct clockrequest *, void *, void *);
uint32_t ogen;
if (cq->cq_dispatch != 0)
}
/*
- * This clockintr has expired. Initialize a shadow copy
- * and execute it.
+ * This clockintr has expired. Execute it.
*/
clockqueue_pend_delete(cq, cl);
- shadow = &cq->cq_shadow;
- shadow->cl_expiration = cl->cl_expiration;
- shadow->cl_arg = cl->cl_arg;
- shadow->cl_func = cl->cl_func;
+ request->cr_expiration = cl->cl_expiration;
+ arg = cl->cl_arg;
+ func = cl->cl_func;
cq->cq_running = cl;
mtx_leave(&cq->cq_mtx);
- shadow->cl_func(shadow, frame, shadow->cl_arg);
+ func(request, frame, arg);
mtx_enter(&cq->cq_mtx);
cq->cq_running = NULL;
- if (ISSET(cl->cl_flags, CLST_IGNORE_SHADOW)) {
- CLR(cl->cl_flags, CLST_IGNORE_SHADOW);
- CLR(shadow->cl_flags, CLST_SHADOW_PENDING);
+ if (ISSET(cl->cl_flags, CLST_IGNORE_REQUEST)) {
+ CLR(cl->cl_flags, CLST_IGNORE_REQUEST);
+ CLR(request->cr_flags, CR_RESCHEDULE);
}
- if (ISSET(shadow->cl_flags, CLST_SHADOW_PENDING)) {
- CLR(shadow->cl_flags, CLST_SHADOW_PENDING);
- clockqueue_pend_insert(cq, cl, shadow->cl_expiration);
+ if (ISSET(request->cr_flags, CR_RESCHEDULE)) {
+ CLR(request->cr_flags, CR_RESCHEDULE);
+ clockqueue_pend_insert(cq, cl, request->cr_expiration);
}
run++;
}
uint64_t count, expiration;
struct clockintr_queue *cq = cl->cl_queue;
- if (cl == &cq->cq_shadow) {
- count = nsec_advance(&cl->cl_expiration, period, cq->cq_uptime);
- SET(cl->cl_flags, CLST_SHADOW_PENDING);
- } else {
- mtx_enter(&cq->cq_mtx);
- expiration = cl->cl_expiration;
- count = nsec_advance(&expiration, period, nsecuptime());
- clockintr_schedule_locked(cl, expiration);
- mtx_leave(&cq->cq_mtx);
- }
+ mtx_enter(&cq->cq_mtx);
+ expiration = cl->cl_expiration;
+ count = nsec_advance(&expiration, period, nsecuptime());
+ clockintr_schedule_locked(cl, expiration);
+ mtx_leave(&cq->cq_mtx);
+
return count;
}
uint64_t
-clockintr_advance_random(struct clockintr *cl, uint64_t min, uint32_t mask)
+clockrequest_advance(struct clockrequest *cr, uint64_t period)
+{
+ struct clockintr_queue *cq = cr->cr_queue;
+
+ KASSERT(cr == &cq->cq_request);
+
+ SET(cr->cr_flags, CR_RESCHEDULE);
+ return nsec_advance(&cr->cr_expiration, period, cq->cq_uptime);
+}
+
+uint64_t
+clockrequest_advance_random(struct clockrequest *cr, uint64_t min,
+ uint32_t mask)
{
uint64_t count = 0;
- struct clockintr_queue *cq = cl->cl_queue;
+ struct clockintr_queue *cq = cr->cr_queue;
uint32_t off;
- KASSERT(cl == &cq->cq_shadow);
+ KASSERT(cr == &cq->cq_request);
- while (cl->cl_expiration <= cq->cq_uptime) {
+ while (cr->cr_expiration <= cq->cq_uptime) {
while ((off = (random() & mask)) == 0)
continue;
- cl->cl_expiration += min + off;
+ cr->cr_expiration += min + off;
count++;
}
- SET(cl->cl_flags, CLST_SHADOW_PENDING);
+ SET(cr->cr_flags, CR_RESCHEDULE);
return count;
}
struct clockintr_queue *cq = cl->cl_queue;
int was_next;
- if (cl == &cq->cq_shadow) {
- CLR(cl->cl_flags, CLST_SHADOW_PENDING);
- return;
- }
-
mtx_enter(&cq->cq_mtx);
if (ISSET(cl->cl_flags, CLST_PENDING)) {
was_next = cl == TAILQ_FIRST(&cq->cq_pend);
}
}
if (cl == cq->cq_running)
- SET(cl->cl_flags, CLST_IGNORE_SHADOW);
+ SET(cl->cl_flags, CLST_IGNORE_REQUEST);
mtx_leave(&cq->cq_mtx);
}
struct clockintr *
clockintr_establish(struct cpu_info *ci,
- void (*func)(struct clockintr *, void *, void *), void *arg)
+ void (*func)(struct clockrequest *, void *, void *), void *arg)
{
struct clockintr *cl;
struct clockintr_queue *cq = &ci->ci_queue;
{
struct clockintr_queue *cq = cl->cl_queue;
- if (cl == &cq->cq_shadow) {
- cl->cl_expiration = expiration;
- SET(cl->cl_flags, CLST_SHADOW_PENDING);
- } else {
- mtx_enter(&cq->cq_mtx);
- clockintr_schedule_locked(cl, expiration);
- mtx_leave(&cq->cq_mtx);
- }
+ mtx_enter(&cq->cq_mtx);
+ clockintr_schedule_locked(cl, expiration);
+ mtx_leave(&cq->cq_mtx);
}
void
}
}
if (cl == cq->cq_running)
- SET(cl->cl_flags, CLST_IGNORE_SHADOW);
+ SET(cl->cl_flags, CLST_IGNORE_REQUEST);
}
void
}
void
-clockintr_hardclock(struct clockintr *cl, void *frame, void *arg)
+clockintr_hardclock(struct clockrequest *cr, void *frame, void *arg)
{
uint64_t count, i;
- count = clockintr_advance(cl, hardclock_period);
+ count = clockrequest_advance(cr, hardclock_period);
for (i = 0; i < count; i++)
hardclock(frame);
}
if (ISSET(cq->cq_flags, CQ_INIT))
return;
- cq->cq_shadow.cl_queue = cq;
+ cq->cq_request.cr_queue = cq;
mtx_init(&cq->cq_mtx, IPL_CLOCK);
TAILQ_INIT(&cq->cq_all);
TAILQ_INIT(&cq->cq_pend);
-/* $OpenBSD: kern_time.c,v 1.166 2023/09/10 03:08:05 cheloha Exp $ */
+/* $OpenBSD: kern_time.c,v 1.167 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
}
void
-itimer_update(struct clockintr *cl, void *cf, void *arg)
+itimer_update(struct clockrequest *cr, void *cf, void *arg)
{
struct timespec elapsed;
uint64_t nsecs;
if (!ISSET(pr->ps_flags, PS_ITIMER))
return;
- nsecs = clockintr_advance(cl, hardclock_period) * hardclock_period;
+ nsecs = clockrequest_advance(cr, hardclock_period) * hardclock_period;
NSEC_TO_TIMESPEC(nsecs, &elapsed);
mtx_enter(&itimer_mtx);
-/* $OpenBSD: sched_bsd.c,v 1.88 2023/10/11 15:42:44 cheloha Exp $ */
+/* $OpenBSD: sched_bsd.c,v 1.89 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
/*-
* Force switch among equal priority processes every 100ms.
*/
void
-roundrobin(struct clockintr *cl, void *cf, void *arg)
+roundrobin(struct clockrequest *cr, void *cf, void *arg)
{
uint64_t count;
struct cpu_info *ci = curcpu();
struct schedstate_percpu *spc = &ci->ci_schedstate;
- count = clockintr_advance(cl, roundrobin_period);
+ count = clockrequest_advance(cr, roundrobin_period);
if (ci->ci_curproc != NULL) {
if (spc->spc_schedflags & SPCF_SEENRR || count >= 2) {
-/* $OpenBSD: subr_prof.c,v 1.39 2023/10/11 15:42:44 cheloha Exp $ */
+/* $OpenBSD: subr_prof.c,v 1.40 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: subr_prof.c,v 1.12 1996/04/22 01:38:50 christos Exp $ */
/*-
extern char etext[];
-void gmonclock(struct clockintr *, void *, void *);
+void gmonclock(struct clockrequest *, void *, void *);
void
prof_init(void)
}
void
-gmonclock(struct clockintr *cl, void *cf, void *arg)
+gmonclock(struct clockrequest *cr, void *cf, void *arg)
{
uint64_t count;
struct clockframe *frame = cf;
struct gmonparam *g = curcpu()->ci_gmon;
u_long i;
- count = clockintr_advance(cl, profclock_period);
+ count = clockrequest_advance(cr, profclock_period);
if (count > ULONG_MAX)
count = ULONG_MAX;
}
void
-profclock(struct clockintr *cl, void *cf, void *arg)
+profclock(struct clockrequest *cr, void *cf, void *arg)
{
uint64_t count;
struct clockframe *frame = cf;
struct proc *p = curproc;
- count = clockintr_advance(cl, profclock_period);
+ count = clockrequest_advance(cr, profclock_period);
if (count > ULONG_MAX)
count = ULONG_MAX;
-/* $OpenBSD: clockintr.h,v 1.22 2023/10/11 15:07:04 cheloha Exp $ */
+/* $OpenBSD: clockintr.h,v 1.23 2023/10/17 00:04:02 cheloha Exp $ */
/*
* Copyright (c) 2020-2022 Scott Cheloha <cheloha@openbsd.org>
*
#include <sys/mutex.h>
#include <sys/queue.h>
+struct clockrequest;
struct cpu_info;
/*
TAILQ_ENTRY(clockintr) cl_alink; /* [m] cq_all glue */
TAILQ_ENTRY(clockintr) cl_plink; /* [m] cq_pend glue */
void *cl_arg; /* [I] argument */
- void (*cl_func)(struct clockintr *, void *, void *); /* [I] callback */
+ void (*cl_func)(struct clockrequest *, void*, void*); /* [I] callback */
struct clockintr_queue *cl_queue; /* [I] parent queue */
uint32_t cl_flags; /* [m] CLST_* flags */
};
#define CLST_PENDING 0x00000001 /* scheduled to run */
-#define CLST_SHADOW_PENDING 0x00000002 /* shadow is scheduled to run */
-#define CLST_IGNORE_SHADOW 0x00000004 /* ignore shadow copy */
+#define CLST_IGNORE_REQUEST 0x00000002 /* ignore callback requests */
+
+/*
+ * Interface for callback rescheduling requests.
+ *
+ * Struct member protections:
+ *
+ * I Immutable after initialization.
+ * o Owned by a single CPU.
+ */
+struct clockrequest {
+ uint64_t cr_expiration; /* [o] copy of dispatch time */
+ struct clockintr_queue *cr_queue; /* [I] enclosing queue */
+ uint32_t cr_flags; /* [o] CR_* flags */
+};
+
+#define CR_RESCHEDULE 0x00000001 /* reschedule upon return */
/*
* Per-CPU clock interrupt state.
* o Owned by a single CPU.
*/
struct clockintr_queue {
- struct clockintr cq_shadow; /* [o] copy of running clockintr */
+ struct clockrequest cq_request; /* [o] callback request object */
struct mutex cq_mtx; /* [a] per-queue mutex */
uint64_t cq_uptime; /* [o] cached uptime */
TAILQ_HEAD(, clockintr) cq_all; /* [m] established clockintr list */
*/
uint64_t clockintr_advance(struct clockintr *, uint64_t);
-uint64_t clockintr_advance_random(struct clockintr *, uint64_t, uint32_t);
void clockintr_cancel(struct clockintr *);
struct clockintr *clockintr_establish(struct cpu_info *,
- void (*)(struct clockintr *, void *, void *), void *);
+ void (*)(struct clockrequest *, void *, void *), void *);
void clockintr_schedule(struct clockintr *, uint64_t);
void clockintr_stagger(struct clockintr *, uint64_t, uint32_t, uint32_t);
+uint64_t clockrequest_advance(struct clockrequest *, uint64_t);
+uint64_t clockrequest_advance_random(struct clockrequest *, uint64_t, uint32_t);
void clockqueue_init(struct clockintr_queue *);
int sysctl_clockintr(int *, u_int, void *, size_t *, void *, size_t);
-/* $OpenBSD: resourcevar.h,v 1.30 2023/10/11 15:42:44 cheloha Exp $ */
+/* $OpenBSD: resourcevar.h,v 1.31 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: resourcevar.h,v 1.12 1995/11/22 23:01:53 cgd Exp $ */
/*
#include <lib/libkern/libkern.h> /* for KASSERT() */
-struct clockintr;
-
extern uint64_t profclock_period;
void addupc_intr(struct proc *, u_long, u_long);
void addupc_task(struct proc *, u_long, u_int);
-void profclock(struct clockintr *, void *, void *);
+struct clockrequest;
+void profclock(struct clockrequest *, void *, void *);
void tuagg_locked(struct process *, struct proc *, const struct timespec *);
void tuagg(struct process *, struct proc *);
struct tusage;
-/* $OpenBSD: sched.h,v 1.65 2023/10/11 15:42:44 cheloha Exp $ */
+/* $OpenBSD: sched.h,v 1.66 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: sched.h,v 1.2 1999/02/28 18:14:58 ross Exp $ */
/*-
struct proc;
void schedclock(struct proc *);
-void roundrobin(struct clockintr *, void *, void *);
+struct clockrequest;
+void roundrobin(struct clockrequest *, void *, void *);
void scheduler_start(void);
void userret(struct proc *p);
-/* $OpenBSD: systm.h,v 1.168 2023/10/11 15:42:44 cheloha Exp $ */
+/* $OpenBSD: systm.h,v 1.169 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
struct clockframe;
void hardclock(struct clockframe *);
-struct clockintr;
-void statclock(struct clockintr *, void *, void *);
+struct clockrequest;
+void statclock(struct clockrequest *, void *, void *);
void initclocks(void);
void inittodr(time_t);
-/* $OpenBSD: time.h,v 1.65 2023/09/10 03:08:05 cheloha Exp $ */
+/* $OpenBSD: time.h,v 1.66 2023/10/17 00:04:02 cheloha Exp $ */
/* $NetBSD: time.h,v 1.18 1996/04/23 10:29:33 mycroft Exp $ */
/*
struct proc;
int clock_gettime(struct proc *, clockid_t, struct timespec *);
-struct clockintr;
-void itimer_update(struct clockintr *, void *, void *);
+struct clockrequest;
+void itimer_update(struct clockrequest *, void *, void *);
void cancel_all_itimers(void);
int settime(const struct timespec *);