Last active
November 4, 2025 19:17
-
-
Save talisein/f4cc66581660559896c33276e4e07435 to your computer and use it in GitHub Desktop.
GCC testcase for DPP coroutine
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Override default options. | |
| // { dg-do run } | |
| // { dg-options "-std=gnu++20 -fcoroutines -Wall -fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -D_GLIBCXX_ASSERTIONS -D_GLIBCXX_DEBUG -DAVX_TYPE=2 -DDPP_BUILD -DDPP_OS=Linux -DHAVE_VOICE -DNOMINMAX -I/home/agpotter/git/DPP/library/../mlspp/include -I/home/agpotter/git/DPP/library/../mlspp/lib/bytes/include -I/home/agpotter/git/DPP/library/../mlspp/lib/hpke/include -I/home/agpotter/git/DPP/library/../include -I/home/agpotter/git/DPP/library/../include/dpp -pthread " } | |
| // | |
| // filename: gcc/testsuite/g++.dg/coroutines/dpp-simple.C | |
| // run via: make -C gcc check-g++ RUNTESTFLAGS=dg.exp=dpp-simple.C | |
| // | |
| #include <thread> | |
| #include <iostream> | |
| #include <dpp/dpp.h> | |
| #include <coroutine> | |
| struct canary { | |
| std::string name; | |
| canary(std::string_view name) : name(name) { std::cerr << "Canary '" << name << "' is born\n"; } | |
| canary(const canary& other) { name = "copied " + other.name; std::cerr << "Canary '" << name << "' is born\n";} | |
| ~canary() { std::cerr << "Canary '" << name << "' is dead\n"; name = "DESTROYED CANARY?!"; } | |
| }; | |
| struct simple_awaitable { | |
| volatile int value{}; | |
| int result{}; | |
| canary c{"simple_awaitable"}; | |
| bool await_ready() const noexcept { | |
| return false; | |
| } | |
| template <typename T> | |
| void await_suspend(std::coroutine_handle<T> handle) { | |
| std::cerr << "simple_awaitable::await_suspend(): Got handle address " << handle.address() << "\n"; | |
| std::thread th([this, handle, c = canary{"thread-lambda capture"}]() mutable { | |
| auto _ = canary{"thread stack variable"}; | |
| std::cerr << "Inside simple_awaitable::await_suspend thread\n"; | |
| std::this_thread::sleep_for(std::chrono::seconds(5)); | |
| std::cerr << "Inside simple_awaitable::await_suspend thread: Finished 5s sleep\n"; | |
| result = value; | |
| try { | |
| std::cerr << "Inside simple_awaitable::await_suspend thread: About to resume handle address " << handle.address() << "\n"; | |
| handle.resume(); | |
| } catch (const std::exception &) { | |
| /* no exception should be caught */ | |
| std::cerr << "Inside simple_awaitable::await_suspend thread: went to exception\n"; | |
| } | |
| }); | |
| std::cerr << "Inside simple_awaitable::await_suspend, about to detach thread\n"; | |
| th.detach(); | |
| } | |
| int await_resume() const noexcept { | |
| std::cerr << "simple_awaitable::await_resume()\n"; | |
| return result; | |
| } | |
| }; | |
| dpp::task<void> task_offline_test() { | |
| std::cerr << "task_offline_test(): co_await simple_awaitable...\n"; | |
| if (int ret = co_await simple_awaitable{42}; ret != 42) { | |
| std::cerr << "failed simple awaitable: expected return value not 42\n"; | |
| } | |
| std::cerr << "task_offline_test(): simple_awaitable has returned, about to co_return myself. (simple_awaitable is destroyed now)\n"; | |
| co_return; | |
| } | |
| int main() | |
| { | |
| []() -> dpp::job { | |
| co_await task_offline_test(); | |
| }(); | |
| std::cerr << "main(): resuming execution.\n"; | |
| std::this_thread::sleep_for(std::chrono::seconds(10)); | |
| std::cerr << "main(): Sleep completed, we didn't crash yet? You fixed the problem.\n"; | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment