# Standardization and API Ergonomics > **The criterion.** Native support for standard programming interfaces — a POSIX pthreads layer especially — > so legacy C/C++ desktop or Linux thread code compiles onto an embedded target with minimal refactoring. ## How Revera answers it The threads / mutex / condition-variable surface is deliberately shaped so a pthreads engineer reads it instantly and embedded-Linux thread code ports **mechanically**. Full POSIX compliance is a **non-goal** — the kernel keeps its own safety model underneath: opaque **kernel-owned handles** (the property that makes unprivileged threads safe), **static pools**, and **caller-provided stacks** (no heap). A thin, opt-in shim [`compat/pthread.h`](../../compat/pthread.h) presents the familiar `pthread_*` names over that; the [`examples/pthread_api`](../../examples/pthread_api) demo is a producer/consumer written in pure POSIX pthreads that builds `-Werror -pedantic-errors` and **runs on the kernel** (verified on QEMU Cortex-A53: `produced=8 consumed=8 → PTHREAD-SHIM PASS`). ## What maps · how to use it | POSIX | Revera | Use these APIs | |---|---|---| | `pthread_create` (+ attr) | attr create (pthread_create shape) | `tk_thread_spawn`, `tk_thread_attr_init` / `setstack` / `setpriority` / `setdetachstate` | | `pthread_join` / `detach` / `exit` / `self` / `equal`, `sched_yield` | near-`#define` | `tk_thread_join` / `detach` / `exit` / `self`, `tk_thread_yield` | | `pthread_mutex_*` + `mutexattr_*` | 1:1 (NORMAL / RECURSIVE / ERRORCHECK, PRIO_INHERIT) | `tk_mutex_init`, `tk_mutex_lock` / `unlock` / `lock_timeout`, `tk_mutexattr_settype` / `setprotocol` | | `pthread_cond_*` | direct (timedwait is relative ms) | `tk_cond_create`, `tk_cond_wait` / `signal` / `broadcast` | *Turn it on by including [`compat/pthread.h`](../../compat/pthread.h) (opt-in) on an embedded board — not on `BOARD=host`, which is real pthreads. Full signatures: [API reference](../reference/api.md).* ## The deliberate divergences (kept as-is, documented) 1. **Caller-provided static stacks** — `pthread_create` needs a stack set via `pthread_attr_setstack` (a valid POSIX call), because the kernel allocates nothing. The malloc-free safety trade. 2. **Kernel-owned opaque handles** — `pthread_t` *is* a `tk_thread_t*`, but the lifecycle is stricter (join reaps the pooled slot). 3. **No async cancellation / TLS / `PTHREAD_MUTEX_INITIALIZER`** — `pthread_cancel` is omitted by design; a pooled object cannot static-init, so ported code uses `pthread_mutex_init`. 4. **Not on `BOARD=host`** — that arch *is* real pthreads; the shim is for embedded targets. ## What can be claimed (honest) A **pthread-shaped compatibility subset** — `pthread_{create,join,detach,exit,self,equal}` + `sched_yield` + `pthread_attr_*` + `pthread_mutex_*`/`mutexattr` + `pthread_cond_*` — that ports embedded-Linux thread code with two mechanical changes: switch the includes to the shim, and give each thread a static stack. It is **not** a drop-in `#include ` and **not** POSIX-conformant (no cancellation, TLS, process scope, or scheduling-policy attributes). Honest framing: *"familiar pthread-style threads/mutex/cond API (opt-in shim), targeting mechanical port-over — not full POSIX conformance."* ## Learn more - **Run it:** [`examples/pthread_api`](../../examples/pthread_api) · the shim [`compat/pthread.h`](../../compat/pthread.h). - **Full API:** [API reference](../reference/api.md).