Skip to content
Snippets Groups Projects
Commit 83d9fb46 authored by Florian Schmaus's avatar Florian Schmaus
Browse files

Merge branch 'deprecate-submit-broken-link-logic' into 'master'

Deprecate IoContext submit broken chain logic

See merge request i4/manycore/emper!248
parents 83ce678a 3fb3892b
No related branches found
No related tags found
No related merge requests found
......@@ -15,6 +15,7 @@
#include "emper-version.h"
#include "emper.hpp"
#include "io/Future.hpp"
#include "lib/LinuxVersion.hpp"
void async(Fiber* fiber) {
assert(fiber != nullptr);
......@@ -44,6 +45,8 @@ void async(const Fiber::fiber_fun0_t& function, workeraffinity_t* affinity) {
namespace emper {
bool IO_MUST_INVALIDATE_BROKEN_CHAIN = EMPER_LINUX_LT("5.15.0");
auto getFullVersion() -> std::string { return EMPER_FULL_VERSION; }
static void ensure_no_current_runtime() {
......
......@@ -130,6 +130,16 @@ static const bool IO_URING_SQPOLL =
#endif
;
// Initialize this bool in Emper.cpp because it needs code evaluation
// (LinuxVersion::compare) during runtime.
// Using a static variable here means EACH object file including this header has to
// evaluate the needed code during library initialization.
// An extern variable results in a single execution during initialization of the
// Emper.cpp object.
// This also has the advantage that the probability we crash because printing
// warnings during the comparison use not yet initialized components is reduced.
extern bool IO_MUST_INVALIDATE_BROKEN_CHAIN;
static const bool IO_URING_SHARED_WQ =
#ifdef EMPER_IO_URING_SHARED_WQ
true
......
......@@ -197,7 +197,14 @@ void IoContext::submitAndWait(Future &future, unsigned wait_nr) {
// broken chains. This means that all sqes in a chain except the broken one will
// result in cqes with result -ECANCELD and the invalid one will
// generate a cqe with the appropriate error code
if (unlikely(static_cast<unsigned>(submitted) < prepared)) {
// When 5.15 is released with
// https://lore.kernel.org/io-uring/180ec124-79b1-2274-4570-9b0d6620d512@linux.alibaba.com/T/#t
// the kernel will consume the whole broken chain and we
// don't need to manually invalidate not submitted sqes.
// This allows SQPOLL to work for invalid chains.
if (unlikely(static_cast<unsigned>(submitted) < prepared) &&
emper::IO_MUST_INVALIDATE_BROKEN_CHAIN) {
cancelUnsubmittedChainParts<callerEnvironment>(future);
}
......
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Fischer
#include "lib/LinuxVersion.hpp"
#include <cassert>
#include <cerrno>
#include <cstdlib>
#include "Common.hpp"
#include "Debug.hpp"
static auto checked_strtol(const std::string& s) -> long {
static const int DECIMAL = 10;
char* endptr;
const char* startptr = s.c_str();
errno = 0;
long res = strtol(startptr, &endptr, DECIMAL);
if (errno != 0) {
DIE_MSG_ERRNO("strtol failed");
}
if (endptr == startptr) {
DIE_MSG("strtol found no digits in " << s);
}
if (endptr != startptr + s.size()) {
LOGW("LinuxVersion compare ignored non digits in " << s)
}
return res;
}
namespace emper::lib {
LinuxVersion LinuxVersion::linuxVersion;
// Returns 1 if s is smaller, -1 if this is smaller, 0 if equal
auto LinuxVersion::compare(const std::string& s) -> int {
size_t last_dot_pos = 0, last_dot_pos2 = 0;
for (;;) {
size_t dot_pos = this->version.find('.', last_dot_pos);
// We run out of parts to compare the versions must be equal
if (dot_pos == std::string::npos) return 0;
size_t dot_pos2 = s.find('.', last_dot_pos2);
assert(dot_pos2 != std::string::npos);
long n1 = checked_strtol(this->version.substr(last_dot_pos, dot_pos - last_dot_pos));
long n2 = checked_strtol(s.substr(last_dot_pos2, dot_pos2 - last_dot_pos2));
if (n1 > n2) return 1;
if (n1 < n2) return -1;
last_dot_pos = dot_pos + 1;
last_dot_pos2 = dot_pos2 + 1;
}
}
} // namespace emper::lib
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Fischer
#pragma once
#include <sys/utsname.h>
#include <string>
namespace emper::lib {
class LinuxVersion {
std::string version;
auto compare(const std::string& s) -> int;
public:
static LinuxVersion linuxVersion;
LinuxVersion() {
struct utsname buf;
uname(&buf);
this->version = std::string(buf.release);
}
auto operator>(const std::string& s) -> bool { return compare(s) > 0; }
auto operator<(const std::string& s) -> bool { return compare(s) < 0; }
auto operator==(const std::string& s) -> bool { return compare(s) == 0; }
auto operator>=(const std::string& s) -> bool { return *this > s || *this == s; }
auto operator<=(const std::string& s) -> bool { return *this < s || *this == s; }
};
} // namespace emper::lib
#define EMPER_LINUX_EQ(version) \
([]() -> bool { return empere::lib::LinuxVersion::linuxVersion == version; }())
#define EMPER_LINUX_GT(version) \
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion > version; }())
#define EMPER_LINUX_GE(version) \
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion >= version; }())
#define EMPER_LINUX_LT(version) \
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion < version; }())
#define EMPER_LINUX_LE(version) \
([]() -> bool { return emper::lib::LinuxVersion::linuxVersion <= version; }())
emper_cpp_sources += files(
'DebugUtil.cpp',
'LinuxVersion.cpp',
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment