blob: 51c69222a05669ad703e391d800ad11a2f2b02c5 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <sync/completion.h>
#include <zircon/syscalls.h>
#include <unittest/unittest.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>
static completion_t completion = COMPLETION_INIT;
#define ITERATIONS 64
static int completion_thread_wait(void* arg) {
for (int iteration = 0u; iteration < ITERATIONS; iteration++) {
zx_status_t status = completion_wait(&completion, ZX_TIME_INFINITE);
ASSERT_EQ(status, ZX_OK, "completion wait failed!");
}
return 0;
}
static int completion_thread_signal(void* arg) {
for (int iteration = 0u; iteration < ITERATIONS; iteration++) {
completion_reset(&completion);
zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
completion_signal(&completion);
}
return 0;
}
static bool test_initializer(void) {
BEGIN_TEST;
// Let's not accidentally break .bss'd completions
static completion_t static_completion;
completion_t completion = COMPLETION_INIT;
int status = memcmp(&static_completion, &completion, sizeof(completion_t));
EXPECT_EQ(status, 0, "completion's initializer is not all zeroes");
END_TEST;
}
#define NUM_THREADS 16
static bool test_completions(void) {
BEGIN_TEST;
thrd_t signal_thread;
thrd_t wait_thread[NUM_THREADS];
for (int idx = 0; idx < NUM_THREADS; idx++)
thrd_create_with_name(wait_thread + idx, completion_thread_wait, NULL, "completion wait");
thrd_create_with_name(&signal_thread, completion_thread_signal, NULL, "completion signal");
for (int idx = 0; idx < NUM_THREADS; idx++)
thrd_join(wait_thread[idx], NULL);
thrd_join(signal_thread, NULL);
END_TEST;
}
static bool test_timeout(void) {
BEGIN_TEST;
zx_time_t timeout = 0u;
completion_t completion = COMPLETION_INIT;
for (int iteration = 0; iteration < 1000; iteration++) {
timeout += 2000u;
zx_status_t status = completion_wait(&completion, timeout);
ASSERT_EQ(status, ZX_ERR_TIMED_OUT, "wait returned spuriously!");
}
END_TEST;
}
BEGIN_TEST_CASE(completion_tests)
RUN_TEST(test_initializer)
RUN_TEST(test_completions)
RUN_TEST(test_timeout)
END_TEST_CASE(completion_tests)
#ifndef BUILD_COMBINED_TESTS
int main(int argc, char** argv) {
return unittest_run_all_tests(argc, argv) ? 0 : -1;
}
#endif