65#ifndef LASS_GUARDIAN_OF_INCLUSION_UTIL_THREAD_H
66#define LASS_GUARDIAN_OF_INCLUSION_UTIL_THREAD_H
79 class ConditionInternal;
81 class ThreadLocalStorageInternal;
114typedef std::vector<bool> TCpuSet;
116LASS_DLL const TCpuSet availableProcessors();
147 bool isLocked()
const;
150 impl::MutexInternal* pimpl_;
171 bool isLocked()
const;
195 impl::ConditionInternal* pimpl_;
216 void bind(
size_t processor);
217 const TCpuSet affinity()
const;
220 static void sleep(
unsigned long milliseconds);
230 friend class impl::ThreadInternal;
232 virtual void doRun() = 0;
234 impl::ThreadInternal* pimpl_;
245 ThreadLocalStorage(
void (*destructor)(
void*) = 0);
246 ~ThreadLocalStorage();
248 void set(
void* value);
250 impl::ThreadLocalStorageInternal* pimpl_;
270class ThreadLocalVariable: NonCopyable
273 typedef typename CallTraits<T>::TValue TValue;
274 typedef typename CallTraits<T>::TParam TParam;
275 typedef typename CallTraits<T>::TConstReference TConstReference;
276 typedef typename CallTraits<T>::TReference TReference;
278 explicit ThreadLocalVariable(TParam prototype = T()):
279 prototype_(prototype),
280 storage_(&ThreadLocalVariable<T>::destructor)
286 TValue* ptr =
static_cast<TValue*
>(storage_.get());
289 TUniquePtr newCopy(
new TValue(prototype_));
290 storage_.set(newCopy.get());
291 ptr = newCopy.release();
296 const TValue* get()
const
298 const TValue* ptr =
static_cast<const TValue*
>(storage_.get());
301 TUniquePtr newCopy(
new TValue(prototype_));
302 storage_.set(newCopy.get());
303 ptr = newCopy.release();
313 const TValue* operator->()
const
318 TReference operator*()
323 TConstReference operator*()
const
330 typedef std::unique_ptr<T> TUniquePtr;
332 static void destructor(
void* p)
334 delete static_cast<T*
>(p);
349 typedef T& TReference;
351 explicit ThreadLocalPtr():
352 storage_(&ThreadLocalPtr<T>::destructor)
356 void reset(TPointer p)
358 TPointer old = get();
363 template <
typename U>
void reset(std::unique_ptr<U>&& p)
365 TPointer old = get();
366 storage_.set(p.get());
373 return static_cast<TPointer
>(storage_.get());
376 TPointer operator->()
const
382 TReference operator*()
const
388 bool operator!()
const
395 static void destructor(
void* p)
397 delete static_cast<T*
>(p);
400 mutable ThreadLocalStorage storage_;
413class Semaphore: NonCopyable
416 Semaphore(
int numberOfSlots = 1): freeSlots_(numberOfSlots) {}
420 bool isLocked()
const {
return freeSlots_ == 0; }
423 std::atomic<int> freeSlots_;
435 bool hasLock()
const {
return hasLock_; }
436 operator bool()
const {
return hasLock_; }
438 LockerBase(
bool hasLock =
true): hasLock_(hasLock) {}
445template <
typename LockType>
446struct DefaultLockTraits
448 static bool lock(LockType& x) { x.lock();
return true; }
449 static void unlock(LockType& x) { x.unlock(); }
452template <
typename LockType>
455 static bool lock(LockType& x) {
return x.tryLock() ==
lockSuccess; }
456 static void unlock(LockType& x) { x.unlock(); }
459template <
typename LockType>
460struct IntegralLockTraits
462 static bool lock(LockType& x) {
atomicLock(x);
return true; }
472 typename LockTraits = DefaultLockTraits<LockType>
477 typedef LockType TLock;
478 typedef LockTraits TLockTraits;
479 Locker(TLock& iLock):
480 LockerBase(TLockTraits::lock(iLock)),
493 TLockTraits::unlock(*lock_);
495 catch (
const std::exception& error)
497 std::cerr <<
"[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: "
498 <<
"exception thrown in ~Locker(): " << error.what() << std::endl;
502 std::cerr <<
"[LASS RUN MSG] UNDEFINED BEHAVIOUR WARNING: "
503 <<
"unknown exception thrown in ~Locker()" << std::endl;
506 const TLock& mutex()
const
511 void swap(Locker& iOther)
513 std::swap(lock_, iOther.lock_);
525inline Locker<T, DefaultLockTraits<T> > makeLocker(T& iLock)
527 return Locker<T, DefaultLockTraits<T> >(iLock);
536inline Locker<T, TryLockTraits<T> > makeTryLocker(T& iLock)
538 return Locker<T, TryLockTraits<T> >(iLock);
547inline Locker<T, IntegralLockTraits<T> > makeIntegralLocker(T& islots)
549 return Locker<T, IntegralLockTraits<T> >(islots);
619#define LASS_LOCK(iLock)\
620 if (const ::lass::util::LockerBase& LASS_UNUSED(lassUtilImplLocker) = ::lass::util::makeLocker(iLock))
622#define LASS_TRY_LOCK(iLock)\
623 if (const ::lass::util::LockerBase& LASS_UNUSED(lassUtilImplLocker) = ::lass::util::makeTryLocker(iLock))
625#define LASS_LOCK_INTEGRAL(iSlots)\
626 if (const ::lass::util::LockerBase& LASS_UNUSED(lassUtilImplLocker) = ::lass::util::makeIntegralLocker(iSlots))
Common base class for lockers.
use as base class if derived should not be copyable
A primitive to provide Thread Local Storage functionality.
static void bindCurrent(size_t processor)
bind current thread to a processor (current as in callee's context)
static constexpr size_t anyProcessor
argument for Thread::bind to unbind the thread so it runs on any processor
void bind(size_t processor)
bind this thread to a processor (this as in this-pointer)
Locker< CriticalSection > CriticalSectionLocker
typedef of Locker for CriticalSection
bool isAvailableProcessor(size_t processor)
Check whether a processor is avaialable.
size_t numberOfAvailableProcessors()
Return total number of processors in machine that are online.
LockResult
Return code for lock functions.
size_t numberOfProcessors()
Return highest id of processor + 1, in this machine.
Locker< Semaphore > SemaphoreLocker
typedef of Locker for Semaphore
WaitResult
Return code for wait functions.
Locker< Mutex > MutexLocker
typedef of Locker for Mutex
@ threadJoinable
joinable thread, can be waited for
@ threadDetached
detached thread
@ lockSuccess
Mutex/CriticalSection is succesfully locked by this thread.
@ lockBusy
Mutex/CriticalSection is locked by another thread.
@ waitSuccess
Wait is successfully terminated.
@ waitTimeout
Wait failed because of a timeout.
void atomicLock(volatile T &semaphore)
bool atomicTryLock(volatile T &semaphore)
void atomicUnlock(volatile T &semaphore)
#define LASS_DLL
DLL interface: import or export symbols?
general utility, debug facilities, ...
Library for Assembled Shared Sources.