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

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

This sample has a barber who sleeps on a semaphore until a customer arrives, and a waiting room of three chairs. Five customers arrive at once: three sit down, two find no chair and leave.

It is the shape of a server with a bounded backlog: looking for a free chair and taking it happen under one lock, and a caller that finds none is turned away instead of waiting. Which two leave depends on the order the kernel runs the customers in, which have the same priority.

Run:

`pbl samples samples/kernel/classic/sleeping_barber`

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\_CHAIRS 3#define NUM\_CUSTOMERS 5/\* Customers run above the barber, so all of them arrive before the first haircut starts. \*/#define CUSTOMER\_PRIO (CONFIG\_KERNEL\_MAIN\_THREAD\_PRIO - 1)#define BARBER\_PRIO (CONFIG\_KERNEL\_MAIN\_THREAD\_PRIO - 2)struct customer {unsigned int id;struct pbl\_thread thread;};/\* Counts the customers waiting, which is what the barber sleeps on. \*/static PBL\_SEM\_DEFINE(s\_customers, 0, NUM\_CHAIRS);/\* Given by the barber when he is ready for the next one. \*/static PBL\_SEM\_DEFINE(s\_barber\_chair, 0, 1);static PBL\_MUTEX\_DEFINE(s\_shop\_lock);static unsigned int s\_waiting;static unsigned int s\_haircuts;static unsigned int s\_turned\_away;static struct customer s\_customers\_list[NUM\_CUSTOMERS];static struct pbl\_thread s\_barber;PBL\_THREAD\_STACK\_DEFINE(s\_barber\_stack, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_0, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_1, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_2, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_3, 1024);PBL\_THREAD\_STACK\_DEFINE(s\_stack\_4, 1024);static void prv\_barber(void \*arg) {for (;;) {/\* Asleep until a customer sits down in the waiting room. \*/pbl\_sem\_take(&s\_customers, PBL\_FOREVER);pbl\_mutex\_lock(&s\_shop\_lock, PBL\_FOREVER);s\_waiting--;pbl\_mutex\_unlock(&s\_shop\_lock);pbl\_sem\_give(&s\_barber\_chair);pbl\_sleep\_ms(20);pbl\_mutex\_lock(&s\_shop\_lock, PBL\_FOREVER);s\_haircuts++;pbl\_mutex\_unlock(&s\_shop\_lock);}}static void prv\_customer(void \*arg) {const struct customer \*customer = arg;bool seated;/\* Looking for a chair and taking it is one step, or two customers could take the last one. \*/pbl\_mutex\_lock(&s\_shop\_lock, PBL\_FOREVER);seated = s\_waiting \< NUM\_CHAIRS;if (seated) {s\_waiting++;} else {s\_turned\_away++;}pbl\_mutex\_unlock(&s\_shop\_lock);if (!seated) {PBL\_LOG\_INFO("customer %u: no free chair, leaves", customer-\>id);return;}pbl\_sem\_give(&s\_customers);pbl\_sem\_take(&s\_barber\_chair, PBL\_FOREVER);PBL\_LOG\_INFO("customer %u: in the barber chair", customer-\>id);}static void prv\_start(struct pbl\_thread \*t, const char \*name, pbl\_thread\_entry\_t entry, void \*arg,pbl\_prio\_t prio, void \*stack) {const struct pbl\_thread\_attr attr = {.name = name,.entry = entry,.arg = arg,.prio = prio,.privileged = true,.stack = stack,.stack\_size = sizeof(s\_barber\_stack),};pbl\_thread\_create(t, &attr);}int main(void) {void \*const stacks[NUM\_CUSTOMERS] = {s\_stack\_0, s\_stack\_1, s\_stack\_2, s\_stack\_3, s\_stack\_4};int ret;prv\_start(&s\_barber, "barber", prv\_barber, NULL, BARBER\_PRIO, s\_barber\_stack);pbl\_sleep\_ms(10);PBL\_LOG\_INFO("shop: empty, barber asleep: %s",pbl\_thread\_state(&s\_barber) == PBL\_THREAD\_BLOCKED ? "yes" : "no");PBL\_LOG\_INFO("shop: %u customers arrive at once, for %u chairs", NUM\_CUSTOMERS, NUM\_CHAIRS);for (unsigned int i = 0; i \< NUM\_CUSTOMERS; i++) {s\_customers\_list[i].id = i;prv\_start(&s\_customers\_list[i].thread, "customer", prv\_customer, &s\_customers\_list[i],CUSTOMER\_PRIO, stacks[i]);}ret = PBL\_POLL\_SLEEP\_MS(s\_haircuts + s\_turned\_away == NUM\_CUSTOMERS, 5, 1000);if (ret != 0) {PBL\_LOG\_ERR("shop: customers still waiting (%d)", ret);return ret;}pbl\_sleep\_ms(10);PBL\_LOG\_INFO("shop: %u haircuts, %u customers turned away", s\_haircuts, s\_turned\_away);PBL\_LOG\_INFO("shop: empty, barber asleep: %s",pbl\_thread\_state(&s\_barber) == PBL\_THREAD\_BLOCKED ? "yes" : "no");PBL\_LOG\_INFO("Sample done");return 0;}
```

## Output

```
shop: empty, barber asleep: yes
shop: 5 customers arrive at once, for 3 chairs
customer \d: no free chair, leaves
customer \d: no free chair, leaves
customer \d: in the barber chair
customer \d: in the barber chair
customer \d: in the barber chair
shop: 3 haircuts, 2 customers turned away
shop: empty, barber asleep: yes
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/sleeping\_barber.md](https://github.com/coredevices/pebbleos/blob/f4926c952bf9b82bce9e3cdb44645a59531c0ee9/docs/samples/kernel/classic/sleeping_barber.md).
