StaticThreadPipeline

This commit is contained in:
2025-08-26 15:13:16 -04:00
parent 0b63e24b98
commit 6dbf29d1e1
4 changed files with 244 additions and 321 deletions

View File

@@ -64,33 +64,47 @@ struct HttpConnectionState {
*/
struct HttpHandler : ConnectionHandler {
HttpHandler() {
for (int threadId = 0; threadId < kFinalStageThreads; ++threadId) {
finalStageThreads.emplace_back([this, threadId]() {
pthread_setname_np(pthread_self(),
("stage-1-" + std::to_string(threadId)).c_str());
for (;;) {
auto guard = pipeline.acquire(1, threadId);
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
if ((it.index() % kFinalStageThreads) == threadId) {
auto &c = *it;
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "pipeline thread",
perfetto::Flow::Global(state->request_id));
Server::release_back_to_server(std::move(c));
finalStageThreads.emplace_back([this]() {
pthread_setname_np(pthread_self(), "stage-1-0");
for (;;) {
auto guard = pipeline.acquire<1, 0>();
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
if ((it.index() % 2) == 0) { // Thread 0 handles even indices
auto &c = *it;
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "release",
perfetto::Flow::Global(state->request_id));
Server::release_back_to_server(std::move(c));
}
}
});
}
}
});
finalStageThreads.emplace_back([this]() {
pthread_setname_np(pthread_self(), "stage-1-1");
for (;;) {
auto guard = pipeline.acquire<1, 1>();
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
if ((it.index() % 2) == 1) { // Thread 1 handles odd indices
auto &c = *it;
if (!c) {
return;
}
auto *state = static_cast<HttpConnectionState *>(c->user_data);
TRACE_EVENT("http", "release",
perfetto::Flow::Global(state->request_id));
Server::release_back_to_server(std::move(c));
}
}
}
});
stage0Thread = std::thread{[this]() {
pthread_setname_np(pthread_self(), "stage-0");
for (;;) {
auto guard = pipeline.acquire(0, 0, 0, false);
for (auto it = guard.batch.begin(); it != guard.batch.end(); ++it) {
auto &c = *it;
auto guard = pipeline.acquire<0, 0>();
for (auto &c : guard.batch) {
if (!c) {
return;
}
@@ -102,7 +116,7 @@ struct HttpHandler : ConnectionHandler {
}
~HttpHandler() {
{
auto guard = pipeline.push(kFinalStageThreads, true);
auto guard = pipeline.push(2, true);
for (auto &c : guard.batch) {
c = {};
}
@@ -137,8 +151,9 @@ struct HttpHandler : ConnectionHandler {
private:
static constexpr int kFinalStageThreads = 2;
static constexpr int kLogSize = 12;
ThreadPipeline<std::unique_ptr<Connection>> pipeline{
kLogSize, {/*noop serial thread*/ 1, kFinalStageThreads}};
StaticThreadPipeline<std::unique_ptr<Connection>,
WaitStrategy::WaitIfStageEmpty, 1, 2>
pipeline{kLogSize};
std::thread stage0Thread;
std::vector<std::thread> finalStageThreads;