#include "coroutine.hpp" /*static*/ sprawl::threading::ThreadLocal<sprawl::threading::CoroutineBase*> sprawl::threading::CoroutineBase::ms_coroutineInitHelper; /*static*/ sprawl::threading::ThreadLocal<sprawl::threading::CoroutineBase> sprawl::threading::CoroutineBase::ms_thisThreadCoroutine; sprawl::threading::CoroutineBase::CoroutineBase() : m_holder(Holder<void>::Create()) , m_ownsHolder(true) { // NOP } sprawl::threading::CoroutineBase::CoroutineBase(sprawl::threading::CoroutineBase::Holder<void>* holder) : m_holder(holder) , m_ownsHolder(true) { if(m_holder && !ms_thisThreadCoroutine) { ms_thisThreadCoroutine = CoroutineBase(); } } sprawl::threading::CoroutineBase::CoroutineBase(CoroutineBase const& other) : m_holder(other.m_holder) , m_ownsHolder(true) { m_holder->IncRef(); } sprawl::threading::CoroutineBase& sprawl::threading::CoroutineBase::operator =(CoroutineBase const& other) { if(m_ownsHolder && m_holder && m_holder->DecRef()) { m_holder->Release(); } m_holder = other.m_holder; if(m_ownsHolder && m_holder) { m_holder->IncRef(); } return *this; } sprawl::threading::CoroutineBase::~CoroutineBase() { if(m_ownsHolder && m_holder && m_holder->DecRef()) { m_holder->Release(); } } sprawl::threading::CoroutineState sprawl::threading::CoroutineBase::State() { return m_holder ? m_holder->m_state : CoroutineState::Invalid; } void sprawl::threading::CoroutineBase::run_() { #if SPRAWL_EXCEPTIONS_ENABLED try { m_holder->RunFunction(); } catch(...) { m_holder->m_exception = std::current_exception(); } #else m_holder->RunFunction(); #endif m_holder->m_state = CoroutineState::Completed; m_holder->m_priorCoroutine.reactivate_(); } /*static*/ void sprawl::threading::CoroutineBase::entryPoint_() { ms_coroutineInitHelper->run_(); } void sprawl::threading::CoroutineBase::releaseRef_() { if(m_holder && m_ownsHolder) { m_holder->DecRef(); m_ownsHolder = false; } } size_t sprawl::threading::CoroutineBase::StackSize() { return m_holder->m_stackSize; } /*static*/ sprawl::threading::CoroutineBase sprawl::threading::CoroutineBase::GetCurrentCoroutine() { return *ms_thisThreadCoroutine; } sprawl::threading::CoroutineBase sprawl::threading::CoroutineBase::GetCallingCoroutine() { return m_holder->m_priorCoroutine; } sprawl::threading::CoroutineType sprawl::threading::CoroutineBase::Type() { return m_holder->Type(); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#2 | 18645 | brandon_m_bare | Integrated latest version of libsprawl. | ||
#1 | 15089 | brandon_m_bare | First integration of sprawl. | ||
//guest/ShadauxCat/Sprawl/Mainline/threading/coroutine.cpp | |||||
#3 | 14216 | ShadauxCat |
-Moved some global sprawl::Strings into local scope in json serialization test because of initialization order issues in the memory allocator on mac. This is a temporary fix, and a real fix will come by making the pool allocator work in explicitly-sized pieces and putting all the code for those pieces into a cpp file. -Fixed a large number of warnings on mac/linux that were exposed by fixes to csbuild -Fixed compile errors on mac due to malloc and alloca not being defined, fixed by #include <stdlib.h> in appropriate places -Fixed mac os x trying to link against pthread erroneously -Provided os x implementation of time library -Fixed compile errors on os x due to std::unordered_map whining about the difference between an allocator that allocates std::pair<key, value> and one that allocates std::pair<key const, value>, which, of course, is that the allocator will be no different at all. -Fixed an actual issue where one unordered_map was allocating only key_type instead of std::pair<key_type, value_type> -Fixed a memory leak where coroutine objects would never be cleaned up because either Yield() or reactivate_() will never return (and thus never clean up their stack memory and thus never release any dynamic memory held in stack objects) depending on the situation - if the function runs to completion, reactivate_() never returns after calling swapcontext(); meanwhile, if the function does not run to completion, Yield() never returns after calling Pause(). This behavior will need to be well-documented because it will affect client-side code as well. Stack memory within a coroutine should not rely on RAII behavior. -Fixed compile failure when creating a StlWrapper with a const value_type #review-14217 |
||
#2 | 14115 | ShadauxCat |
Add missing copy/move/assignment/destructor for BitVector, variadic constructor for Coroutine #review-14116 |
||
#1 | 13650 | ShadauxCat |
- Windows implementations of thread and time libraries - Added coroutines - Added some more unit tests, fixed some unit tests in windows environments - Fixed an issue where multi threading was not properly detected on Linux - Fixed the makefiles to build with threading by default on linux - Changed the pool allocator to use thread-local pools instead of locking mutexes - Fixed output of sprawl::string in the StringBuilder library to take length into account - Added string builder options for StringLiteral - Added thread local implementation #review |