|  | # zx_thread_start | 
|  |  | 
|  | ## NAME | 
|  |  | 
|  | <!-- Updated by update-docs-from-fidl, do not edit. --> | 
|  |  | 
|  | Start execution on a thread. | 
|  |  | 
|  | ## SYNOPSIS | 
|  |  | 
|  | <!-- Updated by update-docs-from-fidl, do not edit. --> | 
|  |  | 
|  | ```c | 
|  | #include <zircon/syscalls.h> | 
|  |  | 
|  | zx_status_t zx_thread_start(zx_handle_t handle, | 
|  | zx_vaddr_t thread_entry, | 
|  | zx_vaddr_t stack, | 
|  | uintptr_t arg1, | 
|  | uintptr_t arg2); | 
|  | ``` | 
|  |  | 
|  | ## DESCRIPTION | 
|  |  | 
|  | `zx_thread_start()` causes a thread to begin execution at the program counter | 
|  | specified by *thread_entry* and with the stack pointer set to *stack*. The | 
|  | arguments *arg1* and *arg2* are arranged to be in the architecture specific | 
|  | registers used for the first two arguments of a function call before the thread | 
|  | is started.  All other registers are zero upon start. | 
|  |  | 
|  | When the last handle to a thread is closed, the thread is destroyed. | 
|  |  | 
|  | Thread handles may be waited on and will assert the signal | 
|  | **ZX_THREAD_TERMINATED** when the thread stops executing (due to | 
|  | [`zx_thread_exit()`] being called). | 
|  |  | 
|  | *thread_entry* shall point to a function that must call [`zx_thread_exit()`] or | 
|  | [`zx_futex_wake_handle_close_thread_exit()`] or | 
|  | [`zx_vmar_unmap_handle_close_thread_exit()`] before reaching the last instruction. | 
|  | Below is an example: | 
|  |  | 
|  | ``` | 
|  | void thread_entry(uintptr_t arg1, uintptr_t arg2) __attribute__((noreturn)) { | 
|  | // do work here. | 
|  |  | 
|  | zx_thread_exit(); | 
|  | } | 
|  | ``` | 
|  |  | 
|  | Failing to call one of the exit functions before reaching the end of | 
|  | the function will cause an architecture / toolchain specific exception. | 
|  |  | 
|  | ## RIGHTS | 
|  |  | 
|  | <!-- Updated by update-docs-from-fidl, do not edit. --> | 
|  |  | 
|  | *handle* must be of type **ZX_OBJ_TYPE_THREAD** and have **ZX_RIGHT_MANAGE_THREAD**. | 
|  |  | 
|  | ## RETURN VALUE | 
|  |  | 
|  | `zx_thread_start()` returns **ZX_OK** on success. | 
|  | In the event of failure, a negative error value is returned. | 
|  |  | 
|  | ## ERRORS | 
|  |  | 
|  | **ZX_ERR_BAD_HANDLE**  *thread* is not a valid handle. | 
|  |  | 
|  | **ZX_ERR_WRONG_TYPE**  *thread* is not a thread handle. | 
|  |  | 
|  | **ZX_ERR_ACCESS_DENIED**  The handle *thread* lacks **ZX_RIGHT_WRITE**. | 
|  |  | 
|  | **ZX_ERR_BAD_STATE**  *thread* is not ready to run or the process *thread* | 
|  | is part of is no longer alive. | 
|  |  | 
|  | **ZX_ERR_INVALID_ARGS** *thread_entry* is not a userspace address, is not a | 
|  | [canonical address], or is not `0`. | 
|  |  | 
|  | ## SEE ALSO | 
|  |  | 
|  | - [`zx_futex_wake_handle_close_thread_exit()`] | 
|  | - [`zx_handle_close()`] | 
|  | - [`zx_handle_duplicate()`] | 
|  | - [`zx_object_wait_async()`] | 
|  | - [`zx_object_wait_many()`] | 
|  | - [`zx_object_wait_one()`] | 
|  | - [`zx_thread_create()`] | 
|  | - [`zx_thread_exit()`] | 
|  | - [`zx_vmar_unmap_handle_close_thread_exit()`] | 
|  |  | 
|  | <!-- References updated by update-docs-from-fidl, do not edit. --> | 
|  |  | 
|  | [`zx_futex_wake_handle_close_thread_exit()`]: futex_wake_handle_close_thread_exit.md | 
|  | [`zx_handle_close()`]: handle_close.md | 
|  | [`zx_handle_duplicate()`]: handle_duplicate.md | 
|  | [`zx_object_wait_async()`]: object_wait_async.md | 
|  | [`zx_object_wait_many()`]: object_wait_many.md | 
|  | [`zx_object_wait_one()`]: object_wait_one.md | 
|  | [`zx_thread_create()`]: thread_create.md | 
|  | [`zx_thread_exit()`]: thread_exit.md | 
|  | [`zx_vmar_unmap_handle_close_thread_exit()`]: vmar_unmap_handle_close_thread_exit.md | 
|  | [canonical address]: ../../concepts/kernel/sysret_problem.md |