/* * Test that we can wake up multiple threads, and that futex_wake() * heeds the wakeup limit. */ void test_futex_wakeup_limit(void) { volatile int futex_value = 1; struct ThreadState threads[4]; int i; for (i = 0; i < NACL_ARRAY_SIZE(threads); i++) { create_waiting_thread(&futex_value, &threads[i]); } check_futex_wake(&futex_value, 2, 2); /* * Test that threads are woken up in the order that they were added * to the wait queue. This is not necessarily true for the Linux * implementation of futexes, but it is true for NaCl's * implementation. */ assert_thread_woken(&threads[0]); assert_thread_woken(&threads[1]); assert_thread_not_woken(&threads[2]); assert_thread_not_woken(&threads[3]); /* Clean up: Wake the remaining threads so that they can exit. */ check_futex_wake(&futex_value, INT_MAX, 2); assert_thread_woken(&threads[2]); assert_thread_woken(&threads[3]); for (i = 0; i < NACL_ARRAY_SIZE(threads); i++) { ASSERT_EQ(pthread_join(threads[i].tid, NULL), 0); } }
/* Test that we can wake up a single thread. */ void test_futex_wakeup(void) { volatile int futex_value = 1; struct ThreadState thread; create_waiting_thread(&futex_value, &thread); check_futex_wake(&futex_value, INT_MAX, 1); assert_thread_woken(&thread); /* Clean up. */ ASSERT_EQ(pthread_join(thread.tid, NULL), 0); }
/* * Check that futex_wait() and futex_wake() heed their address * arguments properly. A futex_wait() call on one address should not * be woken by a futex_wake() call on another address. */ void test_futex_wakeup_address(void) { volatile int futex_value1 = 1; volatile int futex_value2 = 1; volatile int dummy_addr = 1; struct ThreadState thread1; struct ThreadState thread2; create_waiting_thread(&futex_value1, &thread1); create_waiting_thread(&futex_value2, &thread2); check_futex_wake(&dummy_addr, INT_MAX, 0); assert_thread_not_woken(&thread1); assert_thread_not_woken(&thread2); check_futex_wake(&futex_value1, INT_MAX, 1); assert_thread_woken(&thread1); assert_thread_not_woken(&thread2); /* Clean up: Wake the remaining thread so that it can exit. */ check_futex_wake(&futex_value2, INT_MAX, 1); assert_thread_woken(&thread2); ASSERT_EQ(pthread_join(thread1.tid, NULL), 0); ASSERT_EQ(pthread_join(thread2.tid, NULL), 0); }
/* Test that we can wake up a single thread. */ void test_futex_wakeup(void) { volatile int futex_value = 1; struct ThreadState thread; create_waiting_thread(&futex_value, &thread); check_futex_wake(&futex_value, INT_MAX, 1); /* * The thread should have been removed from the wait queue so that * futex_wake() will not return a count of 1 again. futex_wake() * should remove it; it is not enough for futex_wait() to do it. */ check_futex_wake(&futex_value, INT_MAX, 0); assert_thread_woken(&thread); /* Clean up. */ ASSERT_EQ(pthread_join(thread.tid, NULL), 0); }