23 # if __cplusplus >= 201103L
27 # if __cplusplus < 201103L
28 # undef ZTH_TYPEDFIBER98
30 # define ZTH_TYPEDFIBER98 1
31 # elif !defined(ZTH_TYPEDFIBER98)
34 # define ZTH_TYPEDFIBER98 0
39 template <
typename R,
typename F>
117 template <typename R, typename F>
121 template <typename R, typename F>
154 fiber.setStackSize(m_stack);
169 # if __cplusplus >= 201103L
178 : m_name(std::move(name))
181 explicit setName(
char const* name)
185 explicit setName(
string const& name)
186 : m_name(name.c_str())
194 # if __cplusplus >= 201103L
195 fiber.setName(std::move(m_name));
197 fiber.setName(m_name);
202 # if __cplusplus >= 201103L
240 reinterpret_cast<Gate*
>(gate)->pass();
245 fiber.addCleanup(&cleanup, (
void*)m_gate);
252 template <
typename T>
274 template <
typename F>
281 template <
typename F>
284 this->reset(
fiber.withFuture().get());
290 this->reset(af.
get());
295 # if ZTH_TYPEDFIBER98
296 template <
typename R>
297 class TypedFiber0 final :
public TypedFiber<R, R (*)()> {
300 typedef TypedFiber<R, R (*)()> base;
302 explicit TypedFiber0(
typename base::Function
function)
309 virtual
void entry_() final
311 this->setFuture(this->
function()());
316 class TypedFiber0<void> final :
public TypedFiber<void, void (*)()> {
319 typedef TypedFiber<void, void (*)()> base;
321 explicit TypedFiber0(
typename base::Function
function)
328 virtual
void entry_() final
335 template <
typename R,
typename A1>
336 class TypedFiber1 final :
public TypedFiber<R, R (*)(A1)> {
339 typedef TypedFiber<R, R (*)(A1)> base;
341 TypedFiber1(
typename base::Function
function, A1 a1)
349 virtual
void entry_() final
351 this->setFuture(this->
function()(m_a1));
358 template <
typename A1>
359 class TypedFiber1<void, A1> final :
public TypedFiber<void, void (*)(A1)> {
362 typedef TypedFiber<void, void (*)(A1)> base;
364 TypedFiber1(
typename base::Function
function, A1 a1)
372 virtual
void entry_() final
374 this->
function()(m_a1);
382 template <
typename R,
typename A1,
typename A2>
383 class TypedFiber2 final :
public TypedFiber<R, R (*)(A1, A2)> {
386 typedef TypedFiber<R, R (*)(A1, A2)> base;
388 TypedFiber2(
typename base::Function
function, A1 a1, A2 a2)
397 virtual
void entry_() final
399 this->setFuture(this->
function()(m_a1, m_a2));
407 template <
typename A1,
typename A2>
408 class TypedFiber2<void, A1, A2> final :
public TypedFiber<void, void (*)(A1, A2)> {
411 typedef TypedFiber<void, void (*)(A1, A2)> base;
413 TypedFiber2(
typename base::Function
function, A1 a1, A2 a2)
422 virtual
void entry_() final
424 this->
function()(m_a1, m_a2);
433 template <
typename R,
typename A1,
typename A2,
typename A3>
434 class TypedFiber3 final :
public TypedFiber<R, R (*)(A1, A2, A3)> {
437 typedef TypedFiber<R, R (*)(A1, A2, A3)> base;
439 TypedFiber3(
typename base::Function
function, A1 a1, A2 a2, A3 a3)
449 virtual
void entry_() final
451 this->setFuture(this->
function()(m_a1, m_a2, m_a3));
460 template <
typename A1,
typename A2,
typename A3>
461 class TypedFiber3<void, A1, A2, A3> final :
public TypedFiber<void, void (*)(A1, A2, A3)> {
464 typedef TypedFiber<void, void (*)(A1, A2, A3)> base;
466 TypedFiber3(
typename base::Function
function, A1 a1, A2 a2, A3 a3)
476 virtual
void entry_() final
478 this->
function()(m_a1, m_a2, m_a3);
489 # if __cplusplus >= 201103L
490 template <
typename R,
typename... Args>
496 template <
typename... Args_>
500 , m_args(std::forward<Args_>(args)...)
506 virtual
void entry_() final
508 entry__(
typename SequenceGenerator<
sizeof...(Args)>::
type());
512 template <
size_t... S>
515 this->setFuture(this->
function()(std::get<S>(m_args)...));
519 std::tuple<Args...> m_args;
522 template <
typename... Args>
528 template <
typename... Args_>
532 , m_args(std::forward<Args_>(args)...)
538 virtual
void entry_() final
540 entry__(
typename SequenceGenerator<
sizeof...(Args)>::
type());
544 template <
size_t... S>
547 this->
function()(std::get<S>(m_args)...);
552 std::tuple<Args...> m_args;
556 template <
typename F>
559 # if ZTH_TYPEDFIBER98
560 template <
typename R>
563 typedef R returnType;
564 typedef TypedFiber0<R> fiberType;
565 typedef NoArg a1Type;
566 typedef NoArg a2Type;
567 typedef NoArg a3Type;
570 template <
typename R,
typename A1>
571 struct TypedFiberType<R (*)(A1)> {
573 typedef R returnType;
574 typedef TypedFiber1<R, A1> fiberType;
576 typedef NoArg a2Type;
577 typedef NoArg a3Type;
580 template <
typename R,
typename A1,
typename A2>
581 struct TypedFiberType<R (*)(A1, A2)> {
583 typedef R returnType;
584 typedef TypedFiber2<R, A1, A2> fiberType;
587 typedef NoArg a3Type;
590 template <
typename R,
typename A1,
typename A2,
typename A3>
591 struct TypedFiberType<R (*)(A1, A2, A3)> {
593 typedef R returnType;
594 typedef TypedFiber3<R, A1, A2, A3> fiberType;
601 # if __cplusplus >= 201103L
602 template <
typename R,
typename... Args>
614 template <
typename F>
626 : m_function(
function)
630 # if ZTH_TYPEDFIBER98
631 TypedFiber_type& operator()()
const
633 return polish(*
new TypedFiber_type(m_function));
636 TypedFiber_type& operator()(A1 a1)
const
638 return polish(*
new TypedFiber_type(m_function, a1));
641 TypedFiber_type& operator()(A1 a1, A2 a2)
const
643 return polish(*
new TypedFiber_type(m_function, a1, a2));
646 TypedFiber_type& operator()(A1 a1, A2 a2, A3 a3)
const
648 return polish(*
new TypedFiber_type(m_function, a1, a2, a3));
652 # if __cplusplus >= 201103L
653 template <
typename... Args>
656 return polish(*
new TypedFiber_type(m_function, std::forward<Args>(args)...));
664 fiber.setName(m_name);
675 template <
typename F>
682 template <
typename F>
685 # if ZTH_TYPEDFIBER98
686 template <
typename R>
689 template <
typename R,
typename A1>
690 struct fiber_type<R (*)(A1)> :
public fiber_type_impl<R (*)(A1)> {};
692 template <
typename R,
typename A1,
typename A2>
693 struct fiber_type<R (*)(A1, A2)> :
public fiber_type_impl<R (*)(A1, A2)> {};
695 template <
typename R,
typename A1,
typename A2,
typename A3>
696 struct fiber_type<R (*)(A1, A2, A3)> :
public fiber_type_impl<R (*)(A1, A2, A3)> {};
699 # if __cplusplus >= 201103L
700 template <
typename R,
typename... Args>
712 template <
typename F>
726 # define zth_fiber_declare_1(f) \
728 namespace fibered { \
729 extern ::zth::TypedFiberFactory<decltype(&::f)> const f; \
738 # define zth_fiber_declare(...) FOREACH(zth_fiber_declare_1, ##__VA_ARGS__)
740 # define zth_fiber_define_1(storage, f) \
742 namespace fibered { \
743 storage ::zth::TypedFiberFactory<decltype(&::f)> const \
744 f(&::f, ::zth::Config::EnableDebugPrint || ::zth::Config::EnablePerfEvent \
745 ? ZTH_STRINGIFY(f) "()" \
749 typedef ::zth::TypedFiberFactory<decltype(&::f)>::AutoFuture_type f##_future;
750 # define zth_fiber_define_extern_1(f) zth_fiber_define_1(extern, f)
751 # define zth_fiber_define_static_1(f) zth_fiber_define_1(static constexpr, f)
758 # define zth_fiber_define(...) FOREACH(zth_fiber_define_extern_1, ##__VA_ARGS__)
765 # define zth_fiber(...) FOREACH(zth_fiber_define_static_1, ##__VA_ARGS__)
787 # define zth_async ::zth::fibered::
788 # ifndef ZTH_NO_ASYNC_KEYWORD
789 # define async zth_async
797 void (*f)(
void*),
void* arg =
nullptr,
size_t stack = 0,
798 char const* name =
nullptr) noexcept
805 }
catch(std::bad_alloc
const&) {
827 ZTH_EXPORT
int zth_fiber_create(
void (*f)(
void*),
void* arg,
size_t stack,
char const* name);
AutoFuture & operator=(AutoFuture const &af)
AutoFuture & operator=(TypedFiber< T, F > &fiber)
constexpr AutoFuture(AutoFuture const &af) noexcept
constexpr AutoFuture(base const &p) noexcept
SharedPointer< Future< T > > base
AutoFuture(TypedFiber< T, F > &fiber)
virtual ~AutoFuture() override=default
int setStackSize(size_t size) noexcept
constexpr FiberManipulator() noexcept=default
virtual void apply(Fiber &fiber) const =0
Fiber-aware barrier/gate.
constexpr T * get() const noexcept
TypedFiberType< Function >::fiberType TypedFiber_type
TypedFiberType< Function >::a1Type A1
TypedFiberType< Function >::returnType Return
TypedFiberType< Function >::a2Type A2
TypedFiber_type & polish(TypedFiber_type &fiber) const
TypedFiberType< Function >::a3Type A3
AutoFuture< Return > AutoFuture_type
TypedFiber_type & operator()(Args &&... args) const
constexpr TypedFiberFactory(Function function, char const *name) noexcept
Future< Return > Future_type
TypedFiber(Function function)
void setFuture(T const &r)
void registerFuture(Future_type *future)
static void entry(void *that)
SharedPointer< Future_type > withFuture()
virtual ~TypedFiber() override=default
Function function() const noexcept
Future_type * future() const
TypedFiberN(typename base::Function function, Args_ &&... args)
virtual ~TypedFiberN() final=default
TypedFiber< void, void(*)(Args...)> base
virtual ~TypedFiberN() final=default
TypedFiber< R, R(*)(Args...)> base
TypedFiberN(typename base::Function function, Args_ &&... args)
virtual char const * id_str() const override
string const & name() const noexcept
void setName(string const &name)
void add(Fiber *fiber) noexcept
Makes the fiber pass the given gate upon exit.
virtual void apply(Fiber &fiber) const override
virtual ~passOnExit() override=default
constexpr passOnExit(Gate &gate) noexcept
Change the name of a fiber returned by async.
setName(string const &name)
setName(char const *name)
virtual ~setName() override=default
Change the stack size of a fiber returned by async.
virtual ~setStackSize() override=default
constexpr setStackSize(size_t stack) noexcept
int zth_fiber_create(void(*f)(void *), void *arg=nullptr, size_t stack=0, char const *name=nullptr) noexcept
Run a function as a new fiber.
Worker & currentWorker() noexcept
Return the (thread-local) singleton Worker instance.
fiber_type< F >::factory fiber(F f, char const *name=nullptr)
Create a new fiber.
#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.
string format(char const *fmt,...)
Format like sprintf(), but save the result in an zth::string.
static bool const EnablePerfEvent
Enable (but not necessarily record) perf.
static bool const EnableDebugPrint
Actually do print the debug output.
static bool const EnableStackWaterMark
When true, enable stack watermark to detect maximum stack usage.
static bool const NamedSynchronizer
Save names for all zth::Synchronizer instances.
TypedFiberN< R, Args... > fiberType
TypedFiberFactory< F > factory
factory::AutoFuture_type future
factory::TypedFiber_type & fiber
#define likely(expr)
Marks the given expression to likely be evaluated to true.
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.