37 #ifndef CRL_MULTISENSE_THREAD_HH 38 #define CRL_MULTISENSE_THREAD_HH 45 #include <mach/mach_init.h> 46 #include <mach/task.h> 47 #include <mach/semaphore.h> 54 #include "../Exception.hh" 57 namespace multisense {
84 int32_t priority=0) :
m_flags(flags) {
87 pthread_attr_init(&tattr);
92 if (-1 != scheduler) {
93 struct sched_param sattr = {0};
98 if (0 != pthread_attr_setschedpolicy(&tattr, scheduler))
99 CRL_EXCEPTION(
"pthread_attr_setschedpolicy(scheduler=%d) failed: %s",
100 scheduler, strerror(errno));
104 sattr.sched_priority = priority;
105 if (0 != pthread_attr_setschedparam(&tattr, &sattr))
106 CRL_EXCEPTION(
"pthread_attr_setschedparam(pri=%d) failed: %s",
107 priority, strerror(errno));
112 if (0 != pthread_attr_setinheritsched(&tattr, PTHREAD_EXPLICIT_SCHED))
113 CRL_EXCEPTION(
"pthread_attr_setinheritsched(explicit) failed: %s",
121 0 != pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED))
122 CRL_EXCEPTION(
"pthread_attr_setdetachstate() failed: %s", strerror(errno));
127 if (0 != pthread_create(&
m_id, &tattr, functionP, contextP))
128 CRL_EXCEPTION(
"pthread_create() failed: %s", strerror(errno));
132 if (!(
m_flags & FLAGS_DETACH) &&
133 0 != pthread_join(
m_id, NULL))
134 CRL_DEBUG(
"pthread_join() failed: %s\n", strerror(errno));
151 if (0 != pthread_mutex_init(&m_mutex, NULL))
157 pthread_mutex_destroy(&m_mutex);
161 pthread_mutex_t m_mutex;
184 pthread_mutex_unlock(m_lockP);
189 void lock(pthread_mutex_t *lockP) {
191 pthread_mutex_lock(m_lockP);
194 pthread_mutex_t *m_lockP;
226 ts.tv_nsec = (timeout - ts.tv_sec) * 1e9;
229 int32_t ret = wait_(&ts);
233 else if (ETIMEDOUT == ret)
248 if (m_maximum > 0 && m_avail >= static_cast<int>(m_maximum))
252 __sync_add_and_fetch(&m_avail, 1);
257 semaphore_signal_all(m_sem);
269 int32_t val = m_avail;
271 return __sync_bool_compare_and_swap(&m_avail, val, 0);
275 int32_t
count () {
return m_avail; };
285 semaphore_create(mach_task_self(), &m_sem, SYNC_POLICY_FIFO, 1);
289 semaphore_destroy(mach_task_self(), m_sem);
298 inline int32_t
wait_(
const struct timespec *tsP=NULL) {
303 const int32_t val = m_avail;
304 if (val >= 1 && __sync_bool_compare_and_swap(&m_avail, val, val - 1))
311 __sync_fetch_and_add(&m_waiters, 1);
313 const int32_t ret = semaphore_wait(m_sem);
314 __sync_fetch_and_sub(&m_waiters, 1);
320 if (ETIMEDOUT == ret || -1 == ret)
328 const std::size_t m_maximum;
329 aligned_int32_t m_avail;
330 aligned_int32_t m_waiters;
337 template<
class T>
class WaitVar {
358 const double& timeout) {
360 if (
false == m_sem.timedWait(timeout))
399 m_maximum == m_queue.size()) {
409 m_queue.push_back(data);
424 if (0 == m_queue.size())
427 data = m_queue.front();
435 return m_sem.waiters();
440 return m_queue.size();
446 while(
false == m_sem.clear());
454 const std::size_t m_maximum;
455 std::deque<T> m_queue;
#define CRL_EXCEPTION(fmt,...)
bool timedWait(T &data, const double &timeout)
int32_t wait_(const struct timespec *tsP=NULL)
ScopedLock(pthread_mutex_t &lock)
bool timedWait(const double &timeout)
ScopedLock(pthread_mutex_t *lockP)
static CRL_CONSTEXPR uint32_t FLAGS_DETACH
WaitQueue(std::size_t max=0)
Thread(void *(*functionP)(void *), void *contextP=NULL, uint32_t flags=0, int32_t scheduler=-1, int32_t priority=0)
Semaphore(std::size_t max=0)
#define CRL_DEBUG(fmt,...)
void lock(pthread_mutex_t *lockP)
int32_t aligned_int32_t __attribute__((aligned(4)))