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 #ifndef LIB_ZX_THREAD_H_
6 #define LIB_ZX_THREAD_H_
7 
8 #include <lib/zx/object.h>
9 #include <lib/zx/task.h>
10 #include <zircon/process.h>
11 
12 namespace zx {
13 class process;
14 
15 class thread : public task<thread> {
16 public:
17     static constexpr zx_obj_type_t TYPE = ZX_OBJ_TYPE_THREAD;
18 
19     constexpr thread() = default;
20 
thread(zx_handle_t value)21     explicit thread(zx_handle_t value)
22         : task(value) {}
23 
thread(handle && h)24     explicit thread(handle&& h)
25         : task(h.release()) {}
26 
thread(thread && other)27     thread(thread&& other)
28         : task(other.release()) {}
29 
30     thread& operator=(thread&& other) {
31         reset(other.release());
32         return *this;
33     }
34 
35     // Rather than creating a thread directly with this syscall, consider using
36     // std::thread or thrd_create, which properly integrates with the
37     // thread-local data structures in libc.
38     static zx_status_t create(const process& process, const char* name,
39                               uint32_t name_len, uint32_t flags,
40                               thread* result);
41 
42     // The first variant maps exactly to the syscall and can be used for
43     // launching threads in remote processes. The second variant is for
44     // conveniently launching threads in the current process.
start(uintptr_t thread_entry,uintptr_t stack,uintptr_t arg1,uintptr_t arg2)45     zx_status_t start(uintptr_t thread_entry, uintptr_t stack, uintptr_t arg1,
46                       uintptr_t arg2) const {
47         return zx_thread_start(get(), thread_entry, stack, arg1, arg2);
48     }
start(void (* thread_entry)(uintptr_t arg1,uintptr_t arg2),void * stack,uintptr_t arg1,uintptr_t arg2)49     zx_status_t start(void (*thread_entry)(uintptr_t arg1, uintptr_t arg2),
50                       void* stack, uintptr_t arg1, uintptr_t arg2) {
51         return zx_thread_start(get(),
52                                reinterpret_cast<uintptr_t>(thread_entry),
53                                reinterpret_cast<uintptr_t>(stack), arg1, arg2);
54     }
55 
read_state(uint32_t kind,void * buffer,size_t len)56     zx_status_t read_state(uint32_t kind, void* buffer, size_t len) const {
57         return zx_thread_read_state(get(), kind, buffer, len);
58     }
write_state(uint32_t kind,const void * buffer,size_t len)59     zx_status_t write_state(uint32_t kind, const void* buffer, size_t len) {
60         return zx_thread_write_state(get(), kind, buffer, len);
61     }
62 
self()63     static inline unowned<thread> self() {
64         return unowned<thread>(zx_thread_self());
65     }
66 };
67 
68 using unowned_thread = unowned<thread>;
69 
70 } // namespace zx
71 
72 #endif  // LIB_ZX_THREAD_H_
73