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

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

This sample builds a barrier from a mutex and a semaphore: three workers get ready at their own pace, and none goes on until all have arrived.

The last one to arrive lets the others through and resets the count, so the same barrier serves round after round.

Run:

`pbl samples samples/kernel/classic/barrier`

Boards:

every board

## Sources

src/main.c

```
#include \<pbl/kernel/delay.h\>#include \<pbl/kernel/mutex.h\>#include \<pbl/kernel/sem.h\>#include \<pbl/kernel/thread.h\>#include \<pbl/logging/logging.h\>#define NUM\_WORKERS 3/\* A point no thread passes until all of them have reached it. \*/struct barrier {struct pbl\_mutex lock;struct pbl\_sem gate;unsigned int parties;unsigned int waiting;};struct worker {unsigned int id;struct pbl\_thread thread;};static struct barrier s\_start\_line = {.lock = PBL\_MUTEX\_INITIALIZER,.gate = PBL\_SEM\_INITIALIZER(0, NUM\_WORKERS),.parties = NUM\_WORKERS,};static struct worker s\_workers[NUM\_WORKERS];static PBL\_MUTEX\_DEFINE(s\_stats\_lock);static unsigned int s\_ready;static unsigned int s\_passed;static unsigned int s\_passed\_early;PBL\_THREAD\_STACK\_DEFINE(s\_stack\_0, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_1, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_2, 1024);static void prv\_barrier\_wait(struct barrier \*barrier) {pbl\_mutex\_lock(&barrier-\>lock, PBL\_FOREVER);if (++barrier-\>waiting == barrier-\>parties) {/\* The last one in lets the others through, and leaves the barrier ready for another round. \*/for (unsigned int i = 0; i \< barrier-\>parties - 1; i++) {pbl\_sem\_give(&barrier-\>gate);}barrier-\>waiting = 0;pbl\_mutex\_unlock(&barrier-\>lock);return;}pbl\_mutex\_unlock(&barrier-\>lock);pbl\_sem\_take(&barrier-\>gate, PBL\_FOREVER);}static void prv\_worker(void \*arg) {const struct worker \*worker = arg;/\* Getting ready takes each worker a different time. \*/pbl\_sleep\_ms(20 \* (worker-\>id + 1));pbl\_mutex\_lock(&s\_stats\_lock, PBL\_FOREVER);s\_ready++;pbl\_mutex\_unlock(&s\_stats\_lock);PBL\_LOG\_INFO("worker %u: ready", worker-\>id);prv\_barrier\_wait(&s\_start\_line);pbl\_mutex\_lock(&s\_stats\_lock, PBL\_FOREVER);if (s\_ready != NUM\_WORKERS) {s\_passed\_early++;}s\_passed++;pbl\_mutex\_unlock(&s\_stats\_lock);}int main(void) {void \*const stacks[NUM\_WORKERS] = {s\_stack\_0, s\_stack\_1, s\_stack\_2};int ret;for (unsigned int i = 0; i \< NUM\_WORKERS; i++) {const struct pbl\_thread\_attr attr = {.name = "worker",.entry = prv\_worker,.arg = &s\_workers[i],.prio = CONFIG\_KERNEL\_MAIN\_THREAD\_PRIO - 1,.privileged = true,.stack = stacks[i],.stack\_size = sizeof(s\_stack\_0),};s\_workers[i].id = i;pbl\_thread\_create(&s\_workers[i].thread, &attr);}for (unsigned int i = 0; i \< NUM\_WORKERS; i++) {ret = PBL\_POLL\_SLEEP\_MS(pbl\_thread\_state(&s\_workers[i].thread) == PBL\_THREAD\_DEAD, 1, 1000);if (ret != 0) {PBL\_LOG\_ERR("main: worker %u did not end (%d)", i, ret);return ret;}}PBL\_LOG\_INFO("main: %u past the barrier, %u of them before the last was ready", s\_passed,s\_passed\_early);PBL\_LOG\_INFO("Sample done");return 0;}
```

## Output

```
worker \d: ready
worker \d: ready
worker \d: ready
main: 3 past the barrier, 0 of them before the last was ready
Sample done
```

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