RE: Kernel Recursive mutexes 10.4.9 ++
RE: Kernel Recursive mutexes 10.4.9 ++
- Subject: RE: Kernel Recursive mutexes 10.4.9 ++
- From: "Erez Kaplan" <email@hidden>
- Date: Fri, 20 Jul 2007 13:48:29 +0200
- Thread-topic: Kernel Recursive mutexes 10.4.9 ++
Title: RE: Kernel Recursive mutexes 10.4.9 ++
Alexei,
Thanks for the pointer.
Where do I find the implementation for this?
I opend
IOKitTools-57.1
IOKitUser-297.10
But found only 1 reference.
BTW - I am using NKE, can I use IOKit in my project?
Cheers, Erez
-----Original Message-----
From: Alexei Kosut [mailto:email@hidden]
Sent: Thu 7/19/2007 6:30 PM
To: Terry Lambert
Cc: Erez Kaplan; email@hidden
Subject: Re: Kernel Recursive mutexes 10.4.9 ++
On Jul 19, 2007, at 12:26 AM, Terry Lambert wrote:
> 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.
Erez doesn't mention what type of kernel code he's writing, but it
might be worth pointing out that IOKit has a recursive mutex
implementation (IORecursiveLock) that is available.
Alexei
> 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
_______________________________________________
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