summaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
authorJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-18 12:07:26 +0200
committerJustus Winter <4winter@informatik.uni-hamburg.de>2015-08-20 19:59:30 +0200
commit35cab1dc03d4454a523c4611f7c770029c29da19 (patch)
tree7dee8f9f9d498e13c4e697a1905be1b9ee7d4169 /kern
parentc098b6467ff5cfc25dd800d5bb2966f6ba3edff7 (diff)
kern: provide a way to steal a lock
During the message transport, the sender acquires a lock that is released by the sender. By making this explicit, we can provide stronger guarantees about the locking. * ipc/ipc_mqueue.c (ipc_mqueue_receive): Steal lock. * ipc/ipc_object.h (io_lock_steal): New macro. * ipc/ipc_port.h (ip_lock_steal): Likewise. * ipc/mach_msg.c (mach_msg_trap): Steal lock in the inlined version of `ipc_mqueue_receive'. * kern/lock.c (lock_done): Assert that the current thread holds the lock. * kern/lock.h (lock_write_steal): New macro.
Diffstat (limited to 'kern')
-rw-r--r--kern/lock.c1
-rw-r--r--kern/lock.h11
2 files changed, 12 insertions, 0 deletions
diff --git a/kern/lock.c b/kern/lock.c
index 1daf1b4..473e602 100644
--- a/kern/lock.c
+++ b/kern/lock.c
@@ -340,6 +340,7 @@ void lock_done(
else {
l->want_write = FALSE;
#if MACH_LDEBUG
+ assert(have_write_lock(l));
l->writer = THREAD_NULL;
#endif /* MACH_LDEBUG */
}
diff --git a/kern/lock.h b/kern/lock.h
index 74cd933..c8af883 100644
--- a/kern/lock.h
+++ b/kern/lock.h
@@ -211,10 +211,21 @@ extern void lock_clear_recursive(lock_t);
#if ! MACH_LDEBUG
#define have_read_lock(l) 1
#define have_write_lock(l) 1
+#define lock_write_surrender(l)
+#define lock_write_steal(l)
#else /* MACH_LDEBUG */
/* XXX: We don't keep track of readers, so this is an approximation. */
#define have_read_lock(l) ((l)->read_count > 0)
#define have_write_lock(l) ((l)->writer == current_thread())
+#define THREAD_SURRENDERED ((thread_t) ~0U)
+#define lock_write_surrender(l) ({ \
+ assert(have_write_lock(l)); \
+ (l)->writer = THREAD_SURRENDERED; \
+ })
+#define lock_write_steal(l) ({ \
+ assert((l)->writer == THREAD_SURRENDERED); \
+ (l)->writer = current_thread(); \
+ })
#endif /* MACH_LDEBUG */
#define have_lock(l) (have_read_lock(l) || have_write_lock(l))