simplify barrier to use only a mutex and condition variable
This commit is contained in:
parent
9ec841143d
commit
14b16f01b6
|
@ -8,7 +8,7 @@ namespace rt
|
|||
class barrier
|
||||
{
|
||||
public:
|
||||
constexpr barrier(int count) : b(RT_BARRIER_INIT(b, count))
|
||||
constexpr barrier(unsigned int count) : b(RT_BARRIER_INIT(b, count))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <rt/cond.h>
|
||||
#include <rt/mutex.h>
|
||||
#include <rt/sem.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
@ -13,7 +12,7 @@ extern "C" {
|
|||
|
||||
struct rt_barrier;
|
||||
|
||||
void rt_barrier_init(struct rt_barrier *barrier, int count);
|
||||
void rt_barrier_init(struct rt_barrier *barrier, unsigned int count);
|
||||
|
||||
/*
|
||||
* Blocks until count threads have called it, at which point it returns
|
||||
|
@ -24,17 +23,15 @@ bool rt_barrier_wait(struct rt_barrier *barrier);
|
|||
|
||||
struct rt_barrier
|
||||
{
|
||||
struct rt_sem sem;
|
||||
struct rt_mutex mutex;
|
||||
struct rt_cond cond;
|
||||
int level, threshold;
|
||||
unsigned int level, threshold, generation;
|
||||
};
|
||||
|
||||
#define RT_BARRIER_INIT(name, count) \
|
||||
{ \
|
||||
.sem = RT_SEM_INIT(name.sem, count), \
|
||||
.mutex = RT_MUTEX_INIT(name.mutex), .cond = RT_COND_INIT(name.cond), \
|
||||
.level = 0, .threshold = (count), \
|
||||
.level = 0, .threshold = (count), .generation = 0, \
|
||||
}
|
||||
|
||||
#define RT_BARRIER(name, count) \
|
||||
|
|
|
@ -1,35 +1,33 @@
|
|||
#include <rt/barrier.h>
|
||||
|
||||
void rt_barrier_init(struct rt_barrier *barrier, int count)
|
||||
void rt_barrier_init(struct rt_barrier *barrier, unsigned int count)
|
||||
{
|
||||
barrier->level = 0;
|
||||
barrier->threshold = count;
|
||||
rt_sem_init(&barrier->sem, count);
|
||||
rt_mutex_init(&barrier->mutex);
|
||||
rt_cond_init(&barrier->cond);
|
||||
barrier->level = 0;
|
||||
barrier->threshold = count;
|
||||
barrier->generation = 0;
|
||||
}
|
||||
|
||||
bool rt_barrier_wait(struct rt_barrier *barrier)
|
||||
{
|
||||
rt_sem_wait(&barrier->sem);
|
||||
|
||||
rt_mutex_lock(&barrier->mutex);
|
||||
const unsigned int generation = barrier->generation;
|
||||
++barrier->level;
|
||||
if (barrier->level == barrier->threshold)
|
||||
const bool is_leader = barrier->level == barrier->threshold;
|
||||
if (is_leader)
|
||||
{
|
||||
barrier->level = 0;
|
||||
++barrier->generation;
|
||||
rt_cond_broadcast(&barrier->cond);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_cond_wait(&barrier->cond, &barrier->mutex);
|
||||
}
|
||||
--barrier->level;
|
||||
const bool complete = barrier->level == 0;
|
||||
if (complete)
|
||||
{
|
||||
rt_sem_post_n(&barrier->sem, barrier->threshold);
|
||||
while (generation == barrier->generation)
|
||||
{
|
||||
rt_cond_wait(&barrier->cond, &barrier->mutex);
|
||||
}
|
||||
}
|
||||
rt_mutex_unlock(&barrier->mutex);
|
||||
|
||||
return complete;
|
||||
return is_leader;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue