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 
12 extern void thread_entry(uintptr_t arg);
13 
print_fail(void)14 int 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.
raw_thread_create(void (* thread_entry)(uintptr_t arg),uintptr_t arg,zx_handle_t * out)23 zx_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 
tis_test(void)46 bool 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 
58 BEGIN_TEST_CASE(tis_tests)
RUN_TEST(tis_test)59 RUN_TEST(tis_test)
60 END_TEST_CASE(tis_tests)
61 
62 int main(int argc, char** argv) {
63     return unittest_run_all_tests(argc, argv) ? 0 : -1;
64 }
65