Skip to content

Commit 20ac6fa

Browse files
committed
Add socket class with reusable state for benchmarks
1 parent b6578ab commit 20ac6fa

File tree

2 files changed

+55
-40
lines changed

2 files changed

+55
-40
lines changed

test/unit/bench.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,8 @@ struct bench_test
343343

344344
test_suite::log << "\n";
345345

346+
co::socket sock;
347+
346348
// 1 level
347349
bench("async_io native: ", native,
348350
[](auto ex, auto h){ async_io(ex, std::move(h)); });
@@ -351,7 +353,7 @@ struct bench_test
351353
bench("any_io any_all: ", any,
352354
[](auto ex, auto h){ any_io(std::move(ex), std::move(h)); });
353355
bench_co("co::async_io coro: ",
354-
[](int& count) -> co::task { co_await co::async_io; ++count; });
356+
[&](int& count) -> co::task { co_await sock.async_io(); ++count; });
355357

356358
test_suite::log << "\n";
357359

@@ -363,7 +365,7 @@ struct bench_test
363365
bench("any_read_some any_all: ", any,
364366
[](auto ex, auto h){ any_read_some(std::move(ex), std::move(h)); });
365367
bench_co("co::read_some coro: ",
366-
[](int& count) -> co::task { co_await co::async_read_some(); ++count; });
368+
[&](int& count) -> co::task { co_await async_read_some(sock); ++count; });
367369

368370
test_suite::log << "\n";
369371

@@ -375,7 +377,7 @@ struct bench_test
375377
bench("any_read any_all: ", any,
376378
[](auto ex, auto h){ any_read(std::move(ex), std::move(h)); });
377379
bench_co("co::read coro: ",
378-
[](int& count) -> co::task { co_await co::async_read(); ++count; });
380+
[&](int& count) -> co::task { co_await async_read(sock); ++count; });
379381

380382
test_suite::log << "\n";
381383

@@ -387,7 +389,7 @@ struct bench_test
387389
bench("any_request any_all: ", any,
388390
[](auto ex, auto h){ any_request(std::move(ex), std::move(h)); });
389391
bench_co("co::request coro: ",
390-
[](int& count) -> co::task { co_await co::async_request(); ++count; });
392+
[&](int& count) -> co::task { co_await co::async_request(sock); ++count; });
391393
}
392394
};
393395

test/unit/model_coro.hpp

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <concepts>
1414
#include <coroutine>
1515
#include <exception>
16+
#include <memory>
1617

1718
namespace boost {
1819
namespace capy {
@@ -160,48 +161,60 @@ struct executor_ref
160161

161162
//----------------------------------------------------------
162163

163-
struct async_io_t
164+
struct socket
164165
{
165-
bool await_ready() const noexcept { return false; }
166-
void await_resume() const noexcept {}
166+
struct async_awaitable
167+
{
168+
async_awaitable(socket& s) : s_(s) {}
169+
bool await_ready() const noexcept { return false; }
170+
void await_resume() const noexcept {}
167171

168-
// Affine overload: receives dispatcher from caller
169-
template<class Executor>
170-
void await_suspend(coro h, Executor const& ex) const
172+
// Affine overload: receives dispatcher from caller
173+
template<class Executor>
174+
void await_suspend(coro h, Executor const& ex) const
175+
{
176+
s_.perform(h, executor_ref(ex));
177+
}
178+
179+
private:
180+
socket& s_;
181+
};
182+
183+
socket()
184+
: op_(new state)
185+
{
186+
}
187+
188+
// Asynchronous operation that wraps OS-level I/O
189+
async_awaitable async_io()
171190
{
172-
auto p = make_state(h, executor_ref(ex));
173-
ex.post(p); // simulate OS call
191+
return async_awaitable(*this);
174192
}
175193

176194
private:
177-
// this goes in the TU
178-
static work* make_state(coro h, executor_ref ex)
195+
struct state : work
179196
{
180-
struct state : work
181-
{
182-
coro h_;
183-
executor_ref ex_;
184-
state(coro h, executor_ref ex)
185-
: h_(h), ex_(ex)
186-
{
187-
}
197+
coro h_;
198+
executor_ref ex_;
188199

189-
void operator()() override
190-
{
191-
auto h = h_;
192-
auto ex = ex_;
193-
delete this;
194-
ex.dispatch(h);
195-
}
200+
void operator()() override
201+
{
202+
ex_.dispatch(h_);
203+
}
196204

197-
// OVERLAPPED, HANDLE, etc
198-
};
199-
return new state{ h, ex };
205+
// OVERLAPPED, HANDLE, etc
206+
};
207+
208+
void perform(coro h, executor_ref const& ex)
209+
{
210+
op_->h_ = h;
211+
op_->ex_ = ex;
212+
ex.post(op_.get()); // simulate OS call
200213
}
214+
215+
std::unique_ptr<state> op_;
201216
};
202217

203-
// Asynchronous operation that wraps OS-level I/O
204-
inline constexpr async_io_t async_io{};
205218

206219
//----------------------------------------------------------
207220

@@ -420,20 +433,20 @@ void async_run(Executor ex, task t)
420433

421434
//----------------------------------------------------------
422435

423-
inline task async_read_some()
436+
inline task async_read_some(socket& sock)
424437
{
425-
co_await async_io;
438+
co_await sock.async_io();
426439
}
427440

428-
inline task async_read()
441+
inline task async_read(socket& sock)
429442
{
430-
co_await async_read_some();
443+
co_await async_read_some(sock);
431444
}
432445

433-
inline task async_request()
446+
inline task async_request(socket& sock)
434447
{
435448
for(int i = 0; i < 100; ++i)
436-
co_await async_read();
449+
co_await async_read(sock);
437450
}
438451

439452
} // co

0 commit comments

Comments
 (0)