-
Notifications
You must be signed in to change notification settings - Fork 268
/
Copy pathpmr_lazy.cpp
105 lines (91 loc) · 3.47 KB
/
pmr_lazy.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <array>
#include <cassert>
#include <cstddef>
#include <iostream>
#include <memory>
#include <new>
#include "async_simple/coro/Lazy.h"
#include "async_simple/coro/SyncAwait.h"
#if __has_include(<memory_resource>)
#include <memory_resource>
#endif
namespace ac = async_simple::coro;
#if __has_include(<memory_resource>)
class print_new_delete_memory_resource : public std::pmr::memory_resource {
void* do_allocate(std::size_t bytes, size_t /*alignment*/) override {
std::cout << "allocate " << bytes << " bytes\n";
return ::operator new(bytes);
}
void do_deallocate(void* p, std::size_t bytes,
size_t /*alignment*/) override {
std::cout << "deallocate " << bytes << " bytes\n";
::operator delete(p);
}
bool do_is_equal(const memory_resource& other) const noexcept override {
return this == &other;
}
};
#endif
ac::Lazy<int> get_43() {
std::cout << "run with ::operator new/delete" << '\n';
co_return 43;
}
#if __has_include(<memory_resource>)
ac::Lazy<int> get_43_plus_i(
std::allocator_arg_t /*unused*/,
std::pmr::polymorphic_allocator<> /*coroutine state allocator*/,
int i = 0) {
std::cout << "run with async_simple::coro::pmr::memory_resource" << '\n';
int test{};
test = co_await get_43();
std::cout << "a pointer on coroutine frame: " << &test << '\n';
co_return test + i;
}
#endif
std::array<std::byte, 1024> global_buffer;
int main() {
int i = 0;
std::cout << "###############################################\n";
// run without pmr argument, use global new/delete to allocate Lazy's
// coroutine state
i += syncAwait(get_43());
#if __has_include(<memory_resource>)
std::cout << "\n###############################################\n";
std::cout << "global buffer address: " << global_buffer.data() << '\n';
std::pmr::monotonic_buffer_resource pool(global_buffer.data(),
global_buffer.size(),
std::pmr::null_memory_resource());
std::pmr::polymorphic_allocator alloc(&pool);
// the first argument std::allocator_arg indicates that the second argument
// is an custom allocator, which will be used to allocate the coroutine
// state
i += syncAwait(get_43_plus_i(std::allocator_arg, alloc));
// allocate Lazy's coroutine state on stack
std::cout << "\n###############################################\n";
std::array<std::byte, 1024> stack_buffer;
std::cout << "stack buffer address: " << stack_buffer.data() << '\n';
std::pmr::monotonic_buffer_resource stack_pool(
stack_buffer.data(), stack_buffer.size(),
std::pmr::null_memory_resource());
std::pmr::polymorphic_allocator stack_alloc(&stack_pool);
// additional argument can be passed to the coroutine
i += syncAwait(get_43_plus_i(std::allocator_arg, stack_alloc, 4));
std::cout << "\n###############################################\n";
// run with a custom memory resource which prints the allocation and
// deallocation process
print_new_delete_memory_resource res;
std::pmr::polymorphic_allocator<std::byte> print_alloc(&res);
i += syncAwait(get_43_plus_i(std::allocator_arg, print_alloc));
#endif
std::cout << '\n';
if (i == 43
#if __has_include(<memory_resource>)
+ 43 + 43 + 43 + 4
#endif
) {
std::cout << "test passed\n";
} else {
std::cout << "test failed\n";
}
return 0;
}