mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
5602587dd7
It is often desiderable to sync on multiple threads, e.g. there can be a controller thread that waits for `n` worker threads to finish their job. An inverse semaphore provides an easy primitive to implement this pattern. After being initialized with a value `n` (in counter mode), a call to `sema_inv_wait()` will block until each of the `n` threads has called `sema_inv_post()` exactly once. There are situations where workers might post an event more than once (unless additional state is introduced). For this case, the alternative mask mode is provided. Here the inverse semaphore is initialized with a bit mask, each worker can clear one or multiple bits with `sema_inv_post_mask()`. A worker can clear it's bit multiple times.
40 lines
712 B
C
40 lines
712 B
C
/*
|
|
* Copyright (C) 2021 ML!PA Consulting GmbH
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @{
|
|
*
|
|
* @file
|
|
*
|
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
|
*/
|
|
|
|
#include "sema_inv.h"
|
|
|
|
bool sema_inv_post(sema_inv_t *s)
|
|
{
|
|
if (atomic_fetch_sub_u32(&s->value, 1) == 1) {
|
|
mutex_unlock(&s->lock);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool sema_inv_post_mask(sema_inv_t *s, uint32_t mask)
|
|
{
|
|
if (atomic_fetch_and_u32(&s->value, ~mask) == mask) {
|
|
mutex_unlock(&s->lock);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/** @} */
|