This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: Reentrant Mutex
- To: "Fabrice Gautier" <Fabrice_Gautier at sdesigns dot com>
- Subject: Re: [ECOS] Reentrant Mutex
- From: "Boris V. Guzhov" <borg at int dot spb dot ru>
- Date: Thu, 3 Aug 2000 11:02:11 +0400
- Cc: <ecos-discuss at sourceware dot cygnus dot com>
- References: <21DDE8E5343ED411840A00A0CC334020104816@EXCHANGE5_5>
> Hi,
>
> I would like to have a reentrant mutex structure. Do you think there will
> have one someday in eCos ?
>
> Thanks
>
> --
> Fabrice Gautier
Hi,
In eCos I not find the reentrant (or recursive) mutex's.
I did following additional to eCos code:
/* Mutex type */
#define MUTEX_NORMAL 0
#define MUTEX_RECURSIVE 1
/* Mutexes */
typedef struct
{
cyg_mutex_t m_em; /* ecos mutex */
int m_type; /* mutex type */
int m_lock; /* lock mutex deep */
} mutex_t;
int mutex_init(mutex_t *mutex, int type)
{
if ( !mutex )
return EINVAL;
cyg_scheduler_lock();
mutex->m_type = type;
mutex->m_lock = 0;
cyg_mutex_init(&mutex->m_em);
cyg_scheduler_unlock();
return 0;
}
int mutex_destroy ( mutex_t *mutex )
{
cyg_scheduler_lock();
if ( mutex->m_em.locked )
{
cyg_scheduler_unlock();
return BUSY;
}
cyg_mutex_destroy(&mutex->m_em);
cyg_scheduler_unlock();
return 0;
}
int mutex_lock ( mutex_t *mutex )
{
if ( !mutex )
return EINVAL;
cyg_scheduler_lock();
if ( mutex->m_em.locked == 0 || mutex->m_em.owner != (cyg_thread
*)cyg_thread_self())
{
cyg_scheduler_unlock();
cyg_mutex_lock(&mutex->m_em);
cyg_scheduler_lock();
mutex->m_lock = mutex->m_em.locked != 0;
cyg_scheduler_unlock();
return 0;
}
if (mutex->m_type == MUTEX_RECURSIVE )
{
mutex->m_lock++;
cyg_scheduler_unlock();
return 0;
}
cyg_scheduler_unlock();
return EDEADLK; /* deadlock */
}
int mutex_unlock (mutex_t *mutex )
{
if ( !mutex )
return EINVAL;
cyg_scheduler_lock();
if ( !mutex->m_em.locked || mutex->m_em.owner != (cyg_thread
*)cyg_thread_self() )
{
cyg_scheduler_unlock();
return EPERM;
}
if ( mutex->m_type == MUTEX_RECURSIVE )
{
mutex->m_lock--;
if (mutex->m_lock)
{
cyg_scheduler_unlock();
return 0;
}
}
else
mutex->m_lock = 0;
cyg_scheduler_unlock();
cyg_mutex_unlock(&mutex->m_em);
return 0;
}