[ECOS] pthread_mutex_unlock when mutex is not locked

Rubén Pérez de Aranda Alonso rperez@sidsa.es
Wed Apr 27 12:38:00 GMT 2005


Ok,
I understand you explain me. The standard also defines that a mutex
locked by a thread must be unlocked by the same thread. However,
many implementations of Pthreads allow use the mutex to signal events
carring out lock and unlock of the mutex from different threads.
But, ok, the DSR is not a thread :-).
An example is the next code, that works with the POSIX compat layer
of eCOS.
N threads are created and executed in differents priority
levels each one of them in SCHED_FIFO policy. The thread th(K)
takes the priority equal to K and locks the pre-locked mutex
m((K-1)%N).
The th(K) also unlocks the mutex m(K) where the th(K+1) is
waiting. So, because the Prio(th(K+1)) > Prio(th(K)) then the
th(K+1) is dispatched at the same time that the th(K) unlocks
the mutex m(K).

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sched.h>

#include <prof.h>


#define STACK_SIZE (PTHREAD_STACK_MIN*2)
#define NTHREADS   24


static pthread_t       thread_id [NTHREADS];
static pthread_mutex_t mutex_id  [NTHREADS];
static unsigned long   thread_stk[NTHREADS][STACK_SIZE/sizeof(unsigned 
long)];
static profDeltaT_t    clk_data  [NTHREADS];



void *thread_fn (void *pdata)
{
  long          pre_index;

  pre_index = (((long)pdata-1) < 0)?(NTHREADS-1):((long)pdata -1);

  pthread_mutex_lock(&mutex_id[pre_index]);
  profGetHwClock(&(clk_data[pre_index].end));
  profGetHwClock(&(clk_data[(long)pdata].start));
  pthread_mutex_unlock(&mutex_id[(long)pdata]);

  pthread_exit(pdata);
}


int main (void)
{
  long i;
  struct sched_param schedparam;
  pthread_attr_t pthattr;
  pthread_mutexattr_t mattr;

  pthread_mutexattr_init( &mattr );


  schedparam.sched_priority = NTHREADS+2;
  pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedparam);


  pthread_attr_init(&pthattr);
  pthread_attr_setinheritsched(&pthattr, PTHREAD_EXPLICIT_SCHED);
  pthread_attr_setschedpolicy(&pthattr, SCHED_FIFO);
  pthread_attr_setdetachstate(&pthattr, PTHREAD_CREATE_JOINABLE);
  pthread_attr_setstacksize(&pthattr, STACK_SIZE);
   
  for (i = 0; i < NTHREADS; i++)

  {
    pthread_mutex_init(&mutex_id[i], &mattr);
    pthread_mutex_lock(&mutex_id[i]);
  }
   
  profWait4Tick();
  for (i = 0;  i < NTHREADS;  i++)
  {
    pthread_attr_setstackaddr(&pthattr,
      &thread_stk[i][STACK_SIZE/sizeof(unsigned long)]);
    schedparam.sched_priority = i+1;
    pthread_attr_setschedparam(&pthattr, &schedparam);
    pthread_create(&thread_id[i],
                   &pthattr,
                   thread_fn,
                   (void *)i);
  }

  profGetHwClock(&(clk_data[NTHREADS-1].start));
  pthread_mutex_unlock(&mutex_id[NTHREADS-1]);


  for (i = 0; i < NTHREADS; i++)
  {
    pthread_join(thread_id[i], NULL);
  }
 
  printf("\n"
         " POSIX LAYER TEST 1: switch thread context\n"
         " when control is transfered through mutexes\n"
         "\n"
        );

  profPrintData((profDeltaT_t*)clk_data, NTHREADS-1, printf);
  return 0;
}


Anothe cuestion. Can I use the next code to guaratee the mutual
exclusion in access to critical data from a thread and a DSR?

DSR ()
{
  if (pthread_mutex_trylock(&mutex) == 0)
  {
    // Access to data
    // Calculate .....
   
    // Unlock
    pthread_mutex_unlock(&mutex);
  }
}


Thnak you very much


Nick Garnett wrote:

>Rubén Pérez de Aranda Alonso <rperez@sidsa.es> writes:
>
>  
>
>>I think the mutex is appropiate for the explained scenario.
>>
>>The standard says:
>>"If the mutex type is PTHREAD_MUTEX_RECURSIVE, then the mutex
>>maintains the concept of a lock count. When a thread successfully
>>acquires a mutex for the first time, the lock count is set to
>>one. Every time a thread relocks this mutex, the lock count is
>>incremented by one. Each time the thread unlocks the mutex, the lock
>>count is decremented by one. When the lock count reaches zero, the
>>mutex becomes available for other threads to acquire. If a thread
>>attempts to unlock a mutex that it has not locked or a mutex which is
>>unlocked, an error will be returned."
>>
>>http://www.opengroup.org/onlinepubs/007908799/xsh/pthread_mutex_lock.html
>>
>>So, I think the unlock method must return an error code. In eCOS, this
>>method returns void. If we check the mutex is locked at least we avoided the
>>crash of the system.
>>    
>>
>
>eCos doesn't currently support recursive mutexes -- partly because
>some of us consider them the work of the devil and partly because it
>would require some significant work on the kernel mutex code to make
>it work smoothly with the priority inversion protocols.
>
>DSRs are not threads, and can be called in the context of any thread
>in the system. Calling mutex unlock from a DSR would do it in the
>context of the thread that happened to running when the interrupt
>occured. If you are lucky, this will be the thread that locked the
>mutex and it will work. If you are unlucky, it will be a different
>thread and the mutex will not get unlocked.
>
>Condition variables can be signalled from DSRs and you should really
>use one of those to wake up any threads.
>
>
>  
>


-- 
______________________________________________________________

Rubén Israel Pérez de Aranda Alonso
SIDSA - Semiconductores Investigación y Diseño S.A.
Parque Tecnológico de Madrid           Phone : +34 91 803 5052
C/ Torres Quevedo, nº 1                Fax:    +34 91 803 9557
28760 TRES CANTOS (Madrid) (SPAIN)
e-mail: rperez@sidsa.com               www.sidsa.com
______________________________________________________________


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



More information about the Ecos-discuss mailing list