26 thread_local std::array<uintptr_t, x86::kMainStackSize> x86::gMainStack;
47 buf = AllocStack(allocSize);
50 this->
stack = {
reinterpret_cast<uintptr_t *
>(buf), allocSize /
sizeof(uintptr_t)};
51 this->ownsStack =
true;
65 x86::ValidateStackSize(
stack.size() *
sizeof(uintptr_t));
74 x86::DeallocStack(this->
stack.data());
79 x86::Switch(
static_cast<x86 *
>(from),
this);
89 void x86::ValidateStackSize(
const size_t size) {
90 if(!size)
throw std::runtime_error(
"Size may not be nil");
91 if(size %
kStackAlignment)
throw std::runtime_error(
"Stack is misaligned");
104 void* x86::AllocStack(
const size_t bytes) {
112 throw std::runtime_error(
"posix_memalign() failed");
116 throw std::runtime_error(
"failed to allocate stack");
128 void x86::DeallocStack(
void* stack) {
130 _aligned_free(
stack);
140 void x86::CothreadReturned() {
149 void x86::DereferenceCallInfo(CallInfo *info) {
165 void x86::Prepare(
x86 *wrap,
const Entry &entry) {
167 #pragma GCC diagnostic push
168 #pragma GCC diagnostic ignored "-Winvalid-offsetof"
170 static_assert(offsetof(
x86, stackTop) == COTHREAD_OFF_CONTEXT_TOP,
"cothread stack top is invalid");
172 #pragma GCC diagnostic pop
176 auto info =
new CallInfo{entry};
177 if(!info)
throw std::runtime_error(
"Failed to allocate call info");
181 auto &stackBuf = wrap->
stack;
182 auto stackFrame =
reinterpret_cast<std::byte *
>(stackBuf.data());
183 stackFrame += ((stackBuf.size()*
sizeof(uintptr_t)) & ~(0x10-1))
185 auto stack =
reinterpret_cast<uintptr_t *
>(stackFrame);
191 *--
stack =
reinterpret_cast<uintptr_t
>(info);
192 *--
stack =
reinterpret_cast<uintptr_t
>(&x86::DereferenceCallInfo);
193 *--
stack =
reinterpret_cast<uintptr_t
>(&x86::JumpToEntry);
202 wrap->stackTop =
stack;
213 return new x86(x86::gMainStack);
static Cothread * Current()
Architecture specific methods for working with cothreads on x86 systems.
static constexpr const size_t kDefaultStackSize
void switchTo(CothreadImpl *from) override
static const size_t kNumSavedRegisters
static constexpr const size_t kStackAlignment
x86(const Entry &entry, const size_t stackSize=0)
Implementation details (including architecture/platform specific code) for the library.
std::function< void(libcommunism::Cothread *)> gReturnHandler
Main namespace for the libcommunism library.
CothreadImpl * AllocKernelThreadWrapper()
Abstract interface for a platform implementation of cothreads.
std::span< uintptr_t > stack
Stack used by this cothread, if any.