libcommunism
Userspace cooperative threading library
Cothread.cpp
Go to the documentation of this file.
2 
3 #include "AllocImpl.h"
4 #include "CothreadImpl.h"
5 #include "CothreadPrivate.h"
6 
7 #include <exception>
8 #include <iomanip>
9 #include <iostream>
10 
61 namespace libcommunism::internal {
62 static void DefaultCothreadReturnedHandler(Cothread *);
63 }
64 
65 using namespace libcommunism;
66 using namespace libcommunism::internal;
67 
72 std::function<void(Cothread *)> internal::gReturnHandler{DefaultCothreadReturnedHandler};
73 
77 thread_local Cothread *Cothread::gCurrent{nullptr};
78 
79 
80 
84 static void libcommunism::internal::DefaultCothreadReturnedHandler(Cothread *thread) {
85  std::cerr << "[libcommunism] Cothread $" << std::hex << thread << std::dec;
86  if(thread) {
87  const auto &label = thread->getLabel();
88  if(!label.empty()) {
89  std::cerr << " (" << thread->getLabel() << ")";
90  } else {
91  std::cerr << " (unnamed cothread)";
92  }
93  }
94 
95  std::cerr << " returned from entry point!" << std::endl;
96  std::terminate();
97 }
98 
99 Cothread::Cothread(const Entry &entry, const size_t stackSize) {
100  this->impl = AllocImpl(this->implBuffer, this->implBufferUsed, entry, stackSize);
101 }
102 
103 Cothread::Cothread(const Entry &entry, std::span<uintptr_t> stack) {
104  this->impl = AllocImpl(this->implBuffer, this->implBufferUsed, entry, stack);
105 }
106 
107 
109  if(this->implBufferUsed) {
110  reinterpret_cast<CothreadImpl *>(this->implBuffer.data())->~CothreadImpl();
111  } else {
112  delete this->impl;
113  }
114  this->impl = nullptr;
115 }
116 
118  if(!gCurrent) {
119  auto impl = AllocKernelThreadWrapper();
120  if(!impl) {
121  std::cerr << "failed to allocate kernel cothread wrapper!" << std::endl;
122  std::terminate();
123  }
124 
125  gCurrent = new Cothread(impl);
126  }
127  return gCurrent;
128 }
129 
130 void Cothread::SetReturnHandler(const std::function<void (Cothread *)> &handler) {
131  gReturnHandler = handler;
132 }
133 
135  gReturnHandler = DefaultCothreadReturnedHandler;
136 }
137 
139  auto from = Current()->impl;
140  gCurrent = this;
141  this->impl->switchTo(from);
142 }
143 
144 void *Cothread::getStack() const {
145  return this->impl->getStack();
146 }
147 
148 size_t Cothread::getStackSize() const {
149  return this->impl->getStackSize();
150 }
Instance of a single cooperative thread.
Definition: Cothread.h:24
static void SetReturnHandler(const std::function< void(Cothread *)> &handler)
Definition: Cothread.cpp:130
Cothread(const Entry &entry, const size_t stackSize=0)
Definition: Cothread.cpp:99
std::function< void()> Entry
Type alias for an entry point of a cothread.
Definition: Cothread.h:27
static Cothread * Current()
Definition: Cothread.cpp:117
size_t getStackSize() const
Definition: Cothread.cpp:148
constexpr auto & getLabel() const
Definition: Cothread.h:139
static void ResetReturnHandler()
Definition: Cothread.cpp:134
void * getStack() const
Definition: Cothread.cpp:144
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