summaryrefslogtreecommitdiffstats
path: root/sys/sys/callout.h
diff options
context:
space:
mode:
authoriedowse <iedowse@FreeBSD.org>2005-02-07 02:47:33 +0000
committeriedowse <iedowse@FreeBSD.org>2005-02-07 02:47:33 +0000
commit885a9694bc1a30c0841c38f6367dc1cf43e219ee (patch)
tree5dea023d3d1cd872af007610de788883258c40c1 /sys/sys/callout.h
parent5592598fa8171c55f9a1198b685dd61ca95fdc59 (diff)
downloadFreeBSD-src-885a9694bc1a30c0841c38f6367dc1cf43e219ee.zip
FreeBSD-src-885a9694bc1a30c0841c38f6367dc1cf43e219ee.tar.gz
Add a mechanism for associating a mutex with a callout when the
callout is first initialised, using a new function callout_init_mtx(). The callout system will acquire this mutex before calling the callout function and release it on return. In addition, the callout system uses the mutex to avoid most of the complications and race conditions inherent in asynchronous timer facilities, so mutex-protected callouts have much simpler semantics. As long as the mutex is held when invoking callout_stop() or callout_reset(), then these functions will guarantee that the callout will be stopped, even if softclock() had already begun to process the callout. Existing Giant-locked callouts will automatically pick up the new race-free semantics. This should close a number of race conditions in the USB code and probably other areas of the kernel too. There should be no change in behaviour for "MP-safe" callouts; these still need to use the techniques mentioned in timeout(9) to avoid race conditions.
Diffstat (limited to 'sys/sys/callout.h')
-rw-r--r--sys/sys/callout.h5
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/sys/callout.h b/sys/sys/callout.h
index 50dedbf..cec9079 100644
--- a/sys/sys/callout.h
+++ b/sys/sys/callout.h
@@ -40,6 +40,8 @@
#include <sys/queue.h>
+struct mtx;
+
SLIST_HEAD(callout_list, callout);
TAILQ_HEAD(callout_tailq, callout);
@@ -51,6 +53,7 @@ struct callout {
int c_time; /* ticks to the event */
void *c_arg; /* function argument */
void (*c_func)(void *); /* function to call */
+ struct mtx *c_mtx; /* mutex to lock */
int c_flags; /* state of this entry */
};
@@ -58,6 +61,7 @@ struct callout {
#define CALLOUT_ACTIVE 0x0002 /* callout is currently active */
#define CALLOUT_PENDING 0x0004 /* callout is waiting for timeout */
#define CALLOUT_MPSAFE 0x0008 /* callout handler is mp safe */
+#define CALLOUT_RETURNUNLOCKED 0x0010 /* handler returns with mtx unlocked */
struct callout_handle {
struct callout *callout;
@@ -75,6 +79,7 @@ extern struct mtx callout_lock;
#define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE)
#define callout_drain(c) _callout_stop_safe(c, 1)
void callout_init(struct callout *, int);
+void callout_init_mtx(struct callout *, struct mtx *, int);
#define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING)
void callout_reset(struct callout *, int, void (*)(void *), void *);
#define callout_stop(c) _callout_stop_safe(c, 0)
OpenPOWER on IntegriCloud