3

How to implement barrier using posix semaphores?

void my_barrier_init(int a){

    int i;  
    bar.number = a;
    bar.counter = 0;

    bar.arr = (sem_t*) malloc(sizeof(sem_t)*bar.number);
    bar.cont = (sem_t*) malloc(sizeof(sem_t)*bar.number);
    for(i = 0; i < bar.number; i++){    
    sem_init(&bar.arr[i], 0, 0);
    sem_init(&bar.cont[i], 0, 0);   }
}

void my_barrier_wait(){
    int i;    
    bar.counter++;

    if(bar.number == bar.counter){      
    for(i = 0; i < bar.number-1; i++){  sem_wait(&bar.arr[i]);    }
    for(i = 0; i < bar.number-1; i++){   sem_post(&bar.cont[i]);     }
    bar.counter = 0;
    }else{
        sem_post(&bar.arr[pthread_self()-2]);
        sem_wait(&bar.cont[pthread_self()-2]);
  }
}

When function my_barrier_wait is called, first (N-1) times it would set(+1) for semaphores in array 'arr' and go to sleep(calling sem_wait). N-th time it decrements semaphores in 'arr' and SHOULD (as I expect) wake up [0..bar.number-1] threads posting +1 for semaphores in 'cont' array. It doesn't work like barrier.

diana-pure
  • 161
  • 3
  • 16
  • What is the meaning of `pthread_self()-2`? The value returned from `pthread_self()` is an opaque identifier. How do you know you can subtract 2 from it and use it as an array index? – Celada Dec 22 '12 at 23:36
  • I have main thread, which creates N subthreads, their ids are 2,3,..(N+1), mapping to array of semaphores I shift indexes by (-2) – diana-pure Dec 23 '12 at 06:23
  • From the manpage of `pthread_self()`: "Thread identifiers should be considered opaque." – Celada Dec 23 '12 at 16:09
  • when I tested it, semaphores worked correctly, getvalue returned expected number. Anyway, thank you, I'll probably fix it. But does it help me make it work like barrier? – diana-pure Dec 23 '12 at 17:28
  • 1
    No, it doesn't. But you haven't really said what goes wrong (just "It doesn't work like barrier") so it's hard to guess what the problem is. Maybe `bar.counter` needs to be protected from concurrent updates with a mutex? – Celada Dec 23 '12 at 17:40
  • Frankly, this code is just my attempt(it is compiled, but N threads are waiting each other just once 1st time and then they are waking up on barrier one-by-one, but not all in a lump). I'm asking for algorithm, which works. – diana-pure Dec 24 '12 at 07:03
  • 1
    Well, it looks OK to me at first glance except that `bar.counter` is unprotected against simultaneous modification by multiple threads. I might be missing something else (parallel algorithms are hard to reason about) but you should start with `bar.counter`. Then I guess you can add debugging output to show the state before/after each thread waits, and maybe the output will show a state you didn't expect, which would be a clue. – Celada Dec 24 '12 at 15:49

1 Answers1

1

You need to look at this (PDF), The Little Book of Semaphores by Allen Downey. Specifically section 3.6.7. It's in Python, but gist of it should be clear enough.

bazza
  • 7,580
  • 15
  • 22