2018-07-06 14:11:38 +00:00
|
|
|
#ifndef BASE_TL_THREADING_H
|
|
|
|
#define BASE_TL_THREADING_H
|
2011-12-30 15:02:22 +00:00
|
|
|
|
|
|
|
#include "../system.h"
|
2021-12-07 12:18:04 +00:00
|
|
|
#include <atomic>
|
2011-12-30 15:02:22 +00:00
|
|
|
|
2020-11-29 16:53:54 +00:00
|
|
|
class CSemaphore
|
2017-08-31 17:13:55 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
SEMAPHORE m_Sem;
|
2021-12-07 12:18:04 +00:00
|
|
|
// implement the counter seperatly, because the `sem_getvalue`-API is
|
|
|
|
// deprecated on macOS: https://stackoverflow.com/a/16655541
|
2022-01-09 15:22:07 +00:00
|
|
|
std::atomic_int m_Count{0};
|
2020-09-26 19:41:58 +00:00
|
|
|
|
2017-08-31 17:13:55 +00:00
|
|
|
public:
|
2020-11-29 16:53:54 +00:00
|
|
|
CSemaphore() { sphore_init(&m_Sem); }
|
|
|
|
~CSemaphore() { sphore_destroy(&m_Sem); }
|
|
|
|
CSemaphore(const CSemaphore &) = delete;
|
2022-01-09 15:22:07 +00:00
|
|
|
int GetApproximateValue() { return m_Count.load(); }
|
2021-12-07 12:18:04 +00:00
|
|
|
void Wait()
|
|
|
|
{
|
|
|
|
sphore_wait(&m_Sem);
|
2022-01-09 15:22:07 +00:00
|
|
|
m_Count.fetch_sub(1);
|
2021-12-07 12:18:04 +00:00
|
|
|
}
|
|
|
|
void Signal()
|
|
|
|
{
|
2022-01-09 15:22:07 +00:00
|
|
|
m_Count.fetch_add(1);
|
2021-12-07 12:18:04 +00:00
|
|
|
sphore_signal(&m_Sem);
|
|
|
|
}
|
2017-08-31 17:13:55 +00:00
|
|
|
};
|
2011-12-30 15:02:22 +00:00
|
|
|
|
2020-12-02 18:11:19 +00:00
|
|
|
class SCOPED_CAPABILITY CLock
|
2011-12-30 15:02:22 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
LOCK m_Lock;
|
2011-12-30 15:02:22 +00:00
|
|
|
|
|
|
|
public:
|
2020-12-02 18:11:19 +00:00
|
|
|
CLock() ACQUIRE(m_Lock)
|
2011-12-30 15:02:22 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
m_Lock = lock_create();
|
2011-12-30 15:02:22 +00:00
|
|
|
}
|
|
|
|
|
2020-12-02 18:11:19 +00:00
|
|
|
~CLock() RELEASE()
|
2011-12-30 15:02:22 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
lock_destroy(m_Lock);
|
2011-12-30 15:02:22 +00:00
|
|
|
}
|
2018-08-27 12:49:17 +00:00
|
|
|
|
2020-11-29 16:53:54 +00:00
|
|
|
CLock(const CLock &) = delete;
|
2018-08-29 09:13:13 +00:00
|
|
|
|
2020-12-02 18:11:19 +00:00
|
|
|
void Take() ACQUIRE(m_Lock) { lock_wait(m_Lock); }
|
|
|
|
void Release() RELEASE() { lock_unlock(m_Lock); }
|
2011-12-30 15:02:22 +00:00
|
|
|
};
|
|
|
|
|
2020-11-29 16:53:54 +00:00
|
|
|
class CScopeLock
|
2011-12-30 15:02:22 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
CLock *m_pLock;
|
2020-09-26 19:41:58 +00:00
|
|
|
|
2011-12-30 15:02:22 +00:00
|
|
|
public:
|
2020-11-29 16:53:54 +00:00
|
|
|
CScopeLock(CLock *pLock)
|
2011-12-30 15:02:22 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
m_pLock = pLock;
|
|
|
|
m_pLock->Take();
|
2011-12-30 15:02:22 +00:00
|
|
|
}
|
|
|
|
|
2020-11-29 16:53:54 +00:00
|
|
|
~CScopeLock()
|
2011-12-30 15:02:22 +00:00
|
|
|
{
|
2020-11-29 16:53:54 +00:00
|
|
|
m_pLock->Release();
|
2011-12-30 15:02:22 +00:00
|
|
|
}
|
2018-08-29 09:13:13 +00:00
|
|
|
|
2020-11-29 16:53:54 +00:00
|
|
|
CScopeLock(const CScopeLock &) = delete;
|
2011-12-30 15:02:22 +00:00
|
|
|
};
|
2018-07-06 14:11:38 +00:00
|
|
|
|
|
|
|
#endif // BASE_TL_THREADING_H
|