Zth (libzth)
Loading...
Searching...
No Matches
winfiber.h
Go to the documentation of this file.
1#ifndef ZTH_CONTEXT_WINFIBER_H
2#define ZTH_CONTEXT_WINFIBER_H
3/*
4 * SPDX-FileCopyrightText: 2019-2026 Jochem Rutgers
5 *
6 * SPDX-License-Identifier: MPL-2.0
7 */
8
9#ifndef ZTH_CONTEXT_CONTEXT_H
10# error This file must be included by libzth/context/context.h.
11#endif
12
13#ifdef __cplusplus
14
15# include <windows.h>
16
17# pragma GCC diagnostic push
18# ifdef __MINGW32__
19# pragma GCC diagnostic ignored "-Warray-bounds"
20# endif
21
22namespace zth {
23
24class Context : public impl::ContextArch<Context> {
26public:
28
29 constexpr explicit Context(ContextAttr const& attr) noexcept
30 : base(attr)
31 , m_fiber()
32 {}
33
34 static int init() noexcept
35 {
36 int res = 0;
37 if(ConvertThreadToFiber(nullptr))
38 return 0;
39 else if((res = -(int)GetLastError()))
40 return res;
41 else
42 return EINVAL;
43 }
44
45 int initStack(Stack& UNUSED_PAR(stack), Stack& UNUSED_PAR(usable)) noexcept
46 {
47 // Stack is managed by Windows.
48 usable = stack;
49 return 0;
50 }
51
52 void deinitStack(Stack& UNUSED_PAR(stack)) noexcept {}
53
54 int stackGuardInit() noexcept
55 {
56 // There is no stack to guard.
57 return 0;
58 }
59
60 void stackGuardDeinit() noexcept {}
61
62 void valgrindRegister() noexcept
63 {
64 // There is no stack to register.
65 }
66
67 void valgrindDeregister() noexcept {}
68
69 int create() noexcept
70 {
71 int res = 0;
72 if((res = base::create()))
73 return res;
74
75 if(unlikely(!stack().size)) {
76 // Stackless fiber only saves current context.
77 if((m_fiber = GetCurrentFiber()))
78 return 0;
79 } else if((m_fiber = CreateFiber(
81 reinterpret_cast<LPFIBER_START_ROUTINE>(&context_entry),
82 (LPVOID)this))) {
83 zth_dbg(context, "[%s] Created fiber %p", currentWorker().id_str(),
84 m_fiber);
85 return 0;
86 }
87
88 if((res = -(int)GetLastError()))
89 return res;
90 else
91 return EINVAL;
92 }
93
94 void destroy() noexcept
95 {
96 if(!m_fiber)
97 return;
98
99 // If the current fiber is the one to delete, it is probably not created by us.
100 if(likely(m_fiber != GetCurrentFiber())) {
101 zth_dbg(context, "[%s] Delete fiber %p", currentWorker().id_str(), m_fiber);
102 DeleteFiber(m_fiber);
103 }
104
105 m_fiber = nullptr;
106 }
107
108 void context_switch(Context& to) noexcept
109 {
110 zth_assert(to.m_fiber && to.m_fiber != GetCurrentFiber());
111 SwitchToFiber(to.m_fiber);
112 }
113
114private:
115 LPVOID m_fiber;
116};
117
118} // namespace zth
119
120# pragma GCC diagnostic pop
121#endif // __cplusplus
122#endif // ZTH_CONTEXT_WINFIBER_H
void destroy() noexcept
Definition winfiber.h:94
void valgrindRegister() noexcept
Definition winfiber.h:62
void stackGuardDeinit() noexcept
Definition winfiber.h:60
int create() noexcept
Definition winfiber.h:69
void deinitStack(Stack &UNUSED_PAR(stack)) noexcept
Definition winfiber.h:52
impl::ContextArch< Context > base
Definition winfiber.h:27
static int init() noexcept
Definition winfiber.h:34
void valgrindDeregister() noexcept
Definition winfiber.h:67
void context_switch(Context &to) noexcept
Definition winfiber.h:108
int stackGuardInit() noexcept
Definition winfiber.h:54
constexpr Context(ContextAttr const &attr) noexcept
Definition winfiber.h:29
int initStack(Stack &UNUSED_PAR(stack), Stack &UNUSED_PAR(usable)) noexcept
Definition winfiber.h:45
Stack const & stack() const noexcept
Return the stack address.
Definition context.h:249
int create() noexcept
Create context.
Definition context.h:159
ContextAttr & attr() noexcept
Return the context attributes, requested by the user.
Definition context.h:143
Worker & currentWorker() noexcept
Return the (thread-local) singleton Worker instance.
Definition worker.h:389
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
Definition util.h:189
#define ZTH_CLASS_NEW_DELETE(T)
Define new/delete operators for a class, which are allocator-aware.
Definition allocator.h:143
#define UNUSED_PAR(name)
Definition macros.h:78
void context_entry(Context *context)
static size_t const DefaultFiberStackSize
Default fiber stack size in bytes.
Definition config.h:139
Stack information.
Definition context.h:107
#define zth_assert(expr)
assert(), but better integrated in Zth.
Definition util.h:212
#define likely(expr)
Marks the given expression to likely be evaluated to true.
Definition util.h:40
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.
Definition util.h:55