Page MenuHomeFreeBSD

D27252.diff
No OneTemporary

D27252.diff

Index: sys/kern/subr_eventhandler.c
===================================================================
--- sys/kern/subr_eventhandler.c
+++ sys/kern/subr_eventhandler.c
@@ -37,6 +37,7 @@
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/systm.h>
+#include <sys/rmlock.h>
#include <sys/eventhandler.h>
static MALLOC_DEFINE(M_EVENTHANDLER, "eventhandler", "Event handler records");
@@ -317,3 +318,226 @@
return (list);
}
+
+/*
+ * Static event handler points.
+ */
+static void
+static_eventhandler_validate(struct static_eventhandler *seh)
+{
+ int i;
+
+ for (i = 0; i < seh->count; i++) {
+ if (seh->cb[i] != NULL) {
+ switch (seh->prio[i]) {
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ break;
+ default:
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ panic("seh %p bad priority %d at %d\n", seh, seh->prio[i], i);
+ break;
+ }
+ }
+ }
+
+ for (i = 1; i < seh->count; i++) {
+ if (seh->prio[i] < seh->prio[i - 1]) {
+ panic("seh %p unsorted priorities (%d < %d) at %d\n", seh,
+ seh->prio[i], seh->prio[i - 1], i);
+ }
+ }
+
+ for (i = seh->count; i < seh->size; i++) {
+ if (seh->cb[i] != NULL) {
+ panic("seh %p callback %p found past the end\n", seh,
+ seh->cb[i]);
+ }
+ if (seh->prio[i] != STATIC_EVENTHANDLER_PRIO_INVALID) {
+ panic("seh %p prio %d found past the end\n", seh,
+ seh->prio[i]);
+ }
+ }
+}
+
+static void
+static_eventhandler_assert_prio(struct static_eventhandler *seh,
+ enum static_eventhandler_prio prio)
+{
+
+ switch (prio) {
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ break;
+ default:
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ panic("invalid priority %d passed", prio);
+ break;
+ }
+}
+
+void
+static_eventhandler_init(struct static_eventhandler *seh)
+{
+
+ rms_init(&seh->lock, seh->ident);
+}
+
+void
+static_eventhandler_register(struct static_eventhandler *seh, void *pcb,
+ enum static_eventhandler_prio prio)
+{
+ static_eventhandler_cb **newcb, **tofree_cb, *cb;
+ size_t newsize;
+ enum static_eventhandler_prio *newprio, *tofree_prio;
+ int i;
+
+ static_eventhandler_assert_prio(seh, prio);
+
+ cb = (void *)pcb;
+ tofree_cb = NULL;
+ tofree_prio = NULL;
+ rms_wlock(&seh->lock);
+ MPASS(seh->count <= seh->size);
+ if (seh->cb == NULL) {
+ seh->size = 8;
+ seh->cb = malloc(sizeof(seh->cb[0]) * seh->size, M_EVENTHANDLER,
+ M_WAITOK | M_ZERO);
+ seh->prio = malloc(sizeof(seh->prio[0]) * seh->size, M_EVENTHANDLER,
+ M_WAITOK | M_ZERO);
+ } else if (seh->count == seh->size) {
+ newsize = seh->size * 2;
+ newcb = malloc(sizeof(seh->cb[0]) * newsize,
+ M_EVENTHANDLER, M_WAITOK | M_ZERO);
+ newprio = malloc(sizeof(seh->prio[0]) * newsize,
+ M_EVENTHANDLER, M_WAITOK | M_ZERO);
+ memcpy(newcb, seh->cb, sizeof(seh->cb[0]) * seh->size);
+ memcpy(newprio, seh->prio, sizeof(seh->prio[0]) * seh->size);
+
+ tofree_cb = seh->cb;
+ tofree_prio = seh->prio;
+ seh->cb = newcb;
+ seh->prio = newprio;
+ seh->size = newsize;
+ }
+
+ static_eventhandler_validate(seh);
+
+ for (i = 0; i < seh->size; i++) {
+ if (seh->cb[i] == cb)
+ panic("callback %p already registered", cb);
+ }
+
+ switch (prio) {
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ /* appease clang */
+ panic("should not be here");
+ break;
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ memmove(&seh->cb[1], seh->cb,
+ sizeof(seh->cb[0]) * seh->count);
+ memmove(&seh->prio[1], seh->prio,
+ sizeof(seh->prio[0]) * seh->count);
+ seh->cb[0] = cb;
+ seh->prio[0] = prio;
+ seh->count++;
+ break;
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ for (i = 0; i < seh->count; i++) {
+ if (seh->prio[i] != STATIC_EVENTHANDLER_PRIO_FIRST)
+ break;
+ }
+ if (i == seh->count) {
+ /*
+ * Insert at the end.
+ */
+ seh->cb[seh->count] = cb;
+ seh->prio[seh->count] = prio;
+ seh->count++;
+ } else {
+ /*
+ * Move all entries to handle STATIC_EVENTHANDLER_PRIO_LAST.
+ */
+ memmove(&seh->cb[i + 1], seh->cb,
+ sizeof(seh->cb[0]) * (seh->count - i));
+ memmove(&seh->prio[i + 1], seh->prio,
+ sizeof(seh->prio[0]) * (seh->count - i));
+ seh->cb[i] = cb;
+ seh->prio[i] = prio;
+ seh->count++;
+ }
+ break;
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ seh->cb[seh->count] = cb;
+ seh->prio[seh->count] = prio;
+ seh->count++;
+ break;
+ }
+ rms_wunlock(&seh->lock);
+ free(tofree_cb, M_EVENTHANDLER);
+ free(tofree_prio, M_EVENTHANDLER);
+}
+
+void
+static_eventhandler_deregister(struct static_eventhandler *seh, void *pcb)
+{
+ static_eventhandler_cb *cb;
+ int i;
+
+ cb = pcb;
+ rms_wlock(&seh->lock);
+ MPASS(seh->count <= seh->size);
+ static_eventhandler_validate(seh);
+
+ for (i = 0; i < seh->count; i++) {
+ if (seh->cb[i] == cb)
+ break;
+ }
+
+ if (i == seh->count)
+ panic("callback %p not found", cb);
+
+ switch (seh->prio[i]) {
+ case STATIC_EVENTHANDLER_PRIO_INVALID:
+ /* appease clang */
+ panic("should not be here");
+ break;
+ case STATIC_EVENTHANDLER_PRIO_FIRST:
+ memmove(seh->cb, &seh->cb[1],
+ sizeof(seh->cb[0]) * (seh->count - 1));
+ memmove(seh->prio, &seh->prio[1],
+ sizeof(seh->prio[0]) * (seh->count - 1));
+ break;
+ case STATIC_EVENTHANDLER_PRIO_ANY:
+ memmove(&seh->cb[i], &seh->cb[i + 1],
+ sizeof(seh->cb[0]) * (seh->count - i));
+ memmove(&seh->prio[i], &seh->cb[i + 1],
+ sizeof(seh->cb[0]) * (seh->count - i));
+ break;
+ case STATIC_EVENTHANDLER_PRIO_LAST:
+ seh->cb[i] = seh->cb[seh->count - 1];
+ seh->prio[i] = seh->prio[seh->count - 1];
+ break;
+ }
+ seh->cb[seh->count] = NULL;
+ seh->prio[seh->count] = STATIC_EVENTHANDLER_PRIO_INVALID;
+ seh->count--;
+ rms_wunlock(&seh->lock);
+}
+
+void
+static_eventhandler_invoke(struct static_eventhandler *seh, void *arg)
+{
+ int i;
+
+ if (seh->count == 0)
+ return;
+
+ rms_rlock(&seh->lock);
+ for (i = 0; i < seh->count; i++) {
+ (seh->cb[i])(arg);
+ }
+ rms_runlock(&seh->lock);
+}
Index: sys/sys/_eventhandler.h
===================================================================
--- sys/sys/_eventhandler.h
+++ sys/sys/_eventhandler.h
@@ -69,4 +69,52 @@
}; \
struct __hack
+/*
+ * Headers to accomodate _rmlock.h
+ */
+#include <sys/param.h>
+#include <sys/_cpuset.h>
+#include <sys/_lock.h>
+#include <sys/_mutex.h>
+#include <sys/_sx.h>
+#include <sys/_rmlock.h>
+
+typedef void static_eventhandler_cb(void *);
+
+enum static_eventhandler_prio {
+ STATIC_EVENTHANDLER_PRIO_INVALID,
+ STATIC_EVENTHANDLER_PRIO_FIRST,
+ STATIC_EVENTHANDLER_PRIO_ANY,
+ STATIC_EVENTHANDLER_PRIO_LAST
+};
+
+struct static_eventhandler {
+ const char *ident;
+ enum static_eventhandler_prio *prio;
+ struct rmslock lock;
+ u_int count;
+ u_int size;
+ static_eventhandler_cb **cb;
+};
+
+#define STATIC_EVENTHANDLER_DECLARE(name) \
+extern struct static_eventhandler static_eventhandler_ ## name
+
+#define STATIC_EVENTHANDLER_REGISTER(name, func, prio) \
+ static_eventhandler_register(&static_eventhandler_ ## name, func, \
+ STATIC_EVENTHANDLER_PRIO_ ## prio)
+
+#define STATIC_EVENTHANDLER_DEREGISTER(name, func) \
+ static_eventhandler_deregister(&static_eventhandler_ ## name, func)
+
+#define STATIC_EVENTHANDLER_INVOKE(name, arg) \
+ static_eventhandler_invoke(&static_eventhandler_ ## name, arg)
+
+#define STATIC_EVENTHANDLER_DEFINE(name) \
+struct static_eventhandler static_eventhandler_ ## name = { \
+ .ident = __STRING(name), \
+}; \
+SYSINIT(_seh_init_ ## name, SI_SUB_EVENTHANDLER, SI_ORDER_ANY, \
+ static_eventhandler_init, &static_eventhandler_ ## name);
+
#endif
Index: sys/sys/eventhandler.h
===================================================================
--- sys/sys/eventhandler.h
+++ sys/sys/eventhandler.h
@@ -317,4 +317,13 @@
typedef void (*rt_addrmsg_fn)(void *, struct ifaddr *, int);
EVENTHANDLER_DECLARE(rt_addrmsg, rt_addrmsg_fn);
+/*
+ * Static eventhandler support.
+ */
+void static_eventhandler_init(struct static_eventhandler *seh);
+void static_eventhandler_register(struct static_eventhandler *seh, void *func,
+ enum static_eventhandler_prio prio);
+void static_eventhandler_deregister(struct static_eventhandler *seh, void *func);
+void static_eventhandler_invoke(struct static_eventhandler *seh, void *arg);
+
#endif /* _SYS_EVENTHANDLER_H_ */

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 7, 3:45 PM (17 h, 12 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17034517
Default Alt Text
D27252.diff (8 KB)

Event Timeline