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

Architecture specific methods for working with cothreads on amd64 based systems. More...

#include <Common.h>

Inheritance diagram for libcommunism::internal::Amd64:
libcommunism::CothreadImpl

Public Member Functions

 Amd64 (const Entry &entry, const size_t stackSize=0)
 
 Amd64 (const Entry &entry, std::span< uintptr_t > stack)
 
 Amd64 (std::span< uintptr_t > stack)
 
 ~Amd64 ()
 
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 {6}
 
static constexpr const size_t kMainStackSize {64}
 
static constexpr const size_t kStackAlignment {64}
 
static constexpr const size_t kDefaultStackSize {0x80000}
 

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 amd64 based systems.

Definition at line 16 of file Common.h.

Constructor & Destructor Documentation

◆ Amd64() [1/3]

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

Allocates an amd64 thread, allocating its stack.

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 32 of file Common.cpp.

32  : CothreadImpl(entry, stackSize) {
33  void *buf{nullptr};
34 
35  // round down stack size to ensure it's aligned before allocating it
36  auto allocSize = stackSize & ~(kStackAlignment - 1);
37  allocSize = allocSize ? allocSize : kDefaultStackSize;
38 
39  buf = AllocStack(allocSize);
40 
41  // create it as if we had provided the memory in the first place
42  this->stack = {reinterpret_cast<uintptr_t *>(buf), allocSize / sizeof(uintptr_t)};
43  this->ownsStack = true;
44 
45  Prepare(this, entry);
46 }
static constexpr const size_t kStackAlignment
Definition: Common.h:137
static constexpr const size_t kDefaultStackSize
Definition: Common.h:143
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

◆ Amd64() [2/3]

Amd64::Amd64 ( const Entry entry,
std::span< uintptr_t >  _stack 
)

Allocates and amd64 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 56 of file Common.cpp.

56  : CothreadImpl(entry, _stack) {
57  ValidateStackSize(_stack.size() * sizeof(uintptr_t));
58  Prepare(this, entry);
59 }

◆ Amd64() [3/3]

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

Definition at line 31 of file Common.h.

31 : CothreadImpl(stack) {}

◆ ~Amd64()

Amd64::~Amd64 ( )

Release the stack if we allocated it.

Definition at line 64 of file Common.cpp.

64  {
65  if(this->ownsStack) {
66  DeallocStack(this->stack.data());
67  }
68 }

Member Function Documentation

◆ switchTo()

void Amd64::switchTo ( CothreadImpl from)
overridevirtual

Performs a context switch to the provided cothread.

The state of the caller is stored on the stack of the currently active thread.

Implements libcommunism::CothreadImpl.

Definition at line 75 of file Common.cpp.

75  {
76  Switch(static_cast<Amd64 *>(from), this);
77 }
Architecture specific methods for working with cothreads on amd64 based systems.
Definition: Common.h:16

Friends And Related Function Documentation

◆ libcommunism::AllocKernelThreadWrapper

Member Data Documentation

◆ kDefaultStackSize

constexpr const size_t libcommunism::internal::Amd64::kDefaultStackSize {0x80000}
staticconstexpr

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

Definition at line 143 of file Common.h.

◆ kMainStackSize

constexpr const size_t libcommunism::internal::Amd64::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, as well as all of the SSE registers on Windows.

Definition at line 129 of file Common.h.

◆ kNumSavedRegisters

const size_t Amd64::kNumSavedRegisters {6}
static

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

For System V ABI, the only saved registers are rbp, rbx, and r12-r15.

On Windows, we have to save integer registers RBX, RBP, RDI, RSI, and R12-R15. In addition, XMM6-XMM15 must be saved. Since the SSE registers are 128 bits vs. 64 bits for an integer register, we just count them twice.

Definition at line 120 of file Common.h.

◆ kStackAlignment

constexpr const size_t libcommunism::internal::Amd64::kStackAlignment {64}
staticconstexpr

Requested alignment for stack allocations.

This is set to 64 bytes for cache line alignment. On amd64, the stack should always be at least 16 byte aligned (for SSE quantities).

Definition at line 137 of file Common.h.


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