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]

Re: Reentrant Mutex


> 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;
}




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