基于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.

gcc_bugs.cpp 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. g++ --version:
  3. g++ (Ubuntu 10 - 20200416 - 0ubuntu1~18.04) 10.0.1 20200416 (experimental)[master revision 3c3f12e2a76:dcee354ce56:44b326839d864fc10c459916abcc97f35a9ac3de]
  4. Copyright(C) 2020 Free Software Foundation, Inc.
  5. This is free software; see the source for copying conditions.There is NO
  6. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  7. */
  8. #include <iostream>
  9. #include "librf.h"
  10. using namespace librf;
  11. #define GCC_FIX_BUGS 1
  12. static future_t<> gcc_bugs_if_await(event_t e)
  13. {
  14. #if GCC_FIX_BUGS
  15. auto result = co_await e.wait();
  16. if (result == false)
  17. #else
  18. if (co_await e.wait() == false) //internal compiler error: in fold_convert_loc, at fold-const.c:2435
  19. #endif
  20. std::cout << "time out!" << std::endl;
  21. else
  22. std::cout << "event signal!" << std::endl;
  23. }
  24. static future_t<> gcc_bugs_while_await(mutex_t lock)
  25. {
  26. #if GCC_FIX_BUGS
  27. for (;;)
  28. {
  29. auto result = co_await lock.try_lock();
  30. if (result) break;
  31. }
  32. #else
  33. while (!co_await lock.try_lock()); //internal compiler error: in fold_convert_loc, at fold-const.c:2435
  34. #endif
  35. std::cout << "OK." << std::endl;
  36. }
  37. #if GCC_FIX_BUGS
  38. static future_t<> gcc_bugs_lambda_coroutines_fixed(std::thread& other, channel_t<bool> c_done)
  39. {
  40. co_await c_done;
  41. std::cout << "other thread = " << other.get_id();
  42. co_await c_done;
  43. }
  44. #endif
  45. static void gcc_bugs_lambda_coroutines()
  46. {
  47. channel_t<bool> c_done{ 1 };
  48. std::thread other;
  49. #if GCC_FIX_BUGS
  50. go gcc_bugs_lambda_coroutines_fixed(other, c_done);
  51. #else
  52. go[&other, c_done]()->future_t<>
  53. {
  54. co_await c_done;
  55. std::cout << "other thread = " << other.get_id();
  56. co_await c_done;
  57. }; //internal compiler error: in captures_temporary, at cp/coroutines.cc:2716
  58. #endif
  59. }
  60. #if GCC_FIX_BUGS
  61. static future_t<> gcc_bugs_lambda_coroutines2_fixed(channel_t<intptr_t> head, channel_t<intptr_t> tail)
  62. {
  63. for (int i = 0; i < 100; ++i)
  64. {
  65. co_await(head << 0);
  66. co_await tail;
  67. }
  68. }
  69. #endif
  70. static void gcc_bugs_lambda_coroutines2()
  71. {
  72. channel_t<intptr_t> head{ 1 };
  73. channel_t<intptr_t> tail{ 0 };
  74. #if GCC_FIX_BUGS
  75. go gcc_bugs_lambda_coroutines2_fixed(head, tail);
  76. #else
  77. GO
  78. {
  79. for (int i = 0; i < 100; ++i)
  80. {
  81. co_await(head << 0);
  82. intptr_t value = co_await tail;
  83. (void)value;
  84. }
  85. }; //internal compiler error: in captures_temporary, at cp/coroutines.cc:2716
  86. #endif
  87. }
  88. template<class... _Mtxs>
  89. static future_t<> gcc_bugs_nameless_args(adopt_manual_unlock_t
  90. #if GCC_FIX_BUGS
  91. nameless
  92. #endif
  93. , _Mtxs&... mtxs)
  94. {
  95. #if GCC_FIX_BUGS
  96. (void)nameless;
  97. #endif
  98. co_await mutex_t::lock(adopt_manual_unlock, mtxs...);
  99. } //internal compiler error: Segmentation fault
  100. void gcc_bugs()
  101. {
  102. event_t e;
  103. go gcc_bugs_if_await(e);
  104. mutex_t mtx;
  105. go gcc_bugs_while_await(mtx);
  106. mutex_t a, b, c;
  107. go gcc_bugs_nameless_args(adopt_manual_unlock, a, b, c);
  108. }