pth: Use barriers in pthread tests
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 27 Jan 2017 23:38:08 +0000 (18:38 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 9 Feb 2017 17:31:09 +0000 (12:31 -0500)
The use of 'ready' like that assumes that the creator will not block in
between the time it creates the last thread and it hits ready.  It could
block, for instance, on an mmap/malloc.  At that point, the other N threads
would run on the N vcores.  Since pthreads is non-preemptive currently,
thread0 would never run to set 'ready'.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tests/pthread_switch.c
tests/pthread_test.c

index 70df52e..6c013c4 100644 (file)
@@ -14,7 +14,7 @@
 
 pthread_t th1, th2;
 int nr_switch_loops = 100;
-bool ready = FALSE;
+pthread_barrier_t barrier;
 bool should_exit = FALSE;
 
 static void __pth_switch_cb(struct uthread *uthread, void *target)
@@ -36,8 +36,7 @@ void *switch_thread(void *arg)
 {      
        pthread_t other_thr = *(pthread_t*)arg;
 
-       while (!ready)
-               cpu_relax();
+       pthread_barrier_wait(&barrier);
        for (int i = 0; i < nr_switch_loops; i++) {
                cmb();
                if (should_exit)
@@ -73,6 +72,7 @@ int main(int argc, char** argv)
        pthread_need_tls(FALSE);
        pthread_mcp_init();                                     /* gives us one vcore */
 
+       pthread_barrier_init(&barrier, NULL, 2);
        /* each is passed the other's pthread_t.  th1 starts the switching. */
        if (pthread_create(&th1, NULL, &switch_thread, &th2))
                perror("pth_create 1 failed");
@@ -83,8 +83,6 @@ int main(int argc, char** argv)
        if (gettimeofday(&start_tv, 0))
                perror("Start time error...");
 
-       ready = TRUE;                   /* signal to any spinning uthreads to start */
-
        pthread_join(th1, &join_ret);
        pthread_join(th2, &join_ret);
 
index bfd7037..9731f35 100644 (file)
@@ -38,13 +38,12 @@ int amt_fake_work = 0;
 pthread_t my_threads[MAX_NR_TEST_THREADS];
 void *my_retvals[MAX_NR_TEST_THREADS];
 
-bool ready = FALSE;
+pthread_barrier_t barrier;
 
 void *yield_thread(void* arg)
 {      
        /* Wait til all threads are created */
-       while (!ready)
-               cpu_relax();
+       pthread_barrier_wait(&barrier);
        for (int i = 0; i < nr_yield_loops; i++) {
                printf_safe("[A] pthread %d %p on vcore %d, itr: %d\n", pthread_id(),
                            pthread_self(), vcore_id(), i);
@@ -94,6 +93,7 @@ int main(int argc, char** argv)
        }
 #endif /* __ros__ */
 
+       pthread_barrier_init(&barrier, NULL, nr_yield_threads);
        /* create and join on yield */
        for (int i = 0; i < nr_yield_threads; i++) {
                printf_safe("[A] About to create thread %d\n", i);
@@ -102,7 +102,6 @@ int main(int argc, char** argv)
        }
        if (gettimeofday(&start_tv, 0))
                perror("Start time error...");
-       ready = TRUE;                   /* signal to any spinning uthreads to start */
        for (int i = 0; i < nr_yield_threads; i++) {
                printf_safe("[A] About to join on thread %d(%p)\n", i, my_threads[i]);
                pthread_join(my_threads[i], &my_retvals[i]);