Home | History | Annotate | Download | only in tests
      1 #define _GNU_SOURCE
      2 
      3 #include <pthread.h>
      4 #include <sched.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <unistd.h>
      8 #include <config.h>
      9 
     10 /* test based on code from Jeffrey Yasskin, slightly modified. */
     11 /* Reproduces a false positive leak when a pointer is (only) in a live
     12    thread register, and another thread calls exit */
     13 
     14 pthread_mutex_t mu = PTHREAD_MUTEX_INITIALIZER;
     15 int cont = 1;
     16 
     17 void* helper(void* v_bar) {
     18   pthread_barrier_t* bar = (pthread_barrier_t*)v_bar;
     19   register int* i = malloc(sizeof(*i));
     20   // Try hard to have i allocated in a register.
     21   *i = 3;
     22   pthread_barrier_wait(bar);
     23   pthread_mutex_lock(&mu);
     24   while (cont) {
     25 #if defined(VGA_x86) || defined(VGA_amd64)
     26      // Below helps to have i really in a register.
     27      asm volatile("test %0, %0" : : "S"(i));
     28 #else
     29      // Not clear that for other archs, i is in a register.
     30      if (*i) // should do better for other archs.
     31         // "then" part after the #endif
     32 #endif
     33      pthread_mutex_unlock(&mu);
     34      sched_yield();
     35      pthread_mutex_lock(&mu);
     36   }
     37   pthread_mutex_unlock(&mu);
     38   free((void *)i);
     39   fprintf(stderr, "Quitting the helper.\n");
     40   return NULL;
     41 }
     42 
     43 int main() {
     44   pthread_barrier_t bar;
     45   pthread_barrier_init(&bar, NULL, 2);
     46   pthread_t thr;
     47   pthread_create(&thr, NULL, &helper, &bar);
     48   pthread_barrier_wait(&bar);
     49   pthread_barrier_destroy(&bar);
     50   fprintf(stderr, "Abandoning the helper.\n");
     51   pthread_detach(thr);
     52   return 0;
     53 }
     54