1// Copyright 2016 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <lib/sync/completion.h> 6 7#include <zircon/syscalls.h> 8#include <unittest/unittest.h> 9#include <stddef.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13#include <threads.h> 14 15static sync_completion_t completion; 16 17#define ITERATIONS 64 18 19static int sync_completion_thread_wait(void* arg) { 20 for (int iteration = 0u; iteration < ITERATIONS; iteration++) { 21 zx_status_t status = sync_completion_wait(&completion, ZX_TIME_INFINITE); 22 ASSERT_EQ(status, ZX_OK, "completion wait failed!"); 23 } 24 25 return 0; 26} 27 28static int sync_completion_thread_signal(void* arg) { 29 for (int iteration = 0u; iteration < ITERATIONS; iteration++) { 30 sync_completion_reset(&completion); 31 zx_nanosleep(zx_deadline_after(ZX_USEC(10))); 32 sync_completion_signal(&completion); 33 } 34 35 return 0; 36} 37 38static bool test_initializer(void) { 39 BEGIN_TEST; 40 // Let's not accidentally break .bss'd completions 41 static sync_completion_t static_completion; 42 sync_completion_t completion; 43 int status = memcmp(&static_completion, &completion, sizeof(sync_completion_t)); 44 EXPECT_EQ(status, 0, "completion's initializer is not all zeroes"); 45 END_TEST; 46} 47 48#define NUM_THREADS 16 49 50static bool test_completions(void) { 51 BEGIN_TEST; 52 thrd_t signal_thread; 53 thrd_t wait_thread[NUM_THREADS]; 54 55 for (int idx = 0; idx < NUM_THREADS; idx++) 56 thrd_create_with_name(wait_thread + idx, sync_completion_thread_wait, NULL, "completion wait"); 57 thrd_create_with_name(&signal_thread, sync_completion_thread_signal, NULL, "completion signal"); 58 59 for (int idx = 0; idx < NUM_THREADS; idx++) 60 thrd_join(wait_thread[idx], NULL); 61 thrd_join(signal_thread, NULL); 62 63 END_TEST; 64} 65 66static bool test_timeout(void) { 67 BEGIN_TEST; 68 zx_time_t timeout = 0u; 69 sync_completion_t completion; 70 for (int iteration = 0; iteration < 1000; iteration++) { 71 timeout += 2000u; 72 zx_status_t status = sync_completion_wait(&completion, timeout); 73 ASSERT_EQ(status, ZX_ERR_TIMED_OUT, "wait returned spuriously!"); 74 } 75 END_TEST; 76} 77 78BEGIN_TEST_CASE(sync_completion_tests) 79RUN_TEST(test_initializer) 80RUN_TEST(test_completions) 81RUN_TEST(test_timeout) 82END_TEST_CASE(sync_completion_tests) 83