Updated code:
Code:
#include <tbb/atomic.h>
#include "semaphore.hpp"
class XEvent
{
public:
XEvent(bool initial_state): m_semaphore(initial_state ? 1 : 0), m_threadsafety(1)
{
if (!initial_state)
m_flag = false;
else
m_flag = true;
}
void wait()
{
m_threadsafety.down();
assert(m_threadsafety.get_count() == 0);
while (!m_flag)
{
m_threadsafety.up();
assert(m_threadsafety.get_count() == 1);
m_semaphore.down();
assert(m_semaphore.get_count() == 0);
m_threadsafety.down();
assert(m_threadsafety.get_count() == 0);
m_semaphore.up();
assert(m_semaphore.get_count() == 1);
}
m_threadsafety.up();
assert(m_threadsafety.get_count() == 1);
}
bool get_status()
{
XSemaphoreLock lock(m_threadsafety);
return m_flag;
}
void signal()
{
XSemaphoreLock lock(m_threadsafety);
if (m_flag)
return;
m_flag = true;
m_semaphore.up();
assert(m_semaphore.get_count() == 1);
}
void clear()
{
XSemaphoreLock lock(m_threadsafety);
if (!m_flag)
return;
m_flag = false;
m_semaphore.down();
assert(m_semaphore.get_count() == 0);
}
protected:
tbb::atomic<bool> m_flag;
XSemaphore m_semaphore;
XSemaphore m_threadsafety;
};
(I probably have to take into account that signal and clear can be called multiple times in sequence.)