summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/subr_eventhandler.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-09 14:02:09 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:38 +0200
commitbb80d9df8bac71eedee1a6787ca63aef972a7e48 (patch)
tree1b5cb9443c5ead5706c35afb618abbbd1592315e /freebsd/sys/kern/subr_eventhandler.c
parentUpdate to FreeBSD head 2017-10-01 (diff)
downloadrtems-libbsd-bb80d9df8bac71eedee1a6787ca63aef972a7e48.tar.bz2
Update to FreeBSD head 2017-12-01
Git mirror commit e724f51f811a4b2bd29447f8b85ab5c2f9b88266. Update #3472.
Diffstat (limited to 'freebsd/sys/kern/subr_eventhandler.c')
-rw-r--r--freebsd/sys/kern/subr_eventhandler.c103
1 files changed, 70 insertions, 33 deletions
diff --git a/freebsd/sys/kern/subr_eventhandler.c b/freebsd/sys/kern/subr_eventhandler.c
index c373a7f2..92cd9726 100644
--- a/freebsd/sys/kern/subr_eventhandler.c
+++ b/freebsd/sys/kern/subr_eventhandler.c
@@ -1,6 +1,8 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 1999 Michael Smith <msmith@freebsd.org>
* All rights reserved.
*
@@ -40,7 +42,7 @@ __FBSDID("$FreeBSD$");
static MALLOC_DEFINE(M_EVENTHANDLER, "eventhandler", "Event handler records");
-/* List of 'slow' lists */
+/* List of all eventhandler lists */
static TAILQ_HEAD(, eventhandler_list) eventhandler_lists;
static int eventhandler_lists_initted = 0;
static struct mtx eventhandler_mutex;
@@ -66,25 +68,11 @@ eventhandler_init(void *dummy __unused)
SYSINIT(eventhandlers, SI_SUB_EVENTHANDLER, SI_ORDER_FIRST, eventhandler_init,
NULL);
-/*
- * Insertion is O(n) due to the priority scan, but optimises to O(1)
- * if all priorities are identical.
- */
-static eventhandler_tag
-eventhandler_register_internal(struct eventhandler_list *list,
- const char *name, eventhandler_tag epn)
+static struct eventhandler_list *
+eventhandler_find_or_create_list(const char *name)
{
- struct eventhandler_list *new_list;
- struct eventhandler_entry *ep;
-
- KASSERT(eventhandler_lists_initted, ("eventhandler registered too early"));
- KASSERT(epn != NULL, ("%s: cannot register NULL event", __func__));
-
- /* lock the eventhandler lists */
- mtx_lock(&eventhandler_mutex);
+ struct eventhandler_list *list, *new_list;
- /* Do we need to find/create the (slow) list? */
- if (list == NULL) {
/* look for a matching, existing list */
list = _eventhandler_find_list(name);
@@ -92,8 +80,8 @@ eventhandler_register_internal(struct eventhandler_list *list,
if (list == NULL) {
mtx_unlock(&eventhandler_mutex);
- new_list = malloc(sizeof(struct eventhandler_list) +
- strlen(name) + 1, M_EVENTHANDLER, M_WAITOK);
+ new_list = malloc(sizeof(*new_list) + strlen(name) + 1,
+ M_EVENTHANDLER, M_WAITOK | M_ZERO);
/* If someone else created it already, then use that one. */
mtx_lock(&eventhandler_mutex);
@@ -103,21 +91,35 @@ eventhandler_register_internal(struct eventhandler_list *list,
} else {
CTR2(KTR_EVH, "%s: creating list \"%s\"", __func__, name);
list = new_list;
- list->el_flags = 0;
- list->el_runcount = 0;
- bzero(&list->el_lock, sizeof(list->el_lock));
- list->el_name = (char *)list + sizeof(struct eventhandler_list);
+ TAILQ_INIT(&list->el_entries);
+ mtx_init(&list->el_lock, name, "eventhandler list", MTX_DEF);
+ list->el_name = (char *)(list + 1);
strcpy(list->el_name, name);
TAILQ_INSERT_HEAD(&eventhandler_lists, list, el_link);
}
}
+ return (list);
+}
+
+/*
+ * Insertion is O(n) due to the priority scan, but optimises to O(1)
+ * if all priorities are identical.
+ */
+static eventhandler_tag
+eventhandler_register_internal(struct eventhandler_list *list,
+ const char *name, eventhandler_tag epn)
+{
+ struct eventhandler_entry *ep;
+
+ KASSERT(eventhandler_lists_initted, ("eventhandler registered too early"));
+ KASSERT(epn != NULL, ("%s: cannot register NULL event", __func__));
+
+ /* Do we need to find/create the list? */
+ if (list == NULL) {
+ mtx_lock(&eventhandler_mutex);
+ list = eventhandler_find_or_create_list(name);
+ mtx_unlock(&eventhandler_mutex);
}
- if (!(list->el_flags & EHL_INITTED)) {
- TAILQ_INIT(&list->el_entries);
- mtx_init(&list->el_lock, name, "eventhandler list", MTX_DEF);
- atomic_store_rel_int(&list->el_flags, EHL_INITTED);
- }
- mtx_unlock(&eventhandler_mutex);
KASSERT(epn->ee_priority != EHE_DEAD_PRIORITY,
("%s: handler for %s registered with dead priority", __func__, name));
@@ -182,8 +184,9 @@ vimage_eventhandler_register(struct eventhandler_list *list, const char *name,
}
#endif
-void
-eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
+static void
+_eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag,
+ bool wait)
{
struct eventhandler_entry *ep = tag;
@@ -217,11 +220,26 @@ eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
ep->ee_priority = EHE_DEAD_PRIORITY;
}
}
- while (list->el_runcount > 0)
+ while (wait && list->el_runcount > 0)
mtx_sleep(list, &list->el_lock, 0, "evhrm", 0);
EHL_UNLOCK(list);
}
+void
+eventhandler_deregister(struct eventhandler_list *list, eventhandler_tag tag)
+{
+
+ _eventhandler_deregister(list, tag, true);
+}
+
+void
+eventhandler_deregister_nowait(struct eventhandler_list *list,
+ eventhandler_tag tag)
+{
+
+ _eventhandler_deregister(list, tag, false);
+}
+
/*
* Internal version for use when eventhandler list is already locked.
*/
@@ -280,3 +298,22 @@ eventhandler_prune_list(struct eventhandler_list *list)
if (pruned > 0)
wakeup(list);
}
+
+/*
+ * Create (or get the existing) list so the pointer can be stored by
+ * EVENTHANDLER_LIST_DEFINE.
+ */
+struct eventhandler_list *
+eventhandler_create_list(const char *name)
+{
+ struct eventhandler_list *list;
+
+ KASSERT(eventhandler_lists_initted,
+ ("eventhandler list created too early"));
+
+ mtx_lock(&eventhandler_mutex);
+ list = eventhandler_find_or_create_list(name);
+ mtx_unlock(&eventhandler_mutex);
+
+ return (list);
+}