@@ -51,18 +51,6 @@ elseif ("${LIBRF_COMPILER_SETTING}" STREQUAL "gcc") | |||
endif() | |||
if(${LIBRF_COMPILER_SETTING} STREQUAL "msvc") | |||
option(LIBRF_INLINE_STATE "Enable Inline state" ON) | |||
elseif ("${LIBRF_COMPILER_SETTING}" STREQUAL "clang_on_msvc") | |||
option(LIBRF_INLINE_STATE "Enable Inline state" ON) | |||
elseif(${LIBRF_COMPILER_SETTING} STREQUAL "clang") | |||
option(LIBRF_INLINE_STATE "Enable Inline state" ON) | |||
elseif(${LIBRF_COMPILER_SETTING} STREQUAL "gcc") | |||
option(LIBRF_INLINE_STATE "Enable Inline state" OFF) | |||
else() | |||
option(LIBRF_INLINE_STATE "Enable Inline state" OFF) | |||
endif() | |||
option(LIBRF_DEBUG_COUNTER "Debug objects count" OFF) | |||
option(LIBRF_KEEP_REAL_SIZE "Keep real size in queue" OFF) | |||
option(LIBRF_DISABLE_MULT_THREAD "Disable multi-threaded scheduler" OFF) | |||
@@ -97,9 +85,6 @@ message(STATUS "C++ flags: ${CMAKE_CXX_FLAGS}") | |||
#set(RESUMEF_USE_CUSTOM_SPINLOCK "std::mutex") | |||
if(LIBRF_INLINE_STATE) | |||
set(RESUMEF_INLINE_STATE 1) | |||
endif() | |||
if(LIBRF_DEBUG_COUNTER) | |||
set(RESUMEF_DEBUG_COUNTER 1) | |||
endif() |
@@ -6,7 +6,7 @@ | |||
#include "librf/librf.h" | |||
const size_t N = 5000000; | |||
const size_t N = 10'000'000; | |||
const size_t LOOP_COUNT = 50; | |||
std::atomic<size_t> globalValue{0}; |
@@ -1,13 +1,5 @@ | |||
#pragma once | |||
#ifndef RESUMEF_INLINE_STATE | |||
#if defined(__clang__) || defined(_MSC_VER) | |||
#cmakedefine RESUMEF_INLINE_STATE @RESUMEF_INLINE_STATE@ | |||
#else | |||
#cmakedefine RESUMEF_INLINE_STATE 0 | |||
#endif //defined(__clang__) || defined(_MSC_VER) | |||
#endif //RESUMEF_INLINE_STATE | |||
#ifndef RESUMEF_DEBUG_COUNTER | |||
#cmakedefine RESUMEF_DEBUG_COUNTER @RESUMEF_DEBUG_COUNTER@ | |||
#endif //RESUMEF_DEBUG_COUNTER |
@@ -1,13 +1,5 @@ | |||
#pragma once | |||
#ifndef RESUMEF_INLINE_STATE | |||
#if defined(__clang__) || defined(_MSC_VER) | |||
#define RESUMEF_INLINE_STATE 1 | |||
#else | |||
#define RESUMEF_INLINE_STATE 0 | |||
#endif //defined(__clang__) || defined(_MSC_VER) | |||
#endif //RESUMEF_INLINE_STATE | |||
#ifndef RESUMEF_DEBUG_COUNTER | |||
/* #undef RESUMEF_DEBUG_COUNTER */ | |||
#endif //RESUMEF_DEBUG_COUNTER |
@@ -3,7 +3,7 @@ | |||
namespace librf | |||
{ | |||
/** | |||
* @brief 专用与state的智能计数指针,通过管理state内嵌的引用计数来管理state的生存期。 | |||
* @brief 专用于state的智能计数指针,通过管理state内嵌的引用计数来管理state的生存期。 | |||
*/ | |||
template <typename T> | |||
struct counted_ptr |
@@ -79,7 +79,7 @@ namespace librf | |||
template<class _Ty> | |||
constexpr size_t _Align_size() | |||
{ | |||
const size_t _ALIGN_REQ = sizeof(void*) * 2; | |||
constexpr size_t _ALIGN_REQ = sizeof(void*) * 2; | |||
return std::is_empty_v<_Ty> ? 0 : | |||
(sizeof(_Ty) + _ALIGN_REQ - 1) & ~(_ALIGN_REQ - 1); | |||
} | |||
@@ -87,12 +87,12 @@ namespace librf | |||
template<class _Callable> | |||
auto make_stop_callback(const stop_token& token, _Callable&& cb) ->std::unique_ptr<stop_callback<_Callable>> | |||
{ | |||
return std::make_unique<stop_callback<_Callable>>(token, cb); | |||
return std::make_unique<stop_callback<_Callable>>(token, std::forward<_Callable>(cb)); | |||
} | |||
template<class _Callable> | |||
auto make_stop_callback(stop_token&& token, _Callable&& cb) ->std::unique_ptr<stop_callback<_Callable>> | |||
{ | |||
return std::make_unique<stop_callback<_Callable>>(std::move(token), cb); | |||
return std::make_unique<stop_callback<_Callable>>(std::move(token), std::forward<_Callable>(cb)); | |||
} | |||
} | |||
@@ -11,11 +11,11 @@ namespace librf | |||
none, | |||
not_ready, ///< get_value called when value not available | |||
already_acquired, ///< attempt to get another future | |||
unlock_more, ///< unlock 次数多余lock次数 | |||
read_before_write, ///< 0容量的channel,先读后写 | |||
unlock_more, ///< unlock 次数多于 lock 次数 | |||
read_before_write, ///< 0容量的 channel,先读后写 | |||
timer_canceled, ///< 定时器被意外取消 | |||
not_await_lock, ///< 没有在协程中使用co_await等待lock结果 | |||
stop_requested, ///< stop_source触发了 | |||
not_await_lock, ///< 没有在协程中使用 co_await 等待 lock 结果 | |||
stop_requested, ///< stop_source 触发了 | |||
max__ | |||
}; | |||
@@ -52,7 +52,7 @@ namespace librf | |||
}; | |||
/** | |||
* @brief 错误使用channel_t时产生的异常(v2版本已经不再抛此异常了)。 | |||
* @brief 错误使用channel_t时产生的异常(v2.0版本以后已经不再抛此异常了)。 | |||
*/ | |||
struct channel_exception : std::logic_error | |||
{ |
@@ -179,22 +179,7 @@ namespace librf | |||
state_type* get_state() noexcept | |||
{ | |||
#if RESUMEF_INLINE_STATE | |||
size_t _State_size = _Align_size<state_type>(); | |||
#if defined(__clang__) | |||
auto h = coroutine_handle<promise_type>::from_promise(*this); | |||
char* ptr = reinterpret_cast<char*>(h.address()) - _State_size; | |||
return reinterpret_cast<state_type*>(ptr); | |||
#elif defined(_MSC_VER) | |||
auto h = coroutine_handle<promise_type>::from_promise(*this); | |||
char* ptr = reinterpret_cast<char*>(h.address()) - _State_size; | |||
return reinterpret_cast<state_type*>(ptr); | |||
#else | |||
#error "Unknown compiler" | |||
#endif | |||
#else | |||
return _state.get(); | |||
#endif | |||
} | |||
//counted_ptr<state_type> ref_state() noexcept | |||
//{ | |||
@@ -214,26 +199,6 @@ namespace librf | |||
void* operator new(size_t _Size) | |||
{ | |||
_Alloc_char _Al; | |||
#if RESUMEF_INLINE_STATE | |||
size_t _State_size = _Align_size<state_type>(); | |||
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); | |||
char* ptr = _Al.allocate(_Size + _State_size); | |||
char* _Rptr = ptr + _State_size; | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << " generator_promise::new, alloc size=" << (_Size + _State_size) << ", state size=" << _State_size << std::endl; | |||
std::cout << " generator_promise::new, alloc ptr=" << (void*)ptr << std::endl; | |||
std::cout << " generator_promise::new, return ptr=" << (void*)_Rptr << std::endl; | |||
#endif | |||
//在初始地址上构造state | |||
{ | |||
state_type* st = state_type::_Construct(ptr); | |||
st->lock(); | |||
} | |||
return _Rptr; | |||
#else | |||
char* ptr = _Al.allocate(_Size); | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << " generator_promise::new, alloc size=" << _Size << std::endl; | |||
@@ -242,28 +207,15 @@ namespace librf | |||
#endif | |||
return ptr; | |||
#endif | |||
} | |||
void operator delete(void* _Ptr, size_t _Size) | |||
{ | |||
#if RESUMEF_INLINE_STATE | |||
size_t _State_size = _Align_size<state_type>(); | |||
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); | |||
*reinterpret_cast<uint32_t*>(_Ptr) = static_cast<uint32_t>(_Size + _State_size); | |||
state_type* st = reinterpret_cast<state_type*>(static_cast<char*>(_Ptr) - _State_size); | |||
st->unlock(); | |||
#else | |||
_Alloc_char _Al; | |||
return _Al.deallocate(reinterpret_cast<char *>(_Ptr), _Size); | |||
#endif | |||
} | |||
#if !RESUMEF_INLINE_STATE | |||
private: | |||
counted_ptr<state_type> _state = state_generator_t::_Alloc_state(); | |||
#endif | |||
}; | |||
#endif //DOXYGEN_SKIP_PROPERTY | |||
@@ -107,10 +107,8 @@ namespace librf | |||
using _Alloc_char = std::allocator<char>; | |||
void* operator new(size_t _Size); | |||
void operator delete(void* _Ptr, size_t _Size); | |||
#if !RESUMEF_INLINE_STATE | |||
private: | |||
counted_ptr<state_type> _state = state_future_t::_Alloc_state<state_type>(false); | |||
#endif | |||
}; | |||
template<class _Ty> |
@@ -19,24 +19,7 @@ namespace librf | |||
template <typename _Ty> | |||
auto promise_impl_t<_Ty>::get_state() noexcept -> state_type* | |||
{ | |||
#if RESUMEF_INLINE_STATE | |||
size_t _State_size = _Align_size<state_type>(); | |||
#if defined(__clang__) | |||
auto h = coroutine_handle<promise_type>::from_promise(*reinterpret_cast<promise_type *>(this)); | |||
char* ptr = reinterpret_cast<char*>(h.address()) - _State_size; | |||
return reinterpret_cast<state_type*>(ptr); | |||
#elif defined(_MSC_VER) | |||
auto h = coroutine_handle<promise_type>::from_promise(*reinterpret_cast<promise_type*>(this)); | |||
char* ptr = reinterpret_cast<char*>(h.address()) - _State_size; | |||
return reinterpret_cast<state_type*>(ptr); | |||
//char* ptr = reinterpret_cast<char*>(this) - _State_size; | |||
//return reinterpret_cast<state_type*>(ptr); | |||
#else | |||
#error "Unknown compiler" | |||
#endif | |||
#else | |||
return _state.get(); | |||
#endif | |||
} | |||
// 如果去掉了调度器,则ref_state()实现为返回counted_ptr<>,以便于处理一些意外情况 | |||
@@ -55,30 +38,6 @@ namespace librf | |||
void* promise_impl_t<_Ty>::operator new(size_t _Size) | |||
{ | |||
_Alloc_char _Al; | |||
#if RESUMEF_INLINE_STATE | |||
size_t _State_size = _Align_size<state_type>(); | |||
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); | |||
//If allocation fails, the coroutine throws std::bad_alloc, | |||
//unless the Promise type defines the member function Promise::get_return_object_on_allocation_failure(). | |||
//If that member function is defined, allocation uses the nothrow form of operator new and on allocation failure, | |||
//the coroutine immediately returns the object obtained from Promise::get_return_object_on_allocation_failure() to the caller. | |||
char* ptr = _Al.allocate(_Size + _State_size); | |||
char* _Rptr = ptr + _State_size; | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << " future_promise::new, alloc size=" << (_Size + _State_size) << std::endl; | |||
std::cout << " future_promise::new, alloc ptr=" << (void*)ptr << std::endl; | |||
std::cout << " future_promise::new, return ptr=" << (void*)_Rptr << std::endl; | |||
#endif | |||
//在初始地址上构造state | |||
{ | |||
state_type* st = state_future_t::_Construct<state_type>(ptr, _Size + _State_size); | |||
st->lock(); | |||
} | |||
return _Rptr; | |||
#else | |||
char* ptr = _Al.allocate(_Size); | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << " future_promise::new, alloc size=" << (_Size) << std::endl; | |||
@@ -86,23 +45,13 @@ namespace librf | |||
std::cout << " future_promise::new, return ptr=" << (void*)ptr << std::endl; | |||
#endif | |||
return ptr; | |||
#endif | |||
} | |||
template <typename _Ty> | |||
void promise_impl_t<_Ty>::operator delete(void* _Ptr, size_t _Size) | |||
{ | |||
#if RESUMEF_INLINE_STATE | |||
(void)_Size; | |||
size_t _State_size = _Align_size<state_type>(); | |||
assert(_Size >= sizeof(uint32_t) && _Size < (std::numeric_limits<uint32_t>::max)() - sizeof(_State_size)); | |||
state_type* st = reinterpret_cast<state_type*>(static_cast<char*>(_Ptr) - _State_size); | |||
st->unlock(); | |||
#else | |||
_Alloc_char _Al; | |||
return _Al.deallocate(reinterpret_cast<char*>(_Ptr), _Size); | |||
#endif | |||
} | |||
} | |||
@@ -83,12 +83,6 @@ namespace librf | |||
_coro = handler; | |||
} | |||
#if RESUMEF_INLINE_STATE | |||
static state_generator_t* _Construct(void* _Ptr) | |||
{ | |||
return new(_Ptr) state_generator_t(); | |||
} | |||
#endif | |||
LIBRF_API static state_generator_t* _Alloc_state(); | |||
}; | |||
@@ -185,16 +179,6 @@ namespace librf | |||
template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) | |||
void promise_final_suspend(coroutine_handle<_PromiseT> handler); | |||
#if RESUMEF_INLINE_STATE | |||
template<class _Sty> | |||
static _Sty* _Construct(void* _Ptr, size_t _Size) | |||
{ | |||
_Sty* st = new(_Ptr) _Sty(false); | |||
st->_alloc_size = static_cast<uint32_t>(_Size); | |||
return st; | |||
} | |||
#endif | |||
template<class _Sty> | |||
static inline _Sty* _Alloc_state(bool awaitor) | |||
{ |
@@ -4,15 +4,15 @@ | |||
namespace librf | |||
{ | |||
template<typename T> | |||
concept _ValidAwaitSuspendReturnT = std::same_as<T, void> || std::same_as<T, bool> || traits::is_coroutine_handle_v<T>; | |||
template<typename T> | |||
concept _AwaitorT = requires(T&& v) | |||
{ | |||
{ v.await_ready() } ->std::same_as<bool>; | |||
{ v.await_suspend(std::declval<std::coroutine_handle<promise_t<>>>()) }; | |||
{ v.await_ready() } -> std::same_as<bool>; | |||
{ v.await_suspend(std::declval<std::coroutine_handle<promise_t<>>>()) } -> _ValidAwaitSuspendReturnT; | |||
{ v.await_resume() }; | |||
requires traits::is_valid_await_suspend_return_v< | |||
decltype(v.await_suspend(std::declval<std::coroutine_handle<promise_t<>>>())) | |||
>; | |||
}; | |||
template<typename T> |
@@ -22,7 +22,7 @@ namespace librf | |||
"stop_requested", | |||
}; | |||
char sz_future_error_buffer[256]; | |||
thread_local char sz_future_error_buffer[256]; | |||
LIBRF_API const char * get_error_string(error_code fe, const char * classname) | |||
{ |
@@ -58,10 +58,6 @@ namespace librf | |||
LIBRF_API void state_generator_t::destroy_deallocate() | |||
{ | |||
size_t _Size = _Align_size<state_generator_t>(); | |||
#if RESUMEF_INLINE_STATE | |||
char* _Ptr = reinterpret_cast<char*>(this) + _Size; | |||
_Size = *reinterpret_cast<uint32_t*>(_Ptr); | |||
#endif | |||
#if RESUMEF_DEBUG_COUNTER | |||
std::cout << "destroy_deallocate, size=" << _Size << std::endl; | |||
#endif |