31 # ifdef ZTH_USE_VALGRIND
32 # include <valgrind/memcheck.h>
48 zth_assert(m_count < std::numeric_limits<size_t>::max());
106 # if __cplusplus >= 201103L
110 *
this = std::move(p);
115 m_object = p.release();
120 constexpr T*
get() const noexcept
125 constexpr
operator T*()
const noexcept
163 # if __cplusplus >= 201103L
185 m_queue.push_back(*f);
196 if(!m_queue.contains(f))
217 Fiber& f = m_queue.front();
235 while(!m_queue.empty()) {
236 Fiber& f = m_queue.front();
251 , m_synchronizer(synchronizer)
265 m_rang = m_synchronizer.
unblock(m_fiber);
292 return block_(timeout, now);
305 return block_(now + timeout, now);
321 m_queue.push_back(*f);
348 # if __cplusplus >= 201103L
398 # if __cplusplus >= 201103L
409 size_t remaining = count;
410 while(remaining > 0) {
411 if(remaining <= m_count) {
412 m_count -= remaining;
418 remaining -= m_count;
431 if(
unlikely(m_count + count < m_count))
433 m_count = std::numeric_limits<size_t>::max();
464 # if __cplusplus >= 201103L
491 if(!
block(timeout, now))
506 return wait(now + timeout);
509 void signal(
bool queue =
true,
bool queueEveryTime =
false) noexcept
513 if(m_signalled == 0 || queueEveryTime)
541 template <
typename T =
void>
552 # ifdef ZTH_USE_VALGRIND
553 VALGRIND_MAKE_MEM_NOACCESS(m_data,
sizeof(m_data));
557 # if __cplusplus >= 201103L
563 # ifdef ZTH_USE_VALGRIND
564 VALGRIND_MAKE_MEM_NOACCESS(m_data,
sizeof(m_data));
573 # ifdef ZTH_USE_VALGRIND
574 VALGRIND_MAKE_MEM_UNDEFINED(m_data,
sizeof(m_data));
583 operator bool() const noexcept
618 # if __cplusplus >= 201103L
639 return *
static_cast<type*
>(p);
645 void const* p = m_data;
646 return *
static_cast<type const*
>(p);
649 # if __cplusplus >= 201103L
654 return std::move(*
static_cast<type*
>(p));
679 bool set_prepare() noexcept
684 # ifdef ZTH_USE_VALGRIND
685 VALGRIND_MAKE_MEM_UNDEFINED(m_data,
sizeof(m_data));
690 void set_finalize() noexcept
698 alignas(
type)
char m_data[
sizeof(
type)];
714 # if __cplusplus >= 201103L
727 operator bool() const noexcept
766 # if __cplusplus >= 201103L
779 if(++m_current >=
count()) {
780 m_current -=
count();
804 size_t const m_count;
827 }
catch(std::bad_alloc
const&) {
876 return static_cast<zth::Mutex*
>(mutex->p)->trylock() ? 0 : EBUSY;
910 }
catch(std::bad_alloc
const&) {
943 if(
unlikely(!sem || !sem->p || !value))
951 # define EOVERFLOW EAGAIN
965 if(
unlikely(s->
value() == std::numeric_limits<size_t>::max()))
1021 }
catch(std::bad_alloc
const&) {
1107 }
catch(std::bad_alloc
const&) {
1128 future->p =
nullptr;
1139 if(
unlikely(!future || !future->p))
1152 if(
unlikely(!future || !future->p))
1171 if(
unlikely(!future || !future->p || !value))
1185 if(
unlikely(!future || !future->p))
1213 }
catch(std::bad_alloc
const&) {
1233 delete static_cast<zth::Gate*
>(gate->p);
1248 return static_cast<zth::Gate*
>(gate->p)->pass() ? 0 : EBUSY;
1261 static_cast<zth::Gate*
>(gate->p)->wait();
1267 # include <stdint.h>
void nap(Timestamp const &sleepUntil=Timestamp::null()) noexcept
Future(cow_string const &name="Future")
Future(cow_string &&name)
virtual ~Future() override=default
void set(type const &value)
Future & operator=(type &&value)
virtual ~Future() override
type const * operator->() const
Future & operator=(type const &value)
Future(cow_string &&name)
type const & value() const &
bool valid() const noexcept
type const * operator*() const
Future(cow_string const &name="Future")
Fiber-aware barrier/gate.
Gate(size_t count, cow_string &&name)
size_t current() const noexcept
virtual ~Gate() override=default
size_t count() const noexcept
Gate(size_t count, cow_string const &name="Gate")
Mutex(cow_string const &name="Mutex")
virtual ~Mutex() override=default
virtual ~RefCounted()=default
void release(size_t count=1) noexcept
virtual ~Semaphore() override=default
Semaphore(size_t init=0, cow_string const &name="Semaphore")
size_t value() const noexcept
Semaphore(size_t init, cow_string &&name)
void acquire(size_t count=1)
SharedPointer & operator=(SharedPointer const &p)
constexpr SharedPointer(T *object=nullptr) noexcept
constexpr T * operator->() const noexcept
constexpr T * release() noexcept
constexpr SharedPointer(SharedPointer const &p) noexcept
void reset(T *object=nullptr)
constexpr T * get() const noexcept
constexpr SharedPointer & operator=(SharedPointer &&p) noexcept
SharedPointer & operator=(T *object)
constexpr SharedPointer(SharedPointer &&p) noexcept
constexpr T * operator*() const noexcept
void signal(bool queue=true, bool queueEveryTime=false) noexcept
void signalAll(bool queue=true) noexcept
Signal(cow_string &&name)
virtual ~Signal() override=default
bool wait(TimeInterval const &timeout, Timestamp const &now=Timestamp::now())
Signal(cow_string const &name="Signal")
bool wait(Timestamp const &timeout, Timestamp const &now=Timestamp::now())
virtual bool poll(Timestamp const &now=Timestamp::now()) noexcept override
virtual ~AlarmClock() override=default
bool rang() const noexcept
AlarmClock(Synchronizer &synchronizer, Fiber &fiber, Timestamp const &timeout) noexcept
virtual ~Synchronizer() override
bool unblockFirst() noexcept
Synchronizer(cow_string const &name="Synchronizer")
bool unblockAll() noexcept
bool block(TimeInterval const &timeout, Timestamp const &now=Timestamp::now())
Block, with timeout.
Synchronizer(cow_string &&name)
bool block(Timestamp const &timeout, Timestamp const &now=Timestamp::now())
Block, with timeout.
bool unblock(Fiber &f) noexcept
Unblock the specific fiber.
Convenient wrapper around struct timespec that contains a time interval.
constexpr bool isNegative() const noexcept
constexpr bool isNull() const noexcept
virtual bool poll(Timestamp const &now=Timestamp::now()) noexcept override
Timestamp const & timeout() const noexcept
Convenient wrapper around struct timespec that contains an absolute timestamp.
static constexpr Timestamp null() noexcept
friend cow_string str(UniqueIDBase const &)
Keeps track of a process-wide unique ID within the type T.
virtual char const * id_str() const override
string const & name() const noexcept
Fiber & fiber() const noexcept
void scheduleTask(TimedWaitable &w)
void unscheduleTask(TimedWaitable &w)
The class that manages the fibers within this thread.
void release(Fiber &fiber) noexcept
Waiter & waiter() noexcept
bool schedule(Fiber *preferFiber=nullptr, Timestamp const &now=Timestamp::now())
void add(Fiber *fiber) noexcept
int zth_cond_broadcast(zth_cond_t *cond) noexcept
Signals all fibers waiting for the condition.
int zth_future_valid(zth_future_t *future) noexcept
Checks if a future was already set.
int zth_mutex_trylock(zth_mutex_t *mutex) noexcept
Try to lock a mutex.
int zth_gate_pass(zth_gate_t *gate) noexcept
Passes a gate.
int zth_mutex_init(zth_mutex_t *mutex) noexcept
Initializes a mutex.
int zth_cond_signal(zth_cond_t *cond) noexcept
Signals one fiber waiting for the condition.
int zth_gate_init(zth_gate_t *gate, size_t count) noexcept
Initializes a gate.
int zth_cond_wait(zth_cond_t *cond) noexcept
Wait for a condition.
int zth_cond_destroy(zth_cond_t *cond) noexcept
Destroys a condition.
int zth_future_get(zth_future_t *__restrict__ future, uintptr_t *__restrict__ value) noexcept
Wait for and return a future's value.
int zth_gate_wait(zth_gate_t *gate) noexcept
Wait for a gate.
int zth_cond_init(zth_cond_t *cond) noexcept
Initializes a condition.
int zth_sem_post(zth_sem_t *sem) noexcept
Increments a semaphore.
int zth_mutex_lock(zth_mutex_t *mutex) noexcept
Locks a mutex.
int zth_mutex_destroy(zth_mutex_t *mutex) noexcept
Destroys a mutex.
int zth_future_destroy(zth_future_t *future) noexcept
Destroys a future.
int zth_future_set(zth_future_t *future, uintptr_t value) noexcept
Sets a future and signals all waiting fibers.
int zth_sem_init(zth_sem_t *sem, size_t value) noexcept
Initializes a semaphore.
int zth_sem_destroy(zth_sem_t *sem) noexcept
Destroys a semaphore.
int zth_sem_trywait(zth_sem_t *sem) noexcept
Try to decrement a semaphore.
int zth_future_wait(zth_future_t *future) noexcept
Wait for a future.
int zth_gate_destroy(zth_gate_t *gate) noexcept
Destroys a gate.
int zth_sem_getvalue(zth_sem_t *__restrict__ sem, size_t *__restrict__ value) noexcept
Returns the value of a semaphore.
int zth_future_init(zth_future_t *future) noexcept
Initializes a future.
int zth_mutex_unlock(zth_mutex_t *mutex) noexcept
Unlock a mutex.
int zth_sem_wait(zth_sem_t *sem) noexcept
Decrements (or wait for) a semaphore.
void yield(Fiber *preferFiber=nullptr, bool alwaysYield=false, Timestamp const &now=Timestamp::now())
Allow a context switch.
TimeInterval lock(Fsm &fsm)
A wrapper for zth::Fsm::guardLock().
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
std::basic_string< char, std::char_traits< char >, Config::Allocator< char >::type > string
std::string type using Config::Allocator::type.
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
void getContext(Worker **worker, Fiber **fiber) noexcept
The configuration of Zth.
zth::Future< uintptr_t > zth_future_t_type
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define likely(expr)
Marks the given expression to likely be evaluated to true.
#define ZTH_CLASS_NOCOPY(Class)
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.