---
title: "Threads"
canonical_url: https://developer.repebble.com/pebbleos/docs/samples/kernel/threads/
last_updated: 2026-11-13
sdk_version: 4.44
---
# Threads

Source: https://developer.repebble.com/pebbleos/docs/samples/kernel/threads/

This sample creates three [threads](https://developer.repebble.com/pebbleos/docs/kernel/threads.md) from `main()`: one of higher priority, which runs to its end before `pbl_thread_create()` returns, and two of lower priority, which only run once `main()` blocks and then take turns by yielding.

`ping` and `pong` have the same priority, so the kernel also switches between them on every tick: their lines usually alternate, but only the totals are guaranteed.

Run:

`pbl samples samples/kernel/threads`

Boards:

every board

## Sources

src/main.c

```
#include \<pbl/kernel/thread.h\>#include \<pbl/logging/logging.h\>#define ROUNDS 3/\* main() runs at CONFIG\_KERNEL\_MAIN\_THREAD\_PRIO: one thread above it, two below. \*/#define URGENT\_PRIO (CONFIG\_KERNEL\_MAIN\_THREAD\_PRIO + 1)#define PEER\_PRIO (CONFIG\_KERNEL\_MAIN\_THREAD\_PRIO - 1)PBL\_THREAD\_STACK\_DEFINE(s\_urgent\_stack, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_ping\_stack, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_pong\_stack, 1024);static struct pbl\_thread s\_urgent;static struct pbl\_thread s\_ping;static struct pbl\_thread s\_pong;static void prv\_urgent(void \*arg) {PBL\_LOG\_INFO("urgent: preempted main, which is still inside pbl\_thread\_create()");}static void prv\_peer(void \*arg) {unsigned int \*rounds = arg;const char \*name = pbl\_thread\_name(pbl\_thread\_current());for (\*rounds = 0; \*rounds \< ROUNDS; (\*rounds)++) {PBL\_LOG\_INFO("%s: round %u", name, \*rounds);/\* Threads of equal priority also take turns on every tick; yielding does it now. \*/pbl\_thread\_yield();}}static void prv\_start(struct pbl\_thread \*t, const char \*name, pbl\_thread\_entry\_t entry, void \*arg,pbl\_prio\_t prio, void \*stack, size\_t stack\_size) {const struct pbl\_thread\_attr attr = {.name = name,.entry = entry,.arg = arg,.prio = prio,.privileged = true,.stack = stack,.stack\_size = stack\_size,};pbl\_thread\_create(t, &attr);}int main(void) {static unsigned int s\_ping\_rounds;static unsigned int s\_pong\_rounds;PBL\_LOG\_INFO("main: creating a thread of higher priority");prv\_start(&s\_urgent, "urgent", prv\_urgent, NULL, URGENT\_PRIO, s\_urgent\_stack,sizeof(s\_urgent\_stack));PBL\_LOG\_INFO("main: urgent has %s",pbl\_thread\_state(&s\_urgent) == PBL\_THREAD\_DEAD ? "ended" : "not ended");prv\_start(&s\_ping, "ping", prv\_peer, &s\_ping\_rounds, PEER\_PRIO, s\_ping\_stack,sizeof(s\_ping\_stack));prv\_start(&s\_pong, "pong", prv\_peer, &s\_pong\_rounds, PEER\_PRIO, s\_pong\_stack,sizeof(s\_pong\_stack));PBL\_LOG\_INFO("main: created two threads of lower priority, which wait for main to block");while (pbl\_thread\_state(&s\_ping) != PBL\_THREAD\_DEAD ||pbl\_thread\_state(&s\_pong) != PBL\_THREAD\_DEAD) {pbl\_thread\_sleep(PBL\_MSEC(10));}PBL\_LOG\_INFO("main: ping ran %u rounds, pong ran %u rounds", s\_ping\_rounds, s\_pong\_rounds);PBL\_LOG\_INFO("Sample done");return 0;}
```

## Output

```
main: creating a thread of higher priority
urgent: preempted main, which is still inside pbl_thread_create\(\)
main: urgent has ended
main: created two threads of lower priority, which wait for main to block
main: ping ran 3 rounds, pong ran 3 rounds
Sample done
```

Generated from PebbleOS [f4926c952](https://github.com/coredevices/pebbleos/commit/f4926c952bf9b82bce9e3cdb44645a59531c0ee9). This page is maintained in the pebbleos repository: [docs/samples/kernel/threads.md](https://github.com/coredevices/pebbleos/blob/f4926c952bf9b82bce9e3cdb44645a59531c0ee9/docs/samples/kernel/threads.md).
