forked from OSchip/llvm-project
84 lines
2.3 KiB
Plaintext
84 lines
2.3 KiB
Plaintext
; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/coroutine.perfscript --binary=%S/Inputs/coroutine.perfbin --output=%t
|
|
; RUN: FileCheck %s --input-file %t --check-prefix=CHECK
|
|
|
|
; Check that the head sample count for ticker is 0.
|
|
; CHECK: _Z6tickeri:353:0
|
|
; CHECK-NOT: _Z6tickeri.resume
|
|
|
|
|
|
/*
|
|
* Inputs/coroutine.perfbin is generated by compiling the following source code:
|
|
* clang++ coroutine.cpp -std=c++2a -g2 -o coroutine
|
|
*/
|
|
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <ctime>
|
|
#include <experimental/coroutine>
|
|
#include <iostream>
|
|
|
|
struct task {
|
|
struct promise_type {
|
|
task get_return_object() { return {}; }
|
|
std::experimental::suspend_never initial_suspend() { return {}; }
|
|
std::experimental::suspend_never final_suspend() noexcept { return {}; }
|
|
void return_void() {}
|
|
void unhandled_exception() {}
|
|
};
|
|
};
|
|
|
|
template <typename T>
|
|
struct generator {
|
|
struct promise_type;
|
|
using handle = std::experimental::coroutine_handle<promise_type>;
|
|
struct promise_type {
|
|
int current_value;
|
|
static auto get_return_object_on_allocation_failure() { return generator{nullptr}; }
|
|
auto get_return_object() { return generator{handle::from_promise(*this)}; }
|
|
auto initial_suspend() { return std::experimental::suspend_always{}; }
|
|
auto final_suspend() { return std::experimental::suspend_always{}; }
|
|
void unhandled_exception() { std::terminate(); }
|
|
void return_void() {}
|
|
auto yield_value(int value) {
|
|
current_value = value;
|
|
return std::experimental::suspend_always{};
|
|
}
|
|
};
|
|
bool move_next() { return coro ? (coro.resume(), !coro.done()) : false; }
|
|
int current_value() { return coro.promise().current_value; }
|
|
generator(generator const &) = delete;
|
|
generator(generator &&rhs) : coro(rhs.coro) { rhs.coro = nullptr; }
|
|
~generator() {
|
|
if (coro)
|
|
coro.destroy();
|
|
}
|
|
|
|
private:
|
|
generator(handle h) : coro(h) {}
|
|
handle coro;
|
|
};
|
|
|
|
generator<int> ticker(int count) {
|
|
for (int i = 0; i < count; ++i) {
|
|
srand(time(NULL));
|
|
uint32_t a = rand() % 10 + 1;
|
|
uint32_t b = rand() % 10 + 1;
|
|
uint64_t c = 0;
|
|
for (int i = 0; i < 1500; ++i) {
|
|
c = ((uint64_t)a) + b;
|
|
a = b;
|
|
b = c % 2147483648ULL;
|
|
}
|
|
co_yield a;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
auto g = ticker(500000);
|
|
uint64_t ans = 0;
|
|
while (g.move_next()) {
|
|
ans += g.current_value();
|
|
}
|
|
std::cout << ans << "\n";
|
|
}
|