# 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
