@@ -8,8 +8,8 @@ | |||
#include <thread> | |||
*/ | |||
#include <asio.hpp> | |||
#include "librf.h" | |||
#include <asio.hpp> | |||
#include "src/asio_task.h" | |||
#pragma warning(disable : 4834) | |||
@@ -47,7 +47,9 @@ future_t<> RunEchoSession(tcp::socket socket) | |||
std::array<char, BUF_SIZE> buffer; | |||
for(;;) | |||
{ | |||
#ifndef __clang__ | |||
try | |||
#endif | |||
{ | |||
bytes_transferred += co_await socket.async_read_some(asio::buffer(buffer.data() + bytes_transferred, buffer.size() - bytes_transferred), rf_task); | |||
if (bytes_transferred >= buffer.size()) | |||
@@ -58,11 +60,13 @@ future_t<> RunEchoSession(tcp::socket socket) | |||
g_echo_count.fetch_add(1, std::memory_order_release); | |||
} | |||
} | |||
#ifndef __clang__ | |||
catch (std::exception & e) | |||
{ | |||
std::cerr << e.what() << std::endl; | |||
break; | |||
} | |||
#endif | |||
} | |||
} | |||
@@ -77,15 +81,19 @@ void AcceptConnections(tcp::acceptor & acceptor, uarray<tcp::socket, _N> & socke | |||
{ | |||
for (;;) | |||
{ | |||
#ifndef __clang__ | |||
try | |||
#endif | |||
{ | |||
co_await acceptor.async_accept(socketes.c[idx], rf_task); | |||
go RunEchoSession(std::move(socketes.c[idx])); | |||
} | |||
#ifndef __clang__ | |||
catch (std::exception & e) | |||
{ | |||
std::cerr << e.what() << std::endl; | |||
} | |||
#endif | |||
} | |||
}; | |||
} | |||
@@ -151,7 +159,9 @@ future_t<> RunPipelineEchoClient(asio::io_service & ios, tcp::resolver::iterator | |||
{ | |||
std::shared_ptr<tcp::socket> sptr = std::make_shared<tcp::socket>(ios); | |||
#ifndef __clang__ | |||
try | |||
#endif | |||
{ | |||
co_await asio::async_connect(*sptr, ep, rf_task); | |||
@@ -161,22 +171,28 @@ future_t<> RunPipelineEchoClient(asio::io_service & ios, tcp::resolver::iterator | |||
for (auto & c : write_buff_) | |||
c = 'A' + rand() % 52; | |||
#ifndef __clang__ | |||
try | |||
#endif | |||
{ | |||
for (;;) | |||
{ | |||
co_await asio::async_write(*sptr, asio::buffer(write_buff_), rf_task); | |||
} | |||
} | |||
#ifndef __clang__ | |||
catch (std::exception & e) | |||
{ | |||
std::cerr << e.what() << std::endl; | |||
} | |||
#endif | |||
}; | |||
GO | |||
{ | |||
#ifndef __clang__ | |||
try | |||
#endif | |||
{ | |||
std::array<char, BUF_SIZE> read_buff_; | |||
for (;;) | |||
@@ -184,16 +200,20 @@ future_t<> RunPipelineEchoClient(asio::io_service & ios, tcp::resolver::iterator | |||
co_await sptr->async_read_some(asio::buffer(read_buff_), rf_task); | |||
} | |||
} | |||
#ifndef __clang__ | |||
catch (std::exception & e) | |||
{ | |||
std::cerr << e.what() << std::endl; | |||
} | |||
#endif | |||
}; | |||
} | |||
#ifndef __clang__ | |||
catch (std::exception & e) | |||
{ | |||
std::cerr << e.what() << std::endl; | |||
} | |||
#endif | |||
} | |||
#if _HAS_CXX17 | |||
@@ -205,7 +225,9 @@ future_t<> RunPingPongEchoClient(asio::io_service & ios, tcp::resolver::iterator | |||
std::array<char, BUF_SIZE> read_buff_; | |||
std::array<char, BUF_SIZE> write_buff_; | |||
#ifndef __clang__ | |||
try | |||
#endif | |||
{ | |||
co_await asio::async_connect(socket_, ep, rf_task); | |||
@@ -220,10 +242,12 @@ future_t<> RunPingPongEchoClient(asio::io_service & ios, tcp::resolver::iterator | |||
); | |||
} | |||
} | |||
#ifndef __clang__ | |||
catch (std::exception & e) | |||
{ | |||
std::cerr << e.what() << std::endl; | |||
} | |||
#endif | |||
} | |||
void resumable_main_benchmark_asio_client_with_rf(intptr_t nNum) |
@@ -8,6 +8,7 @@ | |||
#include "librf.h" | |||
const size_t N = 1000000; | |||
const size_t LOOP_COUNT = 100; | |||
volatile size_t globalValue = 0; | |||
@@ -19,7 +20,7 @@ void resumable_main_benchmark_mem() | |||
{ | |||
go[=]()->resumef::generator_t<size_t> | |||
{ | |||
for (size_t k = 0; k < 10; ++k) | |||
for (size_t k = 0; k < LOOP_COUNT; ++k) | |||
{ | |||
globalValue += i * k; | |||
co_yield k; | |||
@@ -29,5 +30,6 @@ void resumable_main_benchmark_mem() | |||
} | |||
resumef::this_scheduler()->run_until_notask(); | |||
std::cout << "press any key to continue." << std::endl; | |||
(void)_getch(); | |||
} |
@@ -1,7 +1,6 @@ | |||
| |||
#pragma once | |||
#include <asio.hpp> | |||
#if ASIO_VERSION >= 101200 | |||
#include "asio_task_1.12.0.inl" | |||
#else |
@@ -1,6 +1,6 @@ | |||
#pragma once | |||
#define LIB_RESUMEF_VERSION 20300 // 2.3.0 | |||
#define LIB_RESUMEF_VERSION 20301 // 2.3.1 | |||
#if defined(RESUMEF_MODULE_EXPORT) | |||
#define RESUMEF_NS export namespace resumef |
@@ -53,6 +53,10 @@ RESUMEF_NS | |||
_scheduler_ptr = new scheduler_t; | |||
th_scheduler_ptr = _scheduler_ptr; | |||
} | |||
else | |||
{ | |||
_scheduler_ptr = nullptr; | |||
} | |||
#endif | |||
} | |||
@@ -70,6 +74,11 @@ RESUMEF_NS | |||
{ | |||
_runing_states.reserve(1024); | |||
_cached_states.reserve(1024); | |||
#if RESUMEF_ENABLE_MULT_SCHEDULER | |||
if (th_scheduler_ptr == nullptr) | |||
th_scheduler_ptr = this; | |||
#endif | |||
} | |||
scheduler_t::~scheduler_t() | |||
@@ -98,17 +107,17 @@ RESUMEF_NS | |||
void scheduler_t::add_initial(state_base_t* sptr) | |||
{ | |||
scoped_lock<spinlock, lock_type> __guard(_lock_ready, _lock_running); | |||
scoped_lock<spinlock, spinlock> __guard(_lock_ready, _lock_running); | |||
_runing_states.emplace_back(sptr); | |||
_ready_task.try_emplace(sptr, nullptr); | |||
_runing_states.emplace_back(sptr); | |||
} | |||
void scheduler_t::add_await(state_base_t* sptr) | |||
{ | |||
if (sptr->is_ready()) | |||
{ | |||
scoped_lock<lock_type> __guard(_lock_running); | |||
scoped_lock<spinlock> __guard(_lock_running); | |||
_runing_states.emplace_back(sptr); | |||
} | |||
} | |||
@@ -119,14 +128,14 @@ RESUMEF_NS | |||
if (sptr->has_handler()) | |||
{ | |||
scoped_lock<lock_type> __guard(_lock_running); | |||
scoped_lock<spinlock> __guard(_lock_running); | |||
_runing_states.emplace_back(sptr); | |||
} | |||
} | |||
void scheduler_t::add_generator(state_base_t* sptr) | |||
{ | |||
scoped_lock<lock_type> __guard(_lock_running); | |||
scoped_lock<spinlock> __guard(_lock_running); | |||
_runing_states.emplace_back(sptr); | |||
} | |||
@@ -138,7 +147,7 @@ RESUMEF_NS | |||
} | |||
if (sptr->has_handler()) | |||
{ | |||
scoped_lock<lock_type> __guard(_lock_running); | |||
scoped_lock<spinlock> __guard(_lock_running); | |||
_runing_states.emplace_back(sptr); | |||
} | |||
} | |||
@@ -170,7 +179,7 @@ RESUMEF_NS | |||
/* | |||
void scheduler_t::cancel_all_task_() | |||
{ | |||
scoped_lock<spinlock, lock_type> __guard(_lock_ready, _lock_running); | |||
scoped_lock<spinlock, spinlock> __guard(_lock_ready, _lock_running); | |||
this->_ready_task.clear(); | |||
this->_runing_states.clear(); | |||
@@ -185,14 +194,10 @@ RESUMEF_NS | |||
void scheduler_t::run_one_batch() | |||
{ | |||
#if RESUMEF_ENABLE_MULT_SCHEDULER | |||
if (th_scheduler_ptr == nullptr) | |||
th_scheduler_ptr = this; | |||
#endif | |||
this->_timer->update(); | |||
{ | |||
scoped_lock<lock_type> __guard(_lock_running); | |||
scoped_lock<spinlock> __guard(_lock_running); | |||
if (_runing_states.empty()) | |||
return; | |||
@@ -12,7 +12,7 @@ RESUMEF_NS | |||
using lock_type = std::recursive_mutex; | |||
using task_dictionary_type = std::unordered_map<state_base_t*, std::unique_ptr<task_base_t>>; | |||
mutable lock_type _lock_running; | |||
mutable spinlock _lock_running; | |||
state_vector _runing_states; | |||
state_vector _cached_states; | |||
@@ -41,7 +41,7 @@ RESUMEF_NS | |||
inline bool empty() const | |||
{ | |||
scoped_lock<spinlock, lock_type> __guard(_lock_ready, _lock_running); | |||
scoped_lock<spinlock, spinlock> __guard(_lock_ready, _lock_running); | |||
return _ready_task.empty() && _runing_states.empty() && _timer->empty(); | |||
} | |||
@@ -9,6 +9,8 @@ | |||
#ifndef _LIBCPP_EXPERIMENTAL_COROUTINE | |||
#define _LIBCPP_EXPERIMENTAL_COROUTINE | |||
#define _EXPERIMENTAL_COROUTINE_ | |||
/** | |||
experimental/coroutine synopsis | |||
@@ -61,9 +61,10 @@ void resumable_switch(intptr_t coro, size_t idx) | |||
void resumable_main_resumable() | |||
{ | |||
resumable_switch(1, 0); | |||
//resumable_switch(10, 0); | |||
//resumable_switch(100, 0); | |||
resumable_switch(10, 0); | |||
resumable_switch(100, 0); | |||
resumable_switch(1000, 0); | |||
resumable_switch(10000, 0); | |||
resumable_switch(30000, 0); | |||
/* |
@@ -31,8 +31,8 @@ int main(int argc, const char* argv[]) | |||
{ | |||
(void)argc; | |||
(void)argv; | |||
resumable_main_layout(); | |||
return 0; | |||
//resumable_main_resumable(); | |||
//return 0; | |||
//if (argc > 1) | |||
// resumable_main_benchmark_asio_client(atoi(argv[1])); | |||
@@ -44,13 +44,13 @@ int main(int argc, const char* argv[]) | |||
resumable_main_modern_cb(); | |||
resumable_main_suspend_always(); | |||
resumable_main_yield_return(); | |||
//resumable_main_resumable(); | |||
resumable_main_resumable(); | |||
resumable_main_routine(); | |||
resumable_main_exception(); | |||
resumable_main_dynamic_go(); | |||
//resumable_main_multi_thread(); | |||
resumable_main_multi_thread(); | |||
resumable_main_timer(); | |||
//resumable_main_benchmark_mem(); | |||
resumable_main_benchmark_mem(); | |||
resumable_main_mutex(); | |||
resumable_main_event(); | |||
resumable_main_event_timeout(); | |||
@@ -59,9 +59,9 @@ int main(int argc, const char* argv[]) | |||
resumable_main_sleep(); | |||
resumable_main_when_all(); | |||
resumable_main_switch_scheduler(); | |||
//benchmark_main_channel_passing_next(); | |||
std::cout << "ALL OK!" << std::endl; | |||
benchmark_main_channel_passing_next(); //这是一个死循环测试 | |||
return 0; | |||
} |
@@ -40,7 +40,7 @@ | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||
<ConfigurationType>Application</ConfigurationType> | |||
<PlatformToolset>v142</PlatformToolset> | |||
<PlatformToolset>ClangCL</PlatformToolset> | |||
<UseDebugLibraries>true</UseDebugLibraries> | |||
</PropertyGroup> | |||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |||
@@ -170,10 +170,7 @@ | |||
</Link> | |||
</ItemDefinitionGroup> | |||
<ItemGroup> | |||
<ClCompile Include="..\benchmark\benchmark_asio_echo.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\benchmark\benchmark_asio_echo.cpp" /> | |||
<ClCompile Include="..\benchmark\benchmark_async_mem.cpp" /> | |||
<ClCompile Include="..\benchmark\benchmark_channel_passing_next.cpp" /> | |||
<ClCompile Include="..\librf\src\event.cpp" /> | |||
@@ -184,58 +181,24 @@ | |||
<ClCompile Include="..\librf\src\state.cpp" /> | |||
<ClCompile Include="..\librf\src\timer.cpp" /> | |||
<ClCompile Include="..\librf\src\when.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_cb.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_channel.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_dynamic_go.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_event.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_event_timeout.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_exception.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_cb.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_channel.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_channel_mult_thread.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_dynamic_go.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_event.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_event_timeout.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_exception.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_memory_layout.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_modern_cb.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_multi_thread.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_mutex.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_resumable.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_routine.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_sleep.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_suspend_always.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_switch_scheduler.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_timer.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_when_all.cpp"> | |||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | |||
</ClCompile> | |||
<ClCompile Include="..\tutorial\test_async_modern_cb.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_multi_thread.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_mutex.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_resumable.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_routine.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_sleep.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_suspend_always.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_switch_scheduler.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_timer.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_when_all.cpp" /> | |||
<ClCompile Include="..\tutorial\test_async_yield_return.cpp" /> | |||
<ClCompile Include="librf.cpp"> | |||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Default</BasicRuntimeChecks> |