Hi
I have a problem in a quit big program.

So I have made a simple program to test for this, and the same problem
persist.

This is the situation :
three threads
thread 1 : priority 2    (lowest)
thread 2 : priority 0    (highest)
thread 3 : priority 1    (middle)
(BTW -> is the priority right?)

The three threads look like this.
thread 1
while(1) {
    lock mutex
    sleep for 1msec.
    unlock mutex.
}

thread 2
while(1)
    sleep for 0.7 msec
    lock mutex
    sleep for 0.7msec
    unlock mutex
}

thread 3
while(1)
    sleep for 0.5 msec
    lock mutex
    sleep for 0.7 msec
    unlock mutex
}

The three threads is started at the same time (well allmost). I have
then messured the start and end time for the running part. This is what
i get for 5 samples.

thread 1                2                3
Jul 26 23:27:10 localhost kernel: TEST 1006880  2473600  1739232
Jul 26 23:27:10 localhost kernel: TEST 1006944  2473856  1739584
Jul 26 23:27:10 localhost kernel: TEST 1006944  2473888  1739488
Jul 26 23:27:10 localhost kernel: TEST 1008928  2479328  1742528
Jul 26 23:27:10 localhost kernel: TEST 1007104  2473344  1739680

And this is the problem. it should be close to 1ms, 1.7ms and 24ms.
thread 1 runs as ekspected. it capture the mutex first.
thread 2 and 3 is both locked and the are both ready to run, an one
would assume that the one with the highest priority would wakeup. Thread
2 have priority 0 and thread 3 have 1 -> 2 should go ..... but 3 is
running insted.

Thread 3 does capture the mutex first, but it should not start running,
because 2 have higer priority and is ready.

If I am right the mutex does not run the POSIX way, but in some kind of
fifo mode.

I have attached my code. it should be ready to run.

Anders Gnistrup.

BTW.
I can always insert the module, but sometimes when i try to remove it,
it halt the machine and complains about some interrupt error. Yep, I get
a kernel panic.


#include <rtl.h>
#include <time.h>
#include <pthread.h>
#include <rtl_printf.h>

#define SAMPLE_SIZE 5

pthread_t thread_id[3];
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

void *thread1(void *arg);
void *thread2(void *arg);
void *thread3(void *arg);

void *thread[3];
int init_module(void) {
  pthread_attr_t attr;
  struct sched_param param; 
  int i;

  thread[2] = thread1;
  thread[0] = thread2;
  thread[1] = thread3;
  
  pthread_attr_init(&attr);
  for(i=0;i<3;i++) {
    param.sched_priority = i;
    pthread_attr_setschedparam(&attr,&param);
    pthread_create(&thread_id[i],&attr,thread[i],(void *) i);
  }
  return 0;
}
hrtime_t Time[3][SAMPLE_SIZE][2]; 
void cleanup_module(void) {
  int i,j;
  
  for(i=0;i<3;i++) {
    pthread_cancel(thread_id[i]);
    pthread_join(thread_id[i],NULL);
  }
  
  for(i=0;i<SAMPLE_SIZE;i++) {
    rtl_printf("TEST");
    for(j=0;j<3;j++) {
      rtl_printf(" %u ",(int) (Time[j][i][1]-Time[j][i][0])&0xffffffff);
    }
    rtl_printf("\n");
  }
}

#define PERIOD 10000000
void *thread1(void *arg) {
  int i;
  struct timespec period = {0,1000000};

  pthread_make_periodic_np(pthread_self(),gethrtime(),PERIOD);
  while(1) {
    pthread_wait_np();
    for(i=0;i<SAMPLE_SIZE;i++) {
      pthread_wait_np();
      Time[0][i][0] = gethrtime();
      pthread_mutex_lock(&mutex);
      nanosleep(&period,NULL);
      pthread_mutex_unlock(&mutex);  
      Time[0][i][1] = gethrtime();
    }  
  }
}

void *thread2(void *arg) {
  int i;
  const struct timespec period2 = {0,700000};
 
  pthread_make_periodic_np(pthread_self(),gethrtime(),PERIOD);
  while(1) {
    pthread_wait_np();
    for(i=0;i<SAMPLE_SIZE;i++) {
      pthread_wait_np();
      Time[1][i][0] = gethrtime();
      nanosleep(&period2,NULL);
      pthread_mutex_lock(&mutex); 
      nanosleep(&period2,NULL);
      pthread_mutex_unlock(&mutex);
      Time[1][i][1] = gethrtime();
    }
  }
}

void *thread3(void *arg) {
  int i;
  const struct timespec 
    period3 = {0,500000},
    period4 = {0,700000};

  pthread_make_periodic_np(pthread_self(),gethrtime(),PERIOD);
  
  while(1) {
    pthread_wait_np();
    for(i=0;i<SAMPLE_SIZE;i++) {
      pthread_wait_np();
      Time[2][i][0] = gethrtime();
      nanosleep(&period3,NULL);
      pthread_mutex_lock(&mutex); 
      nanosleep(&period4,NULL);
      pthread_mutex_unlock(&mutex); 
      Time[2][i][1] = gethrtime();
    }
  }
}
TARGET = mutexT
CC = gcc
include /usr/src/rtlinux/rtl.mk

all: $(TARGET).o 

$(TARGET).o: $(TARGET).c
        $(CC) -Wall ${CFLAGS} -c $(TARGET).c

clean:
        rm -f  *.o




Reply via email to