基于C++ Coroutines提案 ‘Stackless Resumable Functions’编写的协程库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_async_memory_layout.cpp 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #include <chrono>
  2. #include <iostream>
  3. #include <string>
  4. #include <thread>
  5. #include "librf/librf.h"
  6. using namespace librf;
  7. #ifndef __GNUC__ //GCC: 没有提供__builtin_coro_frame这样的内置函数
  8. template<class _Ctype>
  9. static void callback_get_long(int64_t a, int64_t b, _Ctype&& cb)
  10. {
  11. std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl;
  12. //编译失败。因为这个函数不是"可恢复函数(resumeable function)",甚至都不是"可等待函数(awaitable function)"
  13. //void* frame_ptr = _coro_frame_ptr();
  14. using namespace std::chrono;
  15. std::thread([=, cb = std::forward<_Ctype>(cb)]
  16. {
  17. std::this_thread::sleep_for(500ms);
  18. cb(a + b);
  19. }).detach();
  20. std::cout << __FUNCTION__ << " - end" << std::endl;
  21. }
  22. //这种情况下,没有生成 frame-context,因此,并没有promise_type被内嵌在frame-context里
  23. future_t<int64_t> awaitable_get_long(int64_t a, int64_t b)
  24. {
  25. std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl;
  26. //编译失败。因为这个函数不是"可恢复函数(resumeable function)",仅仅是"可等待函数(awaitable function)"
  27. //void* frame_ptr = _coro_frame_ptr();
  28. librf::awaitable_t<int64_t> awaitable;
  29. callback_get_long(a, b, [awaitable](int64_t val)
  30. {
  31. awaitable.set_value(val);
  32. });
  33. std::cout << __FUNCTION__ << " - end" << std::endl;
  34. return awaitable.get_future();
  35. }
  36. future_t<int64_t> resumeable_get_long(int64_t x, int64_t y)
  37. {
  38. std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl;
  39. using future_type = future_t<int64_t>;
  40. using promise_type = typename future_type::promise_type;
  41. using state_type = typename future_type::state_type;
  42. void* frame_ptr = _coro_frame_ptr();
  43. auto handler = coroutine_handle<promise_type>::from_address(frame_ptr);
  44. promise_type* promise = &handler.promise();
  45. state_type* state = handler.promise().get_state();
  46. std::cout << " future size=" << sizeof(future_type) << " / " << _Align_size<future_type>() << std::endl;
  47. std::cout << " promise size=" << sizeof(promise_type) << " / " << _Align_size<promise_type>() << std::endl;
  48. std::cout << " state size=" << sizeof(state_type) << " / "<< _Align_size<state_type>() << std::endl;
  49. std::cout << " frame size=" << _coro_frame_size() << ", alloc size=" << state->get_alloc_size() << std::endl;
  50. std::cout << " frame ptr=" << frame_ptr << "," << (void*)&frame_ptr << std::endl;
  51. std::cout << " frame end=" << (void*)((char*)(frame_ptr)+_coro_frame_size()) << std::endl;
  52. std::cout << " promise ptr=" << promise << "," << (void*)&promise << ",offset=" << ((char*)promise - (char*)frame_ptr) << std::endl;
  53. std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << ",offset=" << ((char*)handler.address() - (char*)frame_ptr) << std::endl;
  54. std::cout << " state ptr=" << state << "," << (void*)&state << ",offset=" << ((char*)state - (char*)frame_ptr) << std::endl;
  55. std::cout << " parent ptr=" << state->get_parent() << std::endl;
  56. std::cout << " x=" << x << ", &x=" << std::addressof(x) << std::endl;
  57. std::cout << " y=" << y << ", &y=" << std::addressof(y) << std::endl;
  58. int64_t val = co_await awaitable_get_long(x, y);
  59. std::cout << " val=" << val << ", &val=" << std::addressof(val) << std::endl;
  60. std::cout << __FUNCTION__ << " - end" << std::endl;
  61. co_return val;
  62. }
  63. //这种情况下,会生成对应的 frame-context,一个promise_type被内嵌在frame-context里
  64. future_t<> resumable_get_long_2(int64_t a, int64_t b, int64_t c)
  65. {
  66. int64_t v1, v2, v3;
  67. std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl;
  68. using future_type = future_t<>;
  69. using promise_type = typename future_type::promise_type;
  70. using state_type = typename future_type::state_type;
  71. void* frame_ptr = _coro_frame_ptr();
  72. auto handler = coroutine_handle<promise_type>::from_address(frame_ptr);
  73. promise_type * promise = &handler.promise();
  74. state_type * state = handler.promise().get_state();
  75. std::cout << " future size=" << sizeof(future_type) << " / " << _Align_size<future_type>() << std::endl;
  76. std::cout << " promise size=" << sizeof(promise_type) << " / " << _Align_size<promise_type>() << std::endl;
  77. std::cout << " state size=" << sizeof(state_type) << " / "<< _Align_size<state_type>() << std::endl;
  78. std::cout << " frame size=" << _coro_frame_size() << ", alloc size=" << state->get_alloc_size() << std::endl;
  79. std::cout << " frame ptr=" << frame_ptr << ","<< (void*)&frame_ptr << std::endl;
  80. std::cout << " frame end=" << (void *)((char*)(frame_ptr) + _coro_frame_size()) << std::endl;
  81. std::cout << " promise ptr=" << promise << "," << (void *)&promise << std::endl;
  82. std::cout << " handle ptr=" << handler.address() << "," << (void*)&handler << std::endl;
  83. std::cout << " state ptr=" << state << "," << (void*)&state << std::endl;
  84. std::cout << " parent ptr=" << state->get_parent() << std::endl;
  85. std::cout << " a=" << a << ", &a=" << std::addressof(a) << std::endl;
  86. std::cout << " b=" << b << ", &b=" << std::addressof(b) << std::endl;
  87. std::cout << " c=" << c << ", &c=" << std::addressof(c) << std::endl;
  88. v1 = co_await resumeable_get_long(a, b);
  89. std::cout << " v1=" << v1 << ", &v1=" << std::addressof(v1) << std::endl;
  90. v2 = co_await resumeable_get_long(b, c);
  91. std::cout << " v2=" << v2 << ", &v2=" << std::addressof(v2) << std::endl;
  92. v3 = co_await resumeable_get_long(v1, v2);
  93. std::cout << " v3=" << v3 << ", &v3=" << std::addressof(v3) << std::endl;
  94. int64_t v4 = v1 * v2 * v3;
  95. std::cout << " v4=" << v4 << ", &v4=" << std::addressof(v4) << std::endl;
  96. std::cout << __FUNCTION__ << " - end" << std::endl;
  97. }
  98. #endif //#ifndef __GNUC__
  99. void resumable_main_layout()
  100. {
  101. std::cout << std::endl << __FUNCTION__ << " - begin" << std::endl;
  102. #ifndef __GNUC__ //GCC: 没有提供__builtin_coro_frame这样的内置函数
  103. go resumable_get_long_2(1, 2, 5);
  104. #endif //#ifndef __GNUC__
  105. librf::this_scheduler()->run_until_notask();
  106. std::cout << __FUNCTION__ << " - end" << std::endl;
  107. }
  108. #if LIBRF_TUTORIAL_STAND_ALONE
  109. int main()
  110. {
  111. resumable_main_layout();
  112. return 0;
  113. }
  114. #endif