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 <assert.h> 6#include <zircon/process.h> 7#include <zircon/syscalls.h> 8#include <unittest/unittest.h> 9#include <stdio.h> 10#include <zircon/compiler.h> 11 12extern void thread_entry(uintptr_t arg); 13 14int print_fail(void) { 15 EXPECT_TRUE(false, "Failed"); 16 zx_thread_exit(); 17 return 1; // Not reached 18} 19 20// create a thread using the raw zircon api. 21// cannot use a higher level api because they'll use trampoline functions that'll trash 22// registers on entry. 23zx_status_t raw_thread_create(void (*thread_entry)(uintptr_t arg), uintptr_t arg, 24 zx_handle_t* out) 25{ 26 // preallocated stack to satisfy the thread we create 27 static uint8_t stack[1024] __ALIGNED(16); 28 29 zx_handle_t handle; 30 zx_status_t status = zx_thread_create(zx_process_self(), "", 0, 0, &handle); 31 if (status < 0) 32 return status; 33 34 status = zx_thread_start(handle, (uintptr_t)thread_entry, 35 (uintptr_t)stack + sizeof(stack), 36 arg, 0); 37 if (status < 0) { 38 zx_handle_close(handle); 39 return status; 40 } 41 42 *out = handle; 43 return ZX_OK; 44} 45 46bool tis_test(void) { 47 BEGIN_TEST; 48 uintptr_t arg = 0x1234567890abcdef; 49 zx_handle_t handle = ZX_HANDLE_INVALID; 50 zx_status_t status = raw_thread_create(thread_entry, arg, & handle); 51 ASSERT_EQ(status, ZX_OK, "Error while thread creation"); 52 53 status = zx_object_wait_one(handle, ZX_THREAD_TERMINATED, ZX_TIME_INFINITE, NULL); 54 ASSERT_GE(status, 0, "Error while thread wait"); 55 END_TEST; 56} 57 58BEGIN_TEST_CASE(tis_tests) 59RUN_TEST(tis_test) 60END_TEST_CASE(tis_tests) 61 62int main(int argc, char** argv) { 63 return unittest_run_all_tests(argc, argv) ? 0 : -1; 64} 65