2015-07-27 03:27:33 +02:00
|
|
|
#pragma once
|
|
|
|
|
2016-04-25 12:49:12 +02:00
|
|
|
#include "types.h"
|
|
|
|
#include "Atomic.h"
|
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
// Binary semaphore
|
|
|
|
class benaphore
|
2015-07-27 03:27:33 +02:00
|
|
|
{
|
2016-04-27 00:27:24 +02:00
|
|
|
struct internal;
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
// Reserved value (-1) enforces *_hard() calls
|
|
|
|
atomic_t<u32> m_value{};
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
atomic_t<internal*> m_data{};
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
void wait_hard();
|
|
|
|
void post_hard();
|
2015-07-27 03:27:33 +02:00
|
|
|
|
|
|
|
public:
|
2016-04-27 00:27:24 +02:00
|
|
|
constexpr benaphore() = default;
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
~benaphore();
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
// Initialize internal data
|
|
|
|
void initialize_once();
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
void wait()
|
|
|
|
{
|
|
|
|
if (UNLIKELY(!m_value.compare_and_swap_test(1, 0)))
|
|
|
|
{
|
|
|
|
wait_hard();
|
|
|
|
}
|
|
|
|
}
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
bool try_wait()
|
|
|
|
{
|
2016-05-13 16:01:48 +02:00
|
|
|
return m_value.compare_and_swap_test(1, 0);
|
2016-04-27 00:27:24 +02:00
|
|
|
}
|
2015-07-27 03:27:33 +02:00
|
|
|
|
2016-04-27 00:27:24 +02:00
|
|
|
void post()
|
|
|
|
{
|
|
|
|
if (UNLIKELY(!m_value.compare_and_swap_test(0, 1)))
|
|
|
|
{
|
|
|
|
post_hard();
|
|
|
|
}
|
|
|
|
}
|
2016-04-25 12:49:12 +02:00
|
|
|
};
|