mirror of
https://github.com/tearshark/librf.git
synced 2024-10-01 15:57:07 +08:00
Merge branch 'master' of https://github.com/tearshark/librf
# Conflicts: # CMakeLists.txt # librf/src/config.h
This commit is contained in:
commit
02a69b586d
@ -8,7 +8,7 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
|||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
set(CMAKE_CXX_FLAGS "/std:c++latest /await /EHsc")
|
set(CMAKE_CXX_FLAGS "/std:c++latest /await /EHsc")
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++2a -fcoroutines")
|
set(CMAKE_CXX_FLAGS "-std=c++2a -fcoroutines -pthread")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "C++ flags: ${CMAKE_CXX_FLAGS}")
|
message(STATUS "C++ flags: ${CMAKE_CXX_FLAGS}")
|
||||||
@ -26,7 +26,7 @@ endif()
|
|||||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
option(OPT_USE_CONCEPT "Use conecpt instead of enable_if" ON)
|
option(OPT_USE_CONCEPT "Use conecpt instead of enable_if" ON)
|
||||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||||
option(OPT_USE_CONCEPT "Use conecpt instead of enable_if" ON)
|
option(OPT_USE_CONCEPT "Use conecpt instead of enable_if" OFF)
|
||||||
else()
|
else()
|
||||||
option(OPT_USE_CONCEPT "Use conecpt instead of enable_if" OFF)
|
option(OPT_USE_CONCEPT "Use conecpt instead of enable_if" OFF)
|
||||||
endif()
|
endif()
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
const size_t N = 2000000;
|
const size_t N = 2000000;
|
||||||
const size_t LOOP_COUNT = 50;
|
const size_t LOOP_COUNT = 50;
|
||||||
|
|
||||||
volatile size_t globalValue = 0;
|
std::atomic<size_t> globalValue{0};
|
||||||
|
|
||||||
void resumable_main_benchmark_mem(bool wait_key)
|
void resumable_main_benchmark_mem(bool wait_key)
|
||||||
{
|
{
|
||||||
|
@ -26,6 +26,20 @@ static future_t<> passing_next(channel_t<intptr_t> rd, channel_t<intptr_t> wr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static future_t<> passing_loop_all(channel_t<intptr_t> head, channel_t<intptr_t> tail)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < LoopCount; ++i)
|
||||||
|
{
|
||||||
|
auto tstart = high_resolution_clock::now();
|
||||||
|
|
||||||
|
co_await(head << 0);
|
||||||
|
intptr_t value = co_await tail;
|
||||||
|
|
||||||
|
auto dt = duration_cast<duration<double>>(high_resolution_clock::now() - tstart).count();
|
||||||
|
std::cout << value << " cost time " << dt << "s" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void benchmark_main_channel_passing_next()
|
void benchmark_main_channel_passing_next()
|
||||||
{
|
{
|
||||||
channel_t<intptr_t> head{1};
|
channel_t<intptr_t> head{1};
|
||||||
@ -39,6 +53,9 @@ void benchmark_main_channel_passing_next()
|
|||||||
in = tail;
|
in = tail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
go passing_loop_all(head, tail);
|
||||||
|
#else
|
||||||
GO
|
GO
|
||||||
{
|
{
|
||||||
for (int i = 0; i < LoopCount; ++i)
|
for (int i = 0; i < LoopCount; ++i)
|
||||||
@ -52,6 +69,7 @@ void benchmark_main_channel_passing_next()
|
|||||||
std::cout << value << " cost time " << dt << "s" << std::endl;
|
std::cout << value << " cost time " << dt << "s" << std::endl;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
this_scheduler()->run_until_notask();
|
this_scheduler()->run_until_notask();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#if defined(__clang__)
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
#include "src/unix/coroutine.h" //编译器内建的协程函数,MSVC和clang不一样
|
#include "src/unix/coroutine.h" //编译器内建的协程函数,MSVC和clang不一样
|
||||||
#else
|
#else
|
||||||
#include <experimental/coroutine>
|
#include <experimental/coroutine>
|
||||||
|
@ -14,9 +14,9 @@
|
|||||||
|
|
||||||
#ifndef RESUMEF_ENABLE_CONCEPT
|
#ifndef RESUMEF_ENABLE_CONCEPT
|
||||||
#ifdef __cpp_lib_concepts
|
#ifdef __cpp_lib_concepts
|
||||||
#define RESUMEF_ENABLE_CONCEPT 1
|
/* #undef RESUMEF_ENABLE_CONCEPT */
|
||||||
#else
|
#else
|
||||||
#define RESUMEF_ENABLE_CONCEPT 1
|
/* #undef RESUMEF_ENABLE_CONCEPT */
|
||||||
#endif //#ifdef __cpp_lib_concepts
|
#endif //#ifdef __cpp_lib_concepts
|
||||||
#endif //#ifndef RESUMEF_ENABLE_CONCEPT
|
#endif //#ifndef RESUMEF_ENABLE_CONCEPT
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ namespace resumef
|
|||||||
(void)e;
|
(void)e;
|
||||||
std::terminate();
|
std::terminate();
|
||||||
}
|
}
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
void unhandled_exception()
|
void unhandled_exception()
|
||||||
{
|
{
|
||||||
std::terminate();
|
std::terminate();
|
||||||
|
@ -25,7 +25,7 @@ namespace resumef
|
|||||||
* @brief 在析构的时候自动解锁mutex_t的辅助类。
|
* @brief 在析构的时候自动解锁mutex_t的辅助类。
|
||||||
*/
|
*/
|
||||||
template<class... _Mtxs>
|
template<class... _Mtxs>
|
||||||
struct [[nodiscard]] batch_unlock_t;
|
struct batch_unlock_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 支持递归的锁。
|
* @brief 支持递归的锁。
|
||||||
|
@ -475,7 +475,7 @@ namespace resumef
|
|||||||
for (int cnt = rand() % (1 + _mutex.size()); cnt >= 0; --cnt)
|
for (int cnt = rand() % (1 + _mutex.size()); cnt >= 0; --cnt)
|
||||||
{
|
{
|
||||||
std::this_thread::yield(); //还要考虑多线程里运行的情况
|
std::this_thread::yield(); //还要考虑多线程里运行的情况
|
||||||
co_await ::resumef::yield();
|
co_await yield_awaitor{};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
future_t<> _ReturnValue() const;
|
future_t<> _ReturnValue() const;
|
||||||
@ -489,7 +489,7 @@ namespace resumef
|
|||||||
};
|
};
|
||||||
|
|
||||||
template<class... _Mtxs>
|
template<class... _Mtxs>
|
||||||
struct [[nodiscard]] batch_unlock_t
|
struct batch_unlock_t
|
||||||
{
|
{
|
||||||
mutex_t::_MutexAwaitAssembleT _MAA;
|
mutex_t::_MutexAwaitAssembleT _MAA;
|
||||||
|
|
||||||
@ -534,13 +534,15 @@ namespace resumef
|
|||||||
co_return std::move(unlock_guard);
|
co_return std::move(unlock_guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __GNUC__
|
||||||
template<class... _Mtxs, typename>
|
template<class... _Mtxs, typename>
|
||||||
inline future_t<> mutex_t::lock(adopt_manual_unlock_t, _Mtxs&... mtxs)
|
inline future_t<> mutex_t::lock(adopt_manual_unlock_t, _Mtxs&... mtxs)
|
||||||
{
|
{
|
||||||
mutex_t::_MutexAwaitAssembleT _MAA{ root_state(), mtxs... };
|
mutex_t::_MutexAwaitAssembleT _MAA{ root_state(), mtxs... };
|
||||||
co_await detail::mutex_lock_await_lock_impl::_Lock_range(_MAA);
|
co_await detail::mutex_lock_await_lock_impl::_Lock_range(_MAA);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class... _Mtxs, typename>
|
template<class... _Mtxs, typename>
|
||||||
inline future_t<> mutex_t::unlock(_Mtxs&... mtxs)
|
inline future_t<> mutex_t::unlock(_Mtxs&... mtxs)
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ namespace resumef
|
|||||||
template <typename _Uty>
|
template <typename _Uty>
|
||||||
_Uty&& await_transform(_Uty&& _Whatever) noexcept;
|
_Uty&& await_transform(_Uty&& _Whatever) noexcept;
|
||||||
void set_exception(std::exception_ptr e);
|
void set_exception(std::exception_ptr e);
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
void unhandled_exception(); //If the coroutine ends with an uncaught exception, it performs the following:
|
void unhandled_exception(); //If the coroutine ends with an uncaught exception, it performs the following:
|
||||||
#endif
|
#endif
|
||||||
future_type get_return_object() noexcept;
|
future_type get_return_object() noexcept;
|
||||||
|
@ -73,7 +73,7 @@ namespace resumef
|
|||||||
this->get_state()->set_exception(std::move(e));
|
this->get_state()->set_exception(std::move(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
template <typename _Ty>
|
template <typename _Ty>
|
||||||
inline void promise_impl_t<_Ty>::unhandled_exception()
|
inline void promise_impl_t<_Ty>::unhandled_exception()
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ namespace resumef
|
|||||||
{
|
{
|
||||||
if (classname)
|
if (classname)
|
||||||
{
|
{
|
||||||
#if __clang__
|
#if defined(__clang__) || defined(__GNUC__)
|
||||||
#define sprintf_s sprintf
|
#define sprintf_s sprintf
|
||||||
#endif
|
#endif
|
||||||
sprintf_s(sz_future_error_buffer, "%s, code=%s", classname, future_error_string[(size_t)(fe)]);
|
sprintf_s(sz_future_error_buffer, "%s, code=%s", classname, future_error_string[(size_t)(fe)]);
|
||||||
|
@ -150,7 +150,7 @@ namespace resumef
|
|||||||
//msvc认为是constexpr表达式(不写还给警告),然而,clang不这么认为。
|
//msvc认为是constexpr表达式(不写还给警告),然而,clang不这么认为。
|
||||||
//放弃constexpr,反正合格的编译器都会优化掉这个if判断的。
|
//放弃constexpr,反正合格的编译器都会优化掉这个if判断的。
|
||||||
if
|
if
|
||||||
#ifndef __clang__
|
#ifdef _MSC_VER
|
||||||
constexpr
|
constexpr
|
||||||
#endif
|
#endif
|
||||||
(_offset_of(state_future_t, _is_future) - _offset_of(state_future_t, _has_value) == 1)
|
(_offset_of(state_future_t, _is_future) - _offset_of(state_future_t, _has_value) == 1)
|
||||||
|
@ -52,7 +52,12 @@ template <class P> struct hash<coroutine_handle<P>>;
|
|||||||
#include <memory> // for hash<T*>
|
#include <memory> // for hash<T*>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
#include "clang_builtin.h"
|
#include "clang_builtin.h"
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#include "gcc_builtin.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||||
#pragma GCC system_header
|
#pragma GCC system_header
|
||||||
@ -61,6 +66,9 @@ template <class P> struct hash<coroutine_handle<P>>;
|
|||||||
#ifndef _LIBCPP_HAS_NO_COROUTINES
|
#ifndef _LIBCPP_HAS_NO_COROUTINES
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
inline
|
||||||
|
#endif
|
||||||
namespace experimental {
|
namespace experimental {
|
||||||
|
|
||||||
template <class _Tp, class = void>
|
template <class _Tp, class = void>
|
||||||
|
@ -19,7 +19,8 @@ struct LOCK_ASSEMBLE_NAME(lock_impl)
|
|||||||
try {
|
try {
|
||||||
for (; _Next != _Last; ++_Next)
|
for (; _Next != _Last; ++_Next)
|
||||||
{
|
{
|
||||||
if (!LOCK_ASSEMBLE_AWAIT(_LkN._Try_lock_ref(_LkN[_Next])))
|
auto _Result__ = LOCK_ASSEMBLE_AWAIT(_LkN._Try_lock_ref(_LkN[_Next]));
|
||||||
|
if (!_Result__)
|
||||||
{ // try_lock failed, backout
|
{ // try_lock failed, backout
|
||||||
_Unlock_locks(_First, _Next, _LkN);
|
_Unlock_locks(_First, _Next, _LkN);
|
||||||
LOCK_ASSEMBLE_RETURN(_Next);
|
LOCK_ASSEMBLE_RETURN(_Next);
|
||||||
@ -84,7 +85,8 @@ struct LOCK_ASSEMBLE_NAME(lock_impl)
|
|||||||
// attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 returns whether to try again
|
// attempt to lock 2 locks, by first locking _Lk0, and then trying to lock _Lk1 returns whether to try again
|
||||||
LOCK_ASSEMBLE_AWAIT(_LkN._Lock_ref(_LkN[_Idx0]));
|
LOCK_ASSEMBLE_AWAIT(_LkN._Lock_ref(_LkN[_Idx0]));
|
||||||
try {
|
try {
|
||||||
if (LOCK_ASSEMBLE_AWAIT(_LkN._Try_lock_ref(_LkN[_Idx1])))
|
auto _Result__ = LOCK_ASSEMBLE_AWAIT(_LkN._Try_lock_ref(_LkN[_Idx1]));
|
||||||
|
if (_Result__)
|
||||||
LOCK_ASSEMBLE_RETURN(false);
|
LOCK_ASSEMBLE_RETURN(false);
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
@ -102,10 +104,20 @@ struct LOCK_ASSEMBLE_NAME(lock_impl)
|
|||||||
static auto _Lock_nonmember2(_LA& _LkN) ->decltype(_LkN._ReturnValue())
|
static auto _Lock_nonmember2(_LA& _LkN) ->decltype(_LkN._ReturnValue())
|
||||||
{
|
{
|
||||||
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
|
// lock 2 locks, without deadlock, special case for better codegen and reduced metaprogramming for common case
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
auto _Result__ = LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 0, 1));
|
||||||
|
if (!_Result__) break;
|
||||||
|
_Result__ = LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 1, 0));
|
||||||
|
if (!_Result__) break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
while (LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 0, 1)) &&
|
while (LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 0, 1)) &&
|
||||||
LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 1, 0)))
|
LOCK_ASSEMBLE_AWAIT(_Lock_attempt_small2(_LkN, 1, 0)))
|
||||||
{ // keep trying
|
{ // keep trying
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template<_LockAssembleT _LA>
|
template<_LockAssembleT _LA>
|
||||||
|
@ -22,7 +22,8 @@ static future_t<> resumable_wait_event(const event_t & e)
|
|||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
||||||
if (co_await e.wait() == false)
|
auto result = co_await e.wait();
|
||||||
|
if (result == false)
|
||||||
std::cout << "time out!" << std::endl;
|
std::cout << "time out!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "event signal!" << std::endl;
|
std::cout << "event signal!" << std::endl;
|
||||||
@ -69,7 +70,8 @@ static void test_wait_three()
|
|||||||
|
|
||||||
go[&]() -> future_t<>
|
go[&]() -> future_t<>
|
||||||
{
|
{
|
||||||
if (co_await event_t::wait_all(std::initializer_list<event_t>{ evt1, evt2, evt3 }))
|
auto result = co_await event_t::wait_all(std::initializer_list<event_t>{ evt1, evt2, evt3 });
|
||||||
|
if (result)
|
||||||
std::cout << "all event signal!" << std::endl;
|
std::cout << "all event signal!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "time out!" << std::endl;
|
std::cout << "time out!" << std::endl;
|
||||||
@ -125,7 +127,8 @@ static void test_wait_all()
|
|||||||
|
|
||||||
go[&]() -> future_t<>
|
go[&]() -> future_t<>
|
||||||
{
|
{
|
||||||
if (co_await event_t::wait_all(evts))
|
auto result = co_await event_t::wait_all(evts);
|
||||||
|
if (result)
|
||||||
std::cout << "all event signal!" << std::endl;
|
std::cout << "all event signal!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "time out!" << std::endl;
|
std::cout << "time out!" << std::endl;
|
||||||
@ -153,7 +156,8 @@ static void test_wait_all_timeout()
|
|||||||
|
|
||||||
go[&]() -> future_t<>
|
go[&]() -> future_t<>
|
||||||
{
|
{
|
||||||
if (co_await event_t::wait_all_for(1000ms, evts))
|
auto result = co_await event_t::wait_all_for(1000ms, evts);
|
||||||
|
if (result)
|
||||||
std::cout << "all event signal!" << std::endl;
|
std::cout << "all event signal!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "time out!" << std::endl;
|
std::cout << "time out!" << std::endl;
|
||||||
|
@ -35,7 +35,8 @@ void test_wait_timeout_one()
|
|||||||
intptr_t counter = 0;
|
intptr_t counter = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (co_await evt.wait_for(100ms))
|
auto result = co_await evt.wait_for(100ms);
|
||||||
|
if (result)
|
||||||
break;
|
break;
|
||||||
++counter;
|
++counter;
|
||||||
std::cout << ".";
|
std::cout << ".";
|
||||||
@ -137,7 +138,8 @@ void test_wait_timeout_all()
|
|||||||
intptr_t counter = 0;
|
intptr_t counter = 0;
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
if (co_await event_t::wait_all_for(1500ms, evts))
|
auto result = co_await event_t::wait_all_for(1500ms, evts);
|
||||||
|
if (result)
|
||||||
{
|
{
|
||||||
std::cout << counter << std::endl;
|
std::cout << counter << std::endl;
|
||||||
std::cout << "all event signal!" << std::endl;
|
std::cout << "all event signal!" << std::endl;
|
||||||
|
@ -29,7 +29,8 @@ static std::thread async_set_event_one(event_v2::event_t e, std::chrono::millise
|
|||||||
|
|
||||||
static future_t<> resumable_wait_event(event_v2::event_t e, int idx)
|
static future_t<> resumable_wait_event(event_v2::event_t e, int idx)
|
||||||
{
|
{
|
||||||
if (co_await e)
|
auto result = co_await e;
|
||||||
|
if (result)
|
||||||
std::cout << "[" << idx << "]event signal!" << std::endl;
|
std::cout << "[" << idx << "]event signal!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "[" << idx << "]time out!" << std::endl;
|
std::cout << "[" << idx << "]time out!" << std::endl;
|
||||||
@ -37,7 +38,8 @@ static future_t<> resumable_wait_event(event_v2::event_t e, int idx)
|
|||||||
|
|
||||||
static future_t<> resumable_wait_timeout(event_v2::event_t e, milliseconds dt, int idx)
|
static future_t<> resumable_wait_timeout(event_v2::event_t e, milliseconds dt, int idx)
|
||||||
{
|
{
|
||||||
if (co_await e.wait_for(dt))
|
auto result = co_await e.wait_for(dt);
|
||||||
|
if (result)
|
||||||
std::cout << "[" << idx << "]event signal!" << std::endl;
|
std::cout << "[" << idx << "]event signal!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "[" << idx << "]time out!" << std::endl;
|
std::cout << "[" << idx << "]time out!" << std::endl;
|
||||||
|
@ -51,7 +51,7 @@ future_t<int64_t> resumeable_get_long(int64_t x, int64_t y)
|
|||||||
using promise_type = typename future_type::promise_type;
|
using promise_type = typename future_type::promise_type;
|
||||||
using state_type = typename future_type::state_type;
|
using state_type = typename future_type::state_type;
|
||||||
|
|
||||||
void* frame_ptr = _coro_frame_ptr();
|
void* frame_ptr = __builtin_coro_frame();
|
||||||
auto handler = coroutine_handle<promise_type>::from_address(frame_ptr);
|
auto handler = coroutine_handle<promise_type>::from_address(frame_ptr);
|
||||||
promise_type* promise = &handler.promise();
|
promise_type* promise = &handler.promise();
|
||||||
state_type* state = handler.promise().get_state();
|
state_type* state = handler.promise().get_state();
|
||||||
@ -59,10 +59,10 @@ future_t<int64_t> resumeable_get_long(int64_t x, int64_t y)
|
|||||||
std::cout << " future size=" << sizeof(future_type) << " / " << _Align_size<future_type>() << std::endl;
|
std::cout << " future size=" << sizeof(future_type) << " / " << _Align_size<future_type>() << std::endl;
|
||||||
std::cout << " promise size=" << sizeof(promise_type) << " / " << _Align_size<promise_type>() << std::endl;
|
std::cout << " promise size=" << sizeof(promise_type) << " / " << _Align_size<promise_type>() << std::endl;
|
||||||
std::cout << " state size=" << sizeof(state_type) << " / "<< _Align_size<state_type>() << std::endl;
|
std::cout << " state size=" << sizeof(state_type) << " / "<< _Align_size<state_type>() << std::endl;
|
||||||
std::cout << " frame size=" << _coro_frame_size() << ", alloc size=" << state->get_alloc_size() << std::endl;
|
std::cout << " frame size=" << __builtin_coro_size() << ", alloc size=" << state->get_alloc_size() << std::endl;
|
||||||
|
|
||||||
std::cout << " frame ptr=" << frame_ptr << "," << (void*)&frame_ptr << std::endl;
|
std::cout << " frame ptr=" << frame_ptr << "," << (void*)&frame_ptr << std::endl;
|
||||||
std::cout << " frame end=" << (void*)((char*)(frame_ptr)+_coro_frame_size()) << std::endl;
|
std::cout << " frame end=" << (void*)((char*)(frame_ptr)+__builtin_coro_size()) << std::endl;
|
||||||
std::cout << " promise ptr=" << promise << "," << (void*)&promise << std::endl;
|
std::cout << " promise ptr=" << promise << "," << (void*)&promise << std::endl;
|
||||||
std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl;
|
std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl;
|
||||||
std::cout << " state ptr=" << state << "," << (void*)&state << std::endl;
|
std::cout << " state ptr=" << state << "," << (void*)&state << std::endl;
|
||||||
@ -90,7 +90,7 @@ future_t<> resumable_get_long_2(int64_t a, int64_t b, int64_t c)
|
|||||||
using promise_type = typename future_type::promise_type;
|
using promise_type = typename future_type::promise_type;
|
||||||
using state_type = typename future_type::state_type;
|
using state_type = typename future_type::state_type;
|
||||||
|
|
||||||
void* frame_ptr = _coro_frame_ptr();
|
void* frame_ptr = __builtin_coro_frame();
|
||||||
auto handler = coroutine_handle<promise_type>::from_address(frame_ptr);
|
auto handler = coroutine_handle<promise_type>::from_address(frame_ptr);
|
||||||
promise_type * promise = &handler.promise();
|
promise_type * promise = &handler.promise();
|
||||||
state_type * state = handler.promise().get_state();
|
state_type * state = handler.promise().get_state();
|
||||||
@ -98,10 +98,10 @@ future_t<> resumable_get_long_2(int64_t a, int64_t b, int64_t c)
|
|||||||
std::cout << " future size=" << sizeof(future_type) << " / " << _Align_size<future_type>() << std::endl;
|
std::cout << " future size=" << sizeof(future_type) << " / " << _Align_size<future_type>() << std::endl;
|
||||||
std::cout << " promise size=" << sizeof(promise_type) << " / " << _Align_size<promise_type>() << std::endl;
|
std::cout << " promise size=" << sizeof(promise_type) << " / " << _Align_size<promise_type>() << std::endl;
|
||||||
std::cout << " state size=" << sizeof(state_type) << " / "<< _Align_size<state_type>() << std::endl;
|
std::cout << " state size=" << sizeof(state_type) << " / "<< _Align_size<state_type>() << std::endl;
|
||||||
std::cout << " frame size=" << _coro_frame_size() << ", alloc size=" << state->get_alloc_size() << std::endl;
|
std::cout << " frame size=" << __builtin_coro_size() << ", alloc size=" << state->get_alloc_size() << std::endl;
|
||||||
|
|
||||||
std::cout << " frame ptr=" << frame_ptr << ","<< (void*)&frame_ptr << std::endl;
|
std::cout << " frame ptr=" << frame_ptr << ","<< (void*)&frame_ptr << std::endl;
|
||||||
std::cout << " frame end=" << (void *)((char*)(frame_ptr) + _coro_frame_size()) << std::endl;
|
std::cout << " frame end=" << (void *)((char*)(frame_ptr) + __builtin_coro_size()) << std::endl;
|
||||||
std::cout << " promise ptr=" << promise << "," << (void *)&promise << std::endl;
|
std::cout << " promise ptr=" << promise << "," << (void *)&promise << std::endl;
|
||||||
std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl;
|
std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl;
|
||||||
std::cout << " state ptr=" << state << "," << (void*)&state << std::endl;
|
std::cout << " state ptr=" << state << "," << (void*)&state << std::endl;
|
||||||
|
@ -61,8 +61,12 @@ static future_t<> test_mutex_try_push(size_t idx)
|
|||||||
for (size_t i = 0; i < N; ++i)
|
for (size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
while (!co_await g_lock.try_lock())
|
for (;;)
|
||||||
|
{
|
||||||
|
auto result = co_await g_lock.try_lock();
|
||||||
|
if (result) break;
|
||||||
co_await yield();
|
co_await yield();
|
||||||
|
}
|
||||||
|
|
||||||
++g_counter;
|
++g_counter;
|
||||||
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
||||||
@ -79,8 +83,12 @@ static future_t<> test_mutex_timeout_push(size_t idx)
|
|||||||
for (size_t i = 0; i < N; ++i)
|
for (size_t i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
while (!co_await g_lock.try_lock_for(10ms))
|
for (;;)
|
||||||
|
{
|
||||||
|
auto result = co_await g_lock.try_lock_for(10ms);
|
||||||
|
if (result) break;
|
||||||
co_await yield();
|
co_await yield();
|
||||||
|
}
|
||||||
|
|
||||||
++g_counter;
|
++g_counter;
|
||||||
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
std::cout << "push:" << g_counter << " on " << idx << std::endl;
|
||||||
|
@ -16,7 +16,7 @@ future_t<> test_routine_use_timer()
|
|||||||
{
|
{
|
||||||
co_await resumef::sleep_for(100ms);
|
co_await resumef::sleep_for(100ms);
|
||||||
std::cout << "timer after 100ms" << std::endl;
|
std::cout << "timer after 100ms" << std::endl;
|
||||||
std::cout << "1:frame=" << _coro_frame_ptr() << std::endl;
|
std::cout << "1:frame=" << __builtin_coro_frame() << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,11 +25,11 @@ future_t<> test_routine_use_timer_2()
|
|||||||
std::cout << "test_routine_use_timer_2" << std::endl;
|
std::cout << "test_routine_use_timer_2" << std::endl;
|
||||||
|
|
||||||
co_await test_routine_use_timer();
|
co_await test_routine_use_timer();
|
||||||
std::cout << "2:frame=" << _coro_frame_ptr() << std::endl;
|
std::cout << "2:frame=" << __builtin_coro_frame() << std::endl;
|
||||||
co_await test_routine_use_timer();
|
co_await test_routine_use_timer();
|
||||||
std::cout << "2:frame=" << _coro_frame_ptr() << std::endl;
|
std::cout << "2:frame=" << __builtin_coro_frame() << std::endl;
|
||||||
co_await test_routine_use_timer();
|
co_await test_routine_use_timer();
|
||||||
std::cout << "2:frame=" << _coro_frame_ptr() << std::endl;
|
std::cout << "2:frame=" << __builtin_coro_frame() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void resumable_main_routine()
|
void resumable_main_routine()
|
||||||
|
@ -38,7 +38,8 @@ void test_wait_all_events_with_signal_by_sleep()
|
|||||||
|
|
||||||
go[&]() -> future_t<>
|
go[&]() -> future_t<>
|
||||||
{
|
{
|
||||||
if (co_await event_t::wait_all(evts))
|
auto result = co_await event_t::wait_all(evts);
|
||||||
|
if (result)
|
||||||
std::cout << "all event signal!" << std::endl;
|
std::cout << "all event signal!" << std::endl;
|
||||||
else
|
else
|
||||||
std::cout << "time out!" << std::endl;
|
std::cout << "time out!" << std::endl;
|
||||||
|
@ -88,6 +88,18 @@ static future_t<> resumable_get_long_switch_scheduler(int64_t val, channel_t<boo
|
|||||||
(void)c_done.write(true);
|
(void)c_done.write(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static future_t<> resumable_main_switch_scheduler_fix_gcc_bugs(std::thread & other, channel_t<bool> c_done)
|
||||||
|
{
|
||||||
|
co_await c_done; //第一次等待,等待run_in_thread准备好了
|
||||||
|
|
||||||
|
std::cout << "other thread = " << other.get_id();
|
||||||
|
std::cout << ", sch_in_thread = " << sch_in_thread << std::endl;
|
||||||
|
|
||||||
|
go resumable_get_long_switch_scheduler(1, c_done); //开启另外一个协程
|
||||||
|
//co_await resumable_get_long(3, c_done);
|
||||||
|
co_await c_done; //等待新的协程运行完毕,从而保证主线程的协程不会提早退出
|
||||||
|
}
|
||||||
|
|
||||||
void resumable_main_switch_scheduler()
|
void resumable_main_switch_scheduler()
|
||||||
{
|
{
|
||||||
sch_in_main = this_scheduler();
|
sch_in_main = this_scheduler();
|
||||||
@ -98,6 +110,9 @@ void resumable_main_switch_scheduler()
|
|||||||
channel_t<bool> c_done{ 1 };
|
channel_t<bool> c_done{ 1 };
|
||||||
std::thread other(&run_in_thread, std::ref(c_done));
|
std::thread other(&run_in_thread, std::ref(c_done));
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
go resumable_main_switch_scheduler_fix_gcc_bugs(other, c_done);
|
||||||
|
#else
|
||||||
go[&other, c_done]()->future_t<>
|
go[&other, c_done]()->future_t<>
|
||||||
{
|
{
|
||||||
co_await c_done; //第一次等待,等待run_in_thread准备好了
|
co_await c_done; //第一次等待,等待run_in_thread准备好了
|
||||||
@ -108,7 +123,8 @@ void resumable_main_switch_scheduler()
|
|||||||
go resumable_get_long_switch_scheduler(1, c_done); //开启另外一个协程
|
go resumable_get_long_switch_scheduler(1, c_done); //开启另外一个协程
|
||||||
//co_await resumable_get_long(3, c_done);
|
//co_await resumable_get_long(3, c_done);
|
||||||
co_await c_done; //等待新的协程运行完毕,从而保证主线程的协程不会提早退出
|
co_await c_done; //等待新的协程运行完毕,从而保证主线程的协程不会提早退出
|
||||||
};
|
}; //GCC: internal compiler error: in captures_temporary, at cp/coroutines.cc:2716
|
||||||
|
#endif
|
||||||
|
|
||||||
sch_in_main->run_until_notask();
|
sch_in_main->run_until_notask();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user