From 069a8a3decf5981cd420014384ead470eac8561c Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Tue, 18 Aug 2015 12:07:26 +0200 Subject: 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. --- kern/lock.c | 1 + kern/lock.h | 11 +++++++++++ 2 files changed, 12 insertions(+) (limited to 'kern') 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)) -- cgit v1.2.3