3 ms·
> There is, for example, a binary semaphore that persists in the printk() code because mutex_unlock() cannot be called from interrupt context, while up() can.
by colanderman 3y ago
> There is, for example, a binary semaphore that persists in the printk() code because mutex_unlock() cannot be called from interrupt context, while up() can.
Interestingly, this oddity is mirrored in userspace, where `sem_post/3` is async-signal-safe, but most other concurrency primitives (e.g. `pthread_mutex_unlock/3` and `pthread_cond_broadcast/3`) are not.
(`write/2` and friends is the other notable async-signal-safe concurrency primitive, e.g. in combination with an eventfd or a pipe.)
- tonyarkles 3y agoI've been working on a fair bit of RTOS/embedded code recently and we've used a decent number of semaphores for exactly this reason: you can signal a semaphore from an interrupt context. Usually this is being done with a ring buffer where only the interrupt context writes to it and only "userland"[1] reads from it. We initialize the semaphore with an initial value of 0 and a max capacity that matches the capacity of the ring buffer. This lets the userland threads sleep until there's something in the ring buffer without having to worry about trying to use a mutex from inside an interrupt context (which is forbidden). [1] It's not actually userland since it's a Cortex M0 with no MMU, but it's still practical to think of it that way.