Skip to content

Instantly share code, notes, and snippets.

@talisein
Last active November 4, 2025 19:17
Show Gist options
  • Select an option

  • Save talisein/f4cc66581660559896c33276e4e07435 to your computer and use it in GitHub Desktop.

Select an option

Save talisein/f4cc66581660559896c33276e4e07435 to your computer and use it in GitHub Desktop.
GCC testcase for DPP coroutine
// 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