11 #include <type_traits> 15 #include <hilti/rt/any.h> 16 #include <hilti/rt/exception.h> 17 #include <hilti/rt/lambda.h> 18 #include <hilti/rt/types/reference.h> 19 #include <hilti/rt/util.h> 24 extern "C" void __fiber_run_trampoline(
void* args);
27 extern "C" void __fiber_switch_trampoline(
void* args);
37 using Handle = detail::Fiber;
48 std::unique_ptr<detail::Fiber>
main;
60 std::vector<std::unique_ptr<Fiber>>
cache;
82 std::pair<char*, char*> activeRegion()
const;
88 std::pair<char*, char*> allocatedRegion()
const;
95 size_t activeSize()
const {
return static_cast<size_t>(activeRegion().second - activeRegion().first); }
98 size_t allocatedSize()
const {
return static_cast<size_t>(allocatedRegion().second - allocatedRegion().first); }
101 size_t liveRemainingSize()
const;
110 void restore()
const;
113 const ::Fiber* _fiber;
114 void* _buffer =
nullptr;
118 inline std::ostream& operator<<(std::ostream& out,
const StackBuffer& s) {
151 _exception =
nullptr;
152 _function = std::move(f);
166 bool isMain()
const {
return _type == Type::Main; }
171 case State::Yielded:
return false;
173 case State::Aborting:
174 case State::Finished:
184 auto&& result() {
return std::move(_result); }
185 std::exception_ptr exception()
const {
return _exception; }
187 std::string tag()
const;
189 static std::unique_ptr<Fiber> create();
190 static void destroy(std::unique_ptr<Fiber> f);
191 static void primeCache();
199 uint64_t initialized;
205 friend void ::__fiber_run_trampoline(
void* argsp);
206 friend void ::__fiber_switch_trampoline(
void* argsp);
208 enum class State { Init, Running, Aborting, Yielded, Idle, Finished };
210 void _yield(
const char* tag);
211 void _activate(
const char* tag);
214 static void _startSwitchFiber(
const char* tag,
detail::Fiber* to);
217 static void _finishSwitchFiber(
const char* tag);
223 State _state{State::Init};
224 std::optional<Lambda<hilti::rt::any(resumable::Handle*)>> _function;
225 std::optional<hilti::rt::any> _result;
226 std::exception_ptr _exception;
229 std::unique_ptr<::Fiber> _fiber;
232 Fiber* _caller =
nullptr;
237 #ifdef HILTI_HAVE_SANITIZER 240 const void* stack =
nullptr;
241 size_t stack_size = 0;
242 void* fake_stack =
nullptr;
248 inline static uint64_t _total_fibers;
249 inline static uint64_t _current_fibers;
250 inline static uint64_t _cached_fibers;
251 inline static uint64_t _max_fibers;
252 inline static uint64_t _initialized;
255 std::ostream& operator<<(std::ostream& out,
const Fiber& fiber);
265 extern void checkStack();
282 template<typename Function, typename = std::enable_if_t<std::is_invocable<Function, resumable::Handle*>::value>>
284 _fiber->init(std::move(f));
295 detail::Fiber::destroy(std::move(_fiber));
314 bool hasResult()
const {
return _done && _result.has_value(); }
320 template<
typename Result>
322 assert(static_cast<bool>(_result));
324 if constexpr ( std::is_same<Result, void>::value )
328 return hilti::rt::any_cast<
const Result&>(*_result);
329 }
catch (
const hilti::rt::bad_any_cast& ) {
330 throw InvalidArgument(
"mismatch in result type");
336 explicit operator bool()
const {
return _done; }
341 void checkFiber(
const char*
location)
const {
343 throw std::logic_error(std::string(
"fiber not set in ") + location);
346 std::unique_ptr<detail::Fiber> _fiber;
348 std::optional<hilti::rt::any> _result;
351 namespace resumable::detail {
357 static_assert(! std::is_reference<T>::value,
"copyArg() does not accept references other than ValueReference<T>.");
383 template<
typename Function>
void init()
Definition: init.cc:20
std::shared_ptr< T > asSharedPtr() const
Definition: reference.h:121
std::unique_ptr<::Fiber > shared_stack
Definition: fiber.h:57
size_t activeSize() const
Definition: fiber.h:95
StackBuffer(const ::Fiber *fiber)
Definition: fiber.h:72
Type
Definition: fiber.h:133
void cannot_be_reached() __attribute__((noreturn))
Definition: util.cc:52
Definition: function.h:44
void run()
Definition: fiber.cc:547
const auto & stackBuffer() const
Definition: fiber.h:159
std::unique_ptr< detail::Fiber > main
Definition: fiber.h:48
auto type()
Definition: fiber.h:156
std::pair< char *, char * > activeRegion() const
Definition: fiber.cc:248
size_t allocatedSize() const
Definition: fiber.h:98
Definition: reference.h:47
std::unique_ptr< detail::Fiber > switch_trampoline
Definition: fiber.h:51
std::vector< std::unique_ptr< Fiber > > cache
Definition: fiber.h:60
resumable::Handle * handle()
Definition: fiber.h:308
Definition: location.h:93
bool hasResult() const
Definition: fiber.h:314
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:13
Resumable(Function f)
Definition: fiber.h:283