This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: reentrant mutex


Gentleman,
 See comments below.
----- Original Message -----
From: "Nick Garnett" <nickg at ecoscentric dot com>
To: "Jonathan Larmour" <jifl at eCosCentric dot com>
Cc: <mark_lee_hamilton at att dot net>; "ecos" <ecos-discuss at sources dot redhat dot com>
Sent: Monday, April 14, 2003 2:50 AM
Subject: Re: [ECOS] reentrant mutex


> Jonathan Larmour <jifl at eCosCentric dot com> writes:
>
> > mark_lee_hamilton at att dot net wrote:
> > > Will reentrant mutex support be added in the near future? I ask
> > > because this functionality is currently missing in 2.0 beta. I
> > > scanned through the email archives and noticed that topic was
> > > brought up a while back. There didn't seem to be much of a desire to
> > > support a reentrant mutex. I'm hoping that there has been a change
> > > of heart on the topic.
> >
> > I think it's unlikely we'd want to make existing mutexes recursive,
> > but as indeed one of the threads in the past mentioned, some separate
> > recursive mutex type could be added.
> >
> > Whether or not "strategically" such a patch would be accepted in the
> > sources I'll leave to Nick G though. Personally I'm keen as the kernel
> > is meant to be more than just basic primitives, but a box of tools to
> > make development easier.
> >
>
> I would personally not like to see such a patch. It would not work
> very well with condition variables and any system that mixed regular
> and recursive mutexes would be very hard to debug.
>
> In my opinion, a need for recursive mutexes is usually a symptom of
> poor program design.
Oh, now you've hurt my honor. I think recursive mutexes have their place.
I'll simply point out that W2K and up, Solaris, IRIX, HP's OS, WinCE,
VxWorks, ThreadX, pSOS and AMX all support recursive mutexes. These are just
the ones that I've dealt with. I'm guessing that you would be hard pressed
to find and RTOS that doesn't support recursive mutexes - oh except for
eCos.

There is also the issue of POSIX compliants. Without recursive mutexes is
eCos really POSIX compliant.

As for any future design, I would strongly discourage having two types of
mutexes exposed to developers. I would prefer that two additional functions
be added to the existing API: cyg_mutex_set_type and cyg_mutex_get_type.
Having two types of mutexes is annoying for the developer. If I start with
non-recursive mutexes and then switch to recursive I would have to modify my
code in many places. Verses just calling cyg_mutex_type_set(RECURSIVE) after
the creation of a mutex.

As for justifing their existance. I find that I normally use them to
implement a Monitor, a class where accessor methods guard a critical region
of private attributes. With recursive mutexes public methods can call other
public methods. Without recursive mutexes, I have to create additional
private methods that do not lock mutexes.
Besides a mutex's responsibility is to prevent multiple threads from
accessing a critical region. Recursive support does not break that paradigm.
It only provides the possibility of simplier code.

I'm by no means an expert on the eCos implementation. It seems that the code
snippet below would fit nicely inside of Cyg_Mutex::lock(void).
while( locked && result )
    {
        //Replace CYG_ASSERT with the recursive support.
       //CYG_ASSERT( self != owner, "Locking mutex I already own");
        if((type == RECURSIVE) && (cyg_thread_self() == mx->owner ))
        {
           count++;
           Cyg_Scheduler::unlock();
           return;
         }
        else
        {
          CYG_ASSERT( self != owner, "Locking mutex I already own");
        }

        self->set_sleep_reason( Cyg_Thread::WAIT );

        self->sleep();

        queue.enqueue( self );

You could simple state that by default mutexes are not-recursive. Therefore
all existing kernel code would not change. Users who want recursive mutexes
would need to call cyg_mutex_set_type(cyg_handle_t, int type). As for your
concern with conditional variables, maybe a comment in the documentation
explaining the reasons against using recursive mutexes with conditional
variables would suffice.

>
> If anybody really wants recursive mutexes, then they can always
> implement them above the existing mutex mechanism. For example:
>
> typedef struct
> {
>     cyg_mutex_t     mutex;
>     cyg_handle_t    owner;
>     cyg_uint32      count;
> } cyg_recursive_mutex;
>
> void cyg_recursive_mutex_lock( cyg_recursive_mutex *mx )
> {
>     cyg_scheduler_lock();
>     {
>         if( cyg_thread_self() == mx->owner )
>         {
>             mx->count++;
>         }
>         else
>         {
>             cyg_mutex_lock( &mx->mutex );
>             mx->count = 1;
>             mx->owner = cyg_thread_self();
>         }
>     }
>     cyg_scheduler_unlock();
> }
>
> The rest is left as an exercise for the reader.
>
> --
> Nick Garnett                    eCos Kernel Architect
> http://www.ecoscentric.com/     The eCos and RedBoot experts
>


-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]