libcommunism
Userspace cooperative threading library
Classes | Public Member Functions | Static Public Attributes | Friends | List of all members
libcommunism::internal::x86 Class Referencefinal

Architecture specific methods for working with cothreads on x86 systems. More...

#include <Common.h>

Inheritance diagram for libcommunism::internal::x86:
libcommunism::CothreadImpl

Public Member Functions

 x86 (const Entry &entry, const size_t stackSize=0)
 
 x86 (const Entry &entry, std::span< uintptr_t > stack)
 
 x86 (std::span< uintptr_t > stack)
 
 ~x86 ()
 
void switchTo (CothreadImpl *from) override
 
- Public Member Functions inherited from libcommunism::CothreadImpl
 CothreadImpl (const Cothread::Entry &entry, const size_t stackSize=0)
 
 CothreadImpl (const Cothread::Entry &entry, std::span< uintptr_t > stack)
 
 CothreadImpl (std::span< uintptr_t > stack)
 
virtual ~CothreadImpl ()=default
 
virtual size_t getStackSize () const
 
virtual void * getStack () const
 

Static Public Attributes

static const size_t kNumSavedRegisters {4}
 
static constexpr const size_t kMainStackSize {64}
 
static constexpr const size_t kStackAlignment {16}
 
static constexpr const size_t kDefaultStackSize {0x40000}
 

Friends

CothreadImpllibcommunism::AllocKernelThreadWrapper ()
 

Additional Inherited Members

- Public Types inherited from libcommunism::CothreadImpl
using Entry = Cothread::Entry
 
- Protected Attributes inherited from libcommunism::CothreadImpl
std::span< uintptr_t > stack
 Stack used by this cothread, if any. More...
 

Detailed Description

Architecture specific methods for working with cothreads on x86 systems.

This implementation exploits the fact that clang and GCC both support Microsoft's fastcall calling convention, so we can get away with one implementation for both System V and Windows platforms, albeit with differing assembly syntaxes.

In operation, this is identical to the Amd64 implementation; thread state is stored on the stack and the cothread's stackTop pointer actually points to the stack pointer of the cothread when it is switched out.

Definition at line 29 of file Common.h.

Constructor & Destructor Documentation

◆ x86() [1/3]

x86::x86 ( const Entry entry,
const size_t  stackSize = 0 
)

Allocate an x86 cothread instance, allocating the stack as part of this.

Parameters
entryMethod to execute on entry to this cothread
stackSizeSize of the stack to be allocated, in bytes. it should be a multiple of the machine word size, or specify zero to use the platform default.
Exceptions
std::runtime_errorIf the memory for the cothread could not be allocated.
std::runtime_errorIf the provided stack size is invalid

Definition at line 40 of file Common.cpp.

40  : CothreadImpl(entry, stackSize) {
41  void *buf{nullptr};
42 
43  // round down stack size to ensure it's aligned before allocating it
44  auto allocSize = stackSize & ~(kStackAlignment - 1);
45  allocSize = allocSize ? allocSize : kDefaultStackSize;
46 
47  buf = AllocStack(allocSize);
48 
49  // create it as if we had provided the memory in the first place
50  this->stack = {reinterpret_cast<uintptr_t *>(buf), allocSize / sizeof(uintptr_t)};
51  this->ownsStack = true;
52 
53  Prepare(this, entry);
54 }
static constexpr const size_t kDefaultStackSize
Definition: Common.h:103
static constexpr const size_t kStackAlignment
Definition: Common.h:97
CothreadImpl(const Cothread::Entry &entry, const size_t stackSize=0)
Definition: CothreadImpl.h:29
std::span< uintptr_t > stack
Stack used by this cothread, if any.
Definition: CothreadImpl.h:88

◆ x86() [2/3]

x86::x86 ( const Entry entry,
std::span< uintptr_t >  stack 
)

Allocates an x86 cothread with an already provided stack.

Parameters
entryMethod to execute on entry to this cothread
stackBuffer to use as the stack of the cothread
Exceptions
std::runtime_errorIf the provided stack is invalid

Definition at line 64 of file Common.cpp.

64  : CothreadImpl(entry, stack) {
65  x86::ValidateStackSize(stack.size() * sizeof(uintptr_t));
66  Prepare(this, entry);
67 }

◆ x86() [3/3]

libcommunism::internal::x86::x86 ( std::span< uintptr_t >  stack)
inline

Definition at line 44 of file Common.h.

44 : CothreadImpl(stack) {}

◆ ~x86()

x86::~x86 ( )

Deallocate the stack.

Definition at line 72 of file Common.cpp.

72  {
73  if(this->ownsStack) {
74  x86::DeallocStack(this->stack.data());
75  }
76 }

Member Function Documentation

◆ switchTo()

void x86::switchTo ( CothreadImpl from)
overridevirtual

Perform a context switch to this cothread.

The currently executing cothread's state is saved to its buffer, then this cothread's state is restored.

Implements libcommunism::CothreadImpl.

Definition at line 78 of file Common.cpp.

78  {
79  x86::Switch(static_cast<x86 *>(from), this);
80 }
Architecture specific methods for working with cothreads on x86 systems.
Definition: Common.h:29

Friends And Related Function Documentation

◆ libcommunism::AllocKernelThreadWrapper

Member Data Documentation

◆ kDefaultStackSize

constexpr const size_t libcommunism::internal::x86::kDefaultStackSize {0x40000}
staticconstexpr

Platform default size to use for the stack, in bytes, if no size is requested by the caller. We default to 256K.

Definition at line 103 of file Common.h.

◆ kMainStackSize

constexpr const size_t libcommunism::internal::x86::kMainStackSize {64}
staticconstexpr

Size of the stack buffer for the "fake" initial cothread, in machine words. This only needs to be large enough to fit the register stack frame. This must be a power of two.

It must be sufficiently large to store the callee-saved general purpose registers

Definition at line 90 of file Common.h.

◆ kNumSavedRegisters

const size_t libcommunism::internal::x86::kNumSavedRegisters {4}
static

Number of registers saved by the cothread swap code. This is used to correctly build the stack frames during initialization.

Definition at line 82 of file Common.h.

◆ kStackAlignment

constexpr const size_t libcommunism::internal::x86::kStackAlignment {16}
staticconstexpr

Requested alignment for stack allocations.

This is set to only 16 byte alignment as that's the most stringent of any x86 platform.

Definition at line 97 of file Common.h.


The documentation for this class was generated from the following files: