Re: Kernel Recursive mutexes 10.4.9 ++
Re: Kernel Recursive mutexes 10.4.9 ++
- Subject: Re: Kernel Recursive mutexes 10.4.9 ++
- From: Terry Lambert <email@hidden>
- Date: Thu, 19 Jul 2007 00:26:00 -0700
I avoided that solution because it fosters a reliance on recursive
mutexes, and you tend to end up with subtle bugs in your code, if you
depend on them. But yes, it's possible to build a recursive mutex
construct from non-recursive mutexes.
I'd caution you on a couple of things:
(1) your increments and decrements need to use atomic instructions
(2) the mutex should be held over an increment/decrement; if it's not,
you will need to set up a retry, probably with a condition variable
(3) it's possible to not hold the mutex over the decrement, but your
objects would need to be create-once (it's probably too rough to go
down that path, unless you are going to refactor your code anyway).
(4) you are not going to be able to just declare static instances of
these things; you will need an initializer function of some kind
(minimally, you will need to initialize the interior mutex).
-- Terry
On Jul 19, 2007, at 12:12 AM, Erez Kaplan wrote:
Terry,
OK, got the idea of that solution.
I found another reference to this issue, is it a good one and does
it cover my needs?
>
> typedef struct pthread_mutex_recursive_np_t {
> pthread_mutex_t mutex;
> pthread_t owner;
> UInt32 count;
> } pthread_mutex_recursive_np_t;
>
> void pthread_mutex_lock_recursive_np(pthread_mutex_recursive_np_t
*mutex)
> {
> pthread_t self;
>
> self = pthread_self();
> if (mutex->owner != self)
> {
> pthread_mutex_lock(&mutex->mutex);
> mutex->owner = self;
> mutex->count = 1;
> }
> else
> mutex->count += 1;
> }
>
> void pthread_mutex_unlock_recursive_np(pthread_mutex_recursive_np_t
> *mutex)
> {
> if (--mutex->count == 0)
> {
> mutex->owner = NULL;
> pthread_mutex_unlock(&mutex->mutex);
> }
> }
======= Cheers, Erez
On Jul 19, 2007, at 10:01 AM, Terry Lambert wrote:
If funcB has to be callable unlocked somewhere, then:
funcA() {
lock mutex
funcB_locked()
do stuff...
unlock mutex
}
funcB() {
lock mutex
funcB_locked()
unlock mutex
}
/* MUST be called with mutex held! */
funcB_locked()
{
do stuff...
}
We do this sort of thing in the kernel in a number of places, where
reference counts would be inappropriate.
-- Terry
On Jul 18, 2007, at 9:36 PM, Erez Kaplan wrote:
Terry,
Thanks for the explanation.
I am facing a some what strange sequence of calling (forced by PC
porting) which looks something like this:
Currently I get a deadlock situation.
How would you outline handling this deadlock?
funcA() {
lock mutex
funcB()
do stuff...
unlock mutex
}
funcB() {
lock mutex
do stuff...
unlock mutex
}
Cheers, Erez
On Jul 19, 2007, at 7:24 AM, Terry Lambert wrote:
On Jul 18, 2007, at 8:54 PM, Erez Kaplan wrote:
On Jul 18, 2007, at 10:00 PM, Terry Lambert wrote:
On Jul 18, 2007, at 2:37 AM, Erez Kaplan wrote:
Hi,
10.4.9+ 10.5
How do I obtain a Kernel Recursive mutexe?
The available api does not support this.
lck_mtx_alloc_init(gmutex_grp_m, LCK_ATTR_NULL)
You don't; this is what reference and use counts are for.
Can you explain a bit more or give reference to an example.
For example, all thread reentrant FSs will take an I/O reference
on a vnode, and use that reference to prevent the FS from being
unmounted out from under an operation in progress, rather than
holding a lock over the complete operation (thus unnecessarily
serializing all other I/O to the vnode). Here is a simplified
design pattern:
some function(object)
lock mutex
atomic increment reference count
unlock mutex
... long duration operation ...
lock mutex
atomic decrement reference count
unlock mutex
/* wake up destroy routine; destroy routine may fail acquisition
race */
if !reference count
wakeup(object)
...
destroy(object)
lock mutex
again:
/* Don't destroy the object while someone is using it */
if reference count
msleep(mutex, object)
goto again /* avoid race */
/* last reference gone, OK to kill it */
destroy object
unlock mutex
-- Terry
//======================
Erez Kaplan
Senior software engineer OSX
email@hidden
//======================
//======================
Erez Kaplan
Senior software engineer OSX
email@hidden
//======================
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden