libcommunism
Userspace cooperative threading library
Common.cpp
Go to the documentation of this file.
1 
4 #include "Common.h"
5 #include "CothreadPrivate.h"
6 
7 #include <algorithm>
8 #include <array>
9 #include <cstddef>
10 #include <exception>
11 #include <functional>
12 #include <memory>
13 #include <stdexcept>
14 #include <thread>
15 
16 using namespace libcommunism;
17 using namespace libcommunism::internal;
18 
19 thread_local std::array<uintptr_t, Aarch64::kMainStackSize> Aarch64::gMainStack;
20 
21 
22 
33 Aarch64::Aarch64(const Entry &entry, const size_t stackSize) : CothreadImpl(entry, stackSize) {
34  void *buf{nullptr};
35 
36  // round down stack size to ensure it's aligned before allocating it
37  auto allocSize = stackSize & ~(Aarch64::kStackAlignment - 1);
38  allocSize = allocSize ? allocSize : Aarch64::kDefaultStackSize;
39  allocSize += Aarch64::kContextSaveAreaSize;
40 
41  buf = Aarch64::AllocStack(allocSize);
42 
43  // create it as if we had provided the memory in the first place
44  this->stack = {reinterpret_cast<uintptr_t *>(buf), allocSize / sizeof(uintptr_t)};
45  this->ownsStack = true;
46 
47  Aarch64::Prepare(this, entry);
48 }
49 
58 Aarch64::Aarch64(const Entry &entry, std::span<uintptr_t> _stack) : CothreadImpl(entry, _stack) {
59  Aarch64::ValidateStackSize(_stack.size() * sizeof(uintptr_t));
60  Aarch64::Prepare(this, entry);
61 }
62 
67 Aarch64::Aarch64(std::span<uintptr_t> stack) : CothreadImpl(stack), stackTop(stack.data()) {
68 }
69 
70 
75  if(this->ownsStack) {
76  DeallocStack(this->stack.data());
77  }
78 }
79 
86  Switch(static_cast<Aarch64 *>(from), this);
87 }
88 
96 void Aarch64::ValidateStackSize(const size_t size) {
97  if(!size) throw std::runtime_error("Size may not be nil");
98  if(size % kStackAlignment) throw std::runtime_error("Stack is misaligned");
99 }
100 
105 void Aarch64::CothreadReturned() {
107 }
108 
115 void Aarch64::DereferenceCallInfo(CallInfo *info) {
116  info->entry();
117  delete info;
118 
119  CothreadReturned();
121 
122  // if the return handler returns, we will crash. so abort to make debugging easier
123  std::terminate();
124 }
125 
126 
127 
135  return new Aarch64(Aarch64::gMainStack);
136 }
137 
static Cothread * Current()
Definition: Cothread.cpp:117
Architecture specific methods for working with cothreads on 64 bit ARM machines.
Definition: Common.h:18
static constexpr const size_t kDefaultStackSize
Definition: Common.h:86
static constexpr const size_t kStackAlignment
Definition: Common.h:80
static constexpr const size_t kContextSaveAreaSize
Definition: Common.h:69
Aarch64(const Entry &entry, const size_t stackSize=0)
Definition: Common.cpp:33
void switchTo(CothreadImpl *from) override
Definition: Common.cpp:85
Implementation details (including architecture/platform specific code) for the library.
Definition: Common.h:11
std::function< void(libcommunism::Cothread *)> gReturnHandler
Definition: Cothread.cpp:72
Main namespace for the libcommunism library.
Definition: Common.h:11
CothreadImpl * AllocKernelThreadWrapper()
Definition: Common.cpp:134
Abstract interface for a platform implementation of cothreads.
Definition: CothreadImpl.h:18
std::span< uintptr_t > stack
Stack used by this cothread, if any.
Definition: CothreadImpl.h:88