theRockLiu / thread-sanitizer

Automatically exported from code.google.com/p/thread-sanitizer
0 stars 0 forks source link

pthread_barrier race #21

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi,
I am obviously misunderstanbding the pthread_barrier idiom as I have an issue 
where the main thread + n other threasds wait on a barrier and then main 
continues. The thread receiving the PTHREAD_BARRIER_SERIAL_THREAD calls detroy. 
However, it seem that this causes threadsanitizer to report an error. I cannot 
see how this is a race given my understanding of the barrier call. A simple 
program to demonstrate is below.

What steps will reproduce the problem?
1. See program below

#include <pthread.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>

pthread_barrier_t B;

void *Thread(void *x) {
    if (pthread_barrier_wait(&B) == PTHREAD_BARRIER_SERIAL_THREAD){
          pthread_barrier_destroy(&B);
      }
  return NULL;
}

int main() {
  pthread_t t,t1;
  pthread_barrier_init(&B, 0, 3);
  pthread_create(&t, NULL, Thread, NULL);
  pthread_create(&t1, NULL, Thread, NULL);

  if (pthread_barrier_wait(&B) == PTHREAD_BARRIER_SERIAL_THREAD){
      pthread_barrier_destroy(&B);
  }

  pthread_join(t,NULL);
  pthread_join(t1,NULL);

  return 0;
}

What is the expected output? What do you see instead?
I expect this not to be an issue with threadsanitizer

What version of the product are you using? On what operating system?
gcc (GCC) 4.8.0 20130502 (prerelease)
on linux 3.9.3.1

If I wait until the join completes then call destroy in main there does not 
seem to be an issue (in the real app this will not really be possible unless I 
defer to overall shutdown - which seems a bit wrong.)

regards
Steve

Original issue reported on code.google.com by steview....@googlemail.com on 4 Jun 2013 at 2:34

GoogleCodeExporter commented 9 years ago
The program is buggy, and ThreadSanitizer correctly detects it.
pthread_barrier_destroy() must not be called while threads execute 
pthread_barrier_wait(). I can't find a definitive reference right now, but here 
is something:
http://locklessinc.com/articles/barriers/
It's easy to find other references.

Only pthread_mutex_t can be destroyed that way.
So you need either use additional pthread_mutex_t to safely destroy the 
barrier, or join the threads and then destroy the barrier.

Original comment by dvyu...@google.com on 4 Jun 2013 at 2:45

GoogleCodeExporter commented 9 years ago
Hi Yes I appreciate it is buggy I was trying to work out why. 

I am obviously misunderstanding the return from wait is not guaranteeing what I 
think it is. I was under the impressions all threads were released following 
that call.

thanks

Original comment by steview....@googlemail.com on 4 Jun 2013 at 3:02