1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5 6#include <stddef.h> 7#include <string.h> 8 9#include <zircon/syscalls.h> 10#include <zircon/syscalls/object.h> 11#include <zircon/syscalls/port.h> 12 13#include <runtime/thread.h> 14 15#include "thread-functions.h" 16 17void threads_test_sleep_fn(void* arg) { 18 // Note: You shouldn't use C standard library functions from this thread. 19 zx_time_t time = (zx_time_t)arg; 20 zx_nanosleep(time); 21} 22 23void threads_test_wait_fn(void* arg) { 24 zx_handle_t event = *(zx_handle_t*)arg; 25 zx_object_wait_one(event, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, NULL); 26 zx_object_signal(event, 0u, ZX_USER_SIGNAL_1); 27} 28 29void threads_test_wait_detach_fn(void* arg) { 30 threads_test_wait_fn(arg); 31 // Since we're detached, we are not allowed to return into the default zxr_thread 32 // exit path. 33 zx_thread_exit(); 34} 35 36void threads_test_wait_break_infinite_sleep_fn(void* arg) { 37 zx_handle_t event = *(zx_handle_t*)arg; 38 zx_object_wait_one(event, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, NULL); 39 40 // Don't use builtin_trap since the compiler might assume everything after that call can't 41 // execute and will remove the zx_nanosleep below. 42#if defined(__aarch64__) 43 __asm__ volatile("brk 0"); 44#elif defined(__x86_64__) 45 __asm__ volatile("int3"); 46#else 47#error Not supported on this platform. 48#endif 49 50 zx_nanosleep(ZX_TIME_INFINITE); 51} 52 53void threads_test_busy_fn(void* arg) { 54 volatile uint64_t i = 0u; 55 while (true) { 56 ++i; 57 } 58 __builtin_trap(); 59} 60 61void threads_test_infinite_sleep_fn(void* arg) { 62 zx_nanosleep(ZX_TIME_INFINITE); 63 __builtin_trap(); 64} 65 66void threads_test_infinite_wait_fn(void* arg) { 67 zx_handle_t event = *(zx_handle_t*)arg; 68 zx_object_wait_one(event, ZX_USER_SIGNAL_0, ZX_TIME_INFINITE, NULL); 69 __builtin_trap(); 70} 71 72void threads_test_port_fn(void* arg) { 73 zx_handle_t* port = (zx_handle_t*)arg; 74 zx_port_packet_t packet = {}; 75 zx_port_wait(port[0], ZX_TIME_INFINITE, &packet); 76 packet.key += 5u; 77 zx_port_queue(port[1], &packet); 78} 79 80void threads_test_channel_call_fn(void* arg_) { 81 channel_call_suspend_test_arg* arg = static_cast<channel_call_suspend_test_arg*>(arg_); 82 83 uint8_t send_buf[9] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i' }; 84 uint8_t recv_buf[9]; 85 uint32_t actual_bytes, actual_handles; 86 87 zx_channel_call_args_t call_args = { 88 .wr_bytes = send_buf, 89 .wr_handles = NULL, 90 .rd_bytes = recv_buf, 91 .rd_handles = NULL, 92 .wr_num_bytes = sizeof(send_buf), 93 .wr_num_handles = 0, 94 .rd_num_bytes = sizeof(recv_buf), 95 .rd_num_handles = 0, 96 }; 97 98 arg->call_status = zx_channel_call(arg->channel, 0, ZX_TIME_INFINITE, &call_args, 99 &actual_bytes, &actual_handles); 100 if (arg->call_status == ZX_OK) { 101 if (actual_bytes != sizeof(recv_buf) || 102 memcmp(recv_buf + sizeof(zx_txid_t), "abcdefghj" + sizeof(zx_txid_t), sizeof(recv_buf) - sizeof(zx_txid_t))) { 103 arg->call_status = ZX_ERR_BAD_STATE; 104 } 105 } 106 107 zx_handle_close(arg->channel); 108} 109