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

DRAFT/WIP [stats] blocked contexts

parent 6bded656
No related branches found
No related tags found
No related merge requests found
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020 Florian Schmaus
// Copyright © 2020-2021 Florian Schmaus
#pragma once
#include <atomic> // for atomic
#include "BlockabePurpose.hpp"
#include "PrivateSemaphore.hpp" // for PrivateSemaphore
class Context;
class BinaryPrivateSemaphore final : public PrivateSemaphore {
template <emper::BlockablePurpose blockablePurpose = emper::BlockablePurpose::GENERIC>
class BinaryPrivateSemaphore final : public PrivateSemaphore<blockablePurpose> {
private:
enum State {
initial,
......
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020 Florian Schmaus
// Copyright © 2020-2021 Florian Schmaus
#pragma once
#include <utility>
#include "BlockablePurpose.hpp"
#include "CallerEnvironment.hpp"
#include "Common.hpp"
#include "Context.hpp"
......@@ -11,11 +12,12 @@
#include "Debug.hpp"
#include "Emper.hpp"
#include "Runtime.hpp"
#include "RuntimeWorkerStats.hpp"
#include "lib/adt/LockedSet.hpp"
static emper::lib::adt::LockedSet<Context*> blockedContexts;
template <LogSubsystem logSubsystem>
template <LogSubsystem logSubsystem, emper::BlockablePurpose blockablePurpose = emper::BlockablePurpose::GENERIC>
class Blockable : public Logger<logSubsystem> {
protected:
Runtime& runtime;
......@@ -33,7 +35,7 @@ class Blockable : public Logger<logSubsystem> {
Blockable(Runtime& runtime) : runtime(runtime), contextManager(runtime.getContextManager()) {}
void maybeSetAffinity() {
if constexpr (!emper::SET_AFFINITY_ON_BLOCK) return;
if constexpr (!emper::SET_AFFINITY_ON_BLOCK && !emper::STATS) return;
// TODO: At some point we may want to have something like
// Runtime::isAffinityCapable() and return here if it is
......@@ -61,8 +63,19 @@ class Blockable : public Logger<logSubsystem> {
maybeSetAffinity();
auto blockedContextSize = 0;
if constexpr (emper::BLOCKED_CONTEXT_SET) {
blockedContexts.insert(Context::getCurrentContext());
auto* currentContext = Context::getCurrentContext();
if constexpr (emper::STATS) {
blockedContextSize = blockedContexts.insertAndGetSize(currentContext);
} else {
blockedContexts.insert(currentContext);
}
}
if constexpr (emper::STATS) {
rtwStats->recordBlockedContext(blockedContextSize);
}
contextManager.saveAndStartNew(std::move(freshContextHook));
......@@ -74,6 +87,10 @@ class Blockable : public Logger<logSubsystem> {
blockedContexts.erase(context);
}
if constexpr (emper::STATS) {
stats.recordUnblockedContext(*affinity);
}
return Fiber::from([this, context]() { contextManager.discardAndResume(context); }, affinity);
}
......
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Schmaus
#pragma once
namespace emper {
enum BlockablePurpose {
GENERIC,
IO,
};
}
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020 Florian Schmaus
// Copyright © 2020-2021 Florian Schmaus
#pragma once
#include "Blockable.hpp"
#include "BlockablePurpose.hpp"
#include "CallerEnvironment.hpp"
#include "Context.hpp"
#include "ContextManager.hpp"
......@@ -11,7 +12,8 @@
#include "Fiber.hpp"
#include "Runtime.hpp"
class PrivateSemaphore : protected Blockable<LogSubsystem::PS> {
template <emper::BlockablePurpose blockablePurpose = emper::BlockablePurpose::GENERIC>
class PrivateSemaphore : protected Blockable<LogSubsystem::PS, blockablePurpose> {
protected:
// cppcheck-suppress uninitMemberVar
PrivateSemaphore() : Blockable(*Runtime::getRuntime()) {
......
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Schmaus
#include "RuntimeWorkerStats.hpp"
#include <algorithm>
using namespace emper;
thread_local RuntimeWorkerStats* rtwStats;
RuntimeWorkerStats::RuntimeWorkerStats(workerid_t workerCount)
: unblockAffinitiesGeneric(std::vector<uint32_t>(workerCount)),
unblockAffinitiesIo(std::vector<uint32_t>(workerCount)) {
}
void RuntimeWorkerStats::recordBlockedContext(size_t blockedContextSize, BlockablePurpose blockablePurpose) {
maxBlockedContexts = std::max(maxBlockedContexts, blockedContextSize);
switch (blockablePurpose) {
case BlockablePurpose::GENERIC:
blockedGeneric++;
break;
case BlockablePurpose::IO:
blockedIo++;
break;
}
}
void RuntimeWorkerStats::recordUnblockedContext(workeraffinity_t workerAffinity, BlockabelPurpose blockablePurpose) {
switch (blockablePurpose) {
case BlockabelPurpose::GENERIC:
unblockAffinitiesGeneric(workerAffinity)++;
break;
case BlockablePurpose::IO:
unblockAffinitiesIo(workerAffinity)++;
break;
}
}
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2021 Florian Schmaus
#pragma once
#include <vector>
#include "BlockablePurpose.hpp"
#include "emper-common.h"
namespace emper {
thread_local RuntimeWorkerStats* rtwStats;
class RuntimeWorkerStats {
private:
size_t maxBlockedContexts = 0;
uint32_t blockedGeneric = 0;
std::vector<uint32_t> unblockAffinitiesGeneric;
uint32_t blockedIo = 0;
std::vector<uint32_t> unblockAffinitiesIo;
RuntimeWorkerStats(workerid_t workerCount);
void recordBlockedContext(size_t blockedContextSize, BlockablePurpose blockablePurpose);
void recordUnblockedContext(workeraffinity_t workerAffinty, BlockablePurpose blockablePurpose);
};
}
......@@ -17,6 +17,7 @@
#include <utility>
#include "BinaryPrivateSemaphore.hpp" // for BPS
#include "BlockablePurpose.hpp"
#include "CallerEnvironment.hpp" // for CallerEnvironment, ANYWHERE
#include "Common.hpp"
#include "Debug.hpp" // for LOGD, LogSubsystem, LogSubsyst...
......@@ -71,7 +72,7 @@ class Future : public Logger<LogSubsystem::IO> {
0; /*!< This Future does not care about the result of the IO operation */
};
BPS sem;
BPS<BlockablePurpose::IO> sem;
State state;
......
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright © 2020 Florian Fischer
// Copyright © 2020 Florian Fischer, 2021 Florian Schmaus
#pragma once
#include <iterator>
......@@ -12,9 +12,17 @@ template <class Key, class Compare = std::less<Key>, class Allocator = std::allo
class LockedSet {
private:
std::mutex _mutex;
std::set<Key, Compare, Allocator> _set;
set_type _set;
public:
typedef std::set<Key, Compare, Allocator> set_type;
auto insert(const Key& item) -> set_type::size_type {
std::lock_guard<std::mutex> lock(_mutex);
_set.insert(item);
return _set.size();
}
auto insert(const Key& item)
-> std::pair<typename std::set<Key, Compare, Allocator>::iterator, bool> {
std::lock_guard<std::mutex> lock(_mutex);
......
......@@ -14,6 +14,7 @@ emper_config_header = configure_file(output: 'emper-config.h',
emper_cpp_sources = [
'Runtime.cpp',
'RuntimeWorkerStats.cpp',
'Emper.cpp',
'Fiber.cpp',
'FiberManager.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