Browse Source

彻底删除inline state功能。

多次实践证明,该功能带来的误用比其节省的内存更可怕。
master
tearshark 6 months ago
parent
commit
52c11affc4

+ 0
- 15
CMakeLists.txt View File

endif() 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_DEBUG_COUNTER "Debug objects count" OFF)
option(LIBRF_KEEP_REAL_SIZE "Keep real size in queue" OFF) option(LIBRF_KEEP_REAL_SIZE "Keep real size in queue" OFF)
option(LIBRF_DISABLE_MULT_THREAD "Disable multi-threaded scheduler" OFF) option(LIBRF_DISABLE_MULT_THREAD "Disable multi-threaded scheduler" OFF)
#set(RESUMEF_USE_CUSTOM_SPINLOCK "std::mutex") #set(RESUMEF_USE_CUSTOM_SPINLOCK "std::mutex")
if(LIBRF_INLINE_STATE)
set(RESUMEF_INLINE_STATE 1)
endif()
if(LIBRF_DEBUG_COUNTER) if(LIBRF_DEBUG_COUNTER)
set(RESUMEF_DEBUG_COUNTER 1) set(RESUMEF_DEBUG_COUNTER 1)
endif() endif()

+ 1
- 1
benchmark/benchmark_async_mem.cpp View File

#include "librf/librf.h" #include "librf/librf.h"
const size_t N = 5000000;
const size_t N = 10'000'000;
const size_t LOOP_COUNT = 50; const size_t LOOP_COUNT = 50;
std::atomic<size_t> globalValue{0}; std::atomic<size_t> globalValue{0};

+ 0
- 8
config.h.in View File

#pragma once #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 #ifndef RESUMEF_DEBUG_COUNTER
#cmakedefine RESUMEF_DEBUG_COUNTER @RESUMEF_DEBUG_COUNTER@ #cmakedefine RESUMEF_DEBUG_COUNTER @RESUMEF_DEBUG_COUNTER@
#endif //RESUMEF_DEBUG_COUNTER #endif //RESUMEF_DEBUG_COUNTER

+ 0
- 8
include/librf/src/config.h View File

#pragma once #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 #ifndef RESUMEF_DEBUG_COUNTER
/* #undef RESUMEF_DEBUG_COUNTER */ /* #undef RESUMEF_DEBUG_COUNTER */
#endif //RESUMEF_DEBUG_COUNTER #endif //RESUMEF_DEBUG_COUNTER

+ 1
- 1
include/librf/src/counted_ptr.h View File

namespace librf namespace librf
{ {
/** /**
* @brief 专用state的智能计数指针,通过管理state内嵌的引用计数来管理state的生存期。
* @brief 专用state的智能计数指针,通过管理state内嵌的引用计数来管理state的生存期。
*/ */
template <typename T> template <typename T>
struct counted_ptr struct counted_ptr

+ 3
- 3
include/librf/src/def.h View File

template<class _Ty> template<class _Ty>
constexpr size_t _Align_size() 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 : return std::is_empty_v<_Ty> ? 0 :
(sizeof(_Ty) + _ALIGN_REQ - 1) & ~(_ALIGN_REQ - 1); (sizeof(_Ty) + _ALIGN_REQ - 1) & ~(_ALIGN_REQ - 1);
} }
template<class _Callable> template<class _Callable>
auto make_stop_callback(const stop_token& token, _Callable&& cb) ->std::unique_ptr<stop_callback<_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> template<class _Callable>
auto make_stop_callback(stop_token&& token, _Callable&& cb) ->std::unique_ptr<stop_callback<_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));
} }
} }



+ 5
- 5
include/librf/src/exception.inl View File

none, none,
not_ready, ///< get_value called when value not available not_ready, ///< get_value called when value not available
already_acquired, ///< attempt to get another future 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, ///< 定时器被意外取消 timer_canceled, ///< 定时器被意外取消
not_await_lock, ///< 没有在协程中使用co_await等待lock结果
stop_requested, ///< stop_source触发了
not_await_lock, ///< 没有在协程中使用 co_await 等待 lock 结果
stop_requested, ///< stop_source 触发了


max__ max__
}; };
}; };


/** /**
* @brief 错误使用channel_t时产生的异常(v2版本已经不再抛此异常了)。
* @brief 错误使用channel_t时产生的异常(v2.0版本以后已经不再抛此异常了)。
*/ */
struct channel_exception : std::logic_error struct channel_exception : std::logic_error
{ {

+ 0
- 48
include/librf/src/generator.h View File



state_type* get_state() noexcept 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(); return _state.get();
#endif
} }
//counted_ptr<state_type> ref_state() noexcept //counted_ptr<state_type> ref_state() noexcept
//{ //{
void* operator new(size_t _Size) void* operator new(size_t _Size)
{ {
_Alloc_char _Al; _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); char* ptr = _Al.allocate(_Size);
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
std::cout << " generator_promise::new, alloc size=" << _Size << std::endl; std::cout << " generator_promise::new, alloc size=" << _Size << std::endl;
#endif #endif


return ptr; return ptr;
#endif
} }


void operator delete(void* _Ptr, size_t _Size) 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; _Alloc_char _Al;
return _Al.deallocate(reinterpret_cast<char *>(_Ptr), _Size); return _Al.deallocate(reinterpret_cast<char *>(_Ptr), _Size);
#endif
} }
#if !RESUMEF_INLINE_STATE
private: private:
counted_ptr<state_type> _state = state_generator_t::_Alloc_state(); counted_ptr<state_type> _state = state_generator_t::_Alloc_state();
#endif
}; };
#endif //DOXYGEN_SKIP_PROPERTY #endif //DOXYGEN_SKIP_PROPERTY



+ 0
- 2
include/librf/src/promise.h View File

using _Alloc_char = std::allocator<char>; using _Alloc_char = std::allocator<char>;
void* operator new(size_t _Size); void* operator new(size_t _Size);
void operator delete(void* _Ptr, size_t _Size); void operator delete(void* _Ptr, size_t _Size);
#if !RESUMEF_INLINE_STATE
private: private:
counted_ptr<state_type> _state = state_future_t::_Alloc_state<state_type>(false); counted_ptr<state_type> _state = state_future_t::_Alloc_state<state_type>(false);
#endif
}; };


template<class _Ty> template<class _Ty>

+ 0
- 51
include/librf/src/promise.inl View File

template <typename _Ty> template <typename _Ty>
auto promise_impl_t<_Ty>::get_state() noexcept -> state_type* 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(); return _state.get();
#endif
} }


// 如果去掉了调度器,则ref_state()实现为返回counted_ptr<>,以便于处理一些意外情况 // 如果去掉了调度器,则ref_state()实现为返回counted_ptr<>,以便于处理一些意外情况
void* promise_impl_t<_Ty>::operator new(size_t _Size) void* promise_impl_t<_Ty>::operator new(size_t _Size)
{ {
_Alloc_char _Al; _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); char* ptr = _Al.allocate(_Size);
#if RESUMEF_DEBUG_COUNTER #if RESUMEF_DEBUG_COUNTER
std::cout << " future_promise::new, alloc size=" << (_Size) << std::endl; std::cout << " future_promise::new, alloc size=" << (_Size) << std::endl;
std::cout << " future_promise::new, return ptr=" << (void*)ptr << std::endl; std::cout << " future_promise::new, return ptr=" << (void*)ptr << std::endl;
#endif #endif
return ptr; return ptr;
#endif
} }


template <typename _Ty> template <typename _Ty>
void promise_impl_t<_Ty>::operator delete(void* _Ptr, size_t _Size) 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; _Alloc_char _Al;
return _Al.deallocate(reinterpret_cast<char*>(_Ptr), _Size); return _Al.deallocate(reinterpret_cast<char*>(_Ptr), _Size);
#endif
} }
} }



+ 0
- 16
include/librf/src/state.h View File

_coro = handler; _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(); LIBRF_API static state_generator_t* _Alloc_state();
}; };


template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>) template<class _PromiseT> requires(traits::is_promise_v<_PromiseT>)
void promise_final_suspend(coroutine_handle<_PromiseT> handler); 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> template<class _Sty>
static inline _Sty* _Alloc_state(bool awaitor) static inline _Sty* _Alloc_state(bool awaitor)
{ {

+ 5
- 5
include/librf/src/type_concept.inl View File



namespace librf 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> template<typename T>
concept _AwaitorT = requires(T&& v) 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() }; { 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> template<typename T>

+ 1
- 1
source/scheduler.cpp View File

"stop_requested", "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) LIBRF_API const char * get_error_string(error_code fe, const char * classname)
{ {

+ 0
- 4
source/state.cpp View File

LIBRF_API void state_generator_t::destroy_deallocate() LIBRF_API void state_generator_t::destroy_deallocate()
{ {
size_t _Size = _Align_size<state_generator_t>(); 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 #if RESUMEF_DEBUG_COUNTER
std::cout << "destroy_deallocate, size=" << _Size << std::endl; std::cout << "destroy_deallocate, size=" << _Size << std::endl;
#endif #endif

Loading…
Cancel
Save