Commit 09dd71d7 authored by Florian Schmaus's avatar Florian Schmaus
Browse files

Merge branch 'fix-alarmfuture-stats' into 'master'

[io/Stats] For AlarmFutures (TIMEOUT) expect them to return ETIME

See merge request i4/manycore/emper!402
parents 1f15cf55 c84929e9
Pipeline #84165 passed with stages
in 31 minutes and 49 seconds
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020-2021 Florian Fischer, Florian Schmaus
// Copyright © 2020-2022 Florian Fischer, Florian Schmaus
#include "io/Stats.hpp"
#include <cerrno>
#include <cstdlib>
#include <initializer_list> // for initializer_list
#include <iomanip> // for operator<<, setfill, setw
#include <string> // for operator<<, to_string
#include <utility> // for pair
#include "Debug.hpp"
#include "Future.hpp"
#include "io/IoContext.hpp"
#include "io/Operation.hpp" // for Operation, operator<<, Operation::RECV
#include "lib/math.hpp"
......@@ -119,6 +123,61 @@ auto operator<<(std::ostream& os, const Stats& s) -> std::ostream& {
return os;
}
void Stats::record_completion(Operation op, int32_t res, ssize_t partial_completion, size_t exp) {
auto& operation_map = io_uring_completions[op];
// Persistent Error
if (res < 0) {
if (partial_completion > 0) {
ATOMIC_INC_RELAXED(operation_map[IncrementalError]);
} else {
ATOMIC_INC_RELAXED(operation_map[ErrorCompletion]);
}
return;
}
// Make sure exp which is passed as future.len is only > 0 for Futures with a buffer
switch (op) {
case Operation::SEND:
case Operation::RECV:
case Operation::READ:
case Operation::WRITE:
case Operation::WRITEV:
break;
case Operation::TIMEOUT:
exp = ETIME;
break;
default:
exp = 0;
break;
}
// Full completion
if (!exp || (uint32_t)res == exp) {
ATOMIC_INC_RELAXED(operation_map[FullCompletion]);
return;
}
// we expect partial completion
if (partial_completion != PartialCompletableFuture::DISABLE_PARTIAL_COMPLETION) {
if ((size_t)(res + partial_completion) < exp) {
ATOMIC_INC_RELAXED(operation_map[PartialResubmission]);
} else {
ATOMIC_INC_RELAXED(operation_map[IncrementalCompletion]);
}
return;
}
if ((uint32_t)res < exp) {
ATOMIC_INC_RELAXED(operation_map[PartialCompletion]);
return;
}
LOGW("Unexpected completion case in IoStats");
LOGW(op << ", " << res << ", " << partial_completion << ", " << exp);
abort();
}
void Stats::printStats(IoContext* globalIoContext, const std::vector<IoContext*>& workerIoContexts,
std::ostream& out) {
if (globalIoContext) {
......
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020-2021 Florian Fischer, Florian Schmaus
// Copyright © 2020-2022 Florian Fischer, Florian Schmaus
#pragma once
#include <bits/types/struct_iovec.h> // for iovec
#include <sys/types.h> // for ssize_t
......@@ -8,13 +8,11 @@
#include <chrono> // for nanoseconds
#include <cstddef> // for size_t
#include <cstdint> // for uint64_t, int32_t, uint32_t
#include <cstdlib> // for abort
#include <iostream> // for operator<<, basic_ostream, basi...
#include <map> // for map, map<>::value_compare
#include <vector>
#include "CallerEnvironment.hpp"
#include "Debug.hpp" // for LOGW
#include "Emper.hpp" // for STATS
#include "emper-common.h" // for workerid_t
#include "io/Future.hpp" // for PartialCompletableFuture, Write...
......@@ -156,57 +154,7 @@ class Stats {
exp);
}
void record_completion(Operation op, int32_t res, ssize_t partial_completion, size_t exp) {
auto& operation_map = io_uring_completions[op];
// Persistent Error
if (res < 0) {
if (partial_completion > 0) {
ATOMIC_INC_RELAXED(operation_map[IncrementalError]);
} else {
ATOMIC_INC_RELAXED(operation_map[ErrorCompletion]);
}
return;
}
// Make sure exp which is passed as future.len is only > 0 for Futures with a buffer
switch (op) {
case Operation::SEND:
case Operation::RECV:
case Operation::READ:
case Operation::WRITE:
case Operation::WRITEV:
break;
default:
exp = 0;
break;
}
// Full completion
if (!exp || (uint32_t)res == exp) {
ATOMIC_INC_RELAXED(operation_map[FullCompletion]);
return;
}
// we expect partial completion
if (partial_completion != PartialCompletableFuture::DISABLE_PARTIAL_COMPLETION) {
if ((size_t)(res + partial_completion) < exp) {
ATOMIC_INC_RELAXED(operation_map[PartialResubmission]);
} else {
ATOMIC_INC_RELAXED(operation_map[IncrementalCompletion]);
}
return;
}
if ((uint32_t)res < exp) {
ATOMIC_INC_RELAXED(operation_map[PartialCompletion]);
return;
}
LOGW("Unexpected completion case in IoStats");
LOGW(op << ", " << res << ", " << partial_completion << ", " << exp);
abort();
}
void record_completion(Operation op, int32_t res, ssize_t partial_completion, size_t exp);
// running mean calculation taken from
// https://math.stackexchange.com/questions/106700/incremental-averageing
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment