From f48f3822146083ba78c28c5928388dd4d8901029 Mon Sep 17 00:00:00 2001 From: Florian Schmaus <flow@cs.fau.de> Date: Thu, 5 Nov 2020 09:02:01 +0100 Subject: [PATCH] [codestyle] Add check-format target and apply codestyle to codebase --- .clang-format | 5 + .editorconfig | 12 ++ Makefile | 9 +- apps/Main.cpp | 19 +- apps/WorkerSleepExample.cpp | 36 ++-- emper/Actor.hpp | 44 ++--- emper/BinaryPrivateSemaphore.cpp | 26 +-- emper/BinaryPrivateSemaphore.hpp | 13 +- emper/Blockable.hpp | 23 +-- emper/Common.cpp | 7 +- emper/Common.hpp | 4 +- emper/Context.cpp | 22 +-- emper/Context.hpp | 43 ++--- emper/ContextManager.cpp | 8 +- emper/ContextManager.hpp | 10 +- emper/CountingPrivateSemaphore.cpp | 37 ++-- emper/CountingPrivateSemaphore.hpp | 9 +- emper/Debug.cpp | 4 +- emper/Debug.hpp | 145 ++++++++------ emper/Dispatcher.cpp | 10 +- emper/Dispatcher.hpp | 24 +-- emper/Fiber.cpp | 15 +- emper/Fiber.hpp | 73 +++---- emper/FiberManager.cpp | 7 +- emper/FiberManager.hpp | 8 +- emper/MemoryManager.hpp | 37 ++-- emper/PrivateSemaphore.hpp | 23 +-- emper/Runtime.cpp | 46 ++--- emper/Runtime.hpp | 48 ++--- emper/RuntimeStrategy.hpp | 7 +- emper/RuntimeStrategyStats.hpp | 5 +- emper/Scheduler.cpp | 11 +- emper/Scheduler.hpp | 16 +- emper/Semaphore.cpp | 4 +- emper/Semaphore.hpp | 9 +- emper/SynchronizedFiber.hpp | 47 +++-- emper/UnboundedBlockingMpscQueue.hpp | 32 ++- emper/c_emper.cpp | 29 ++- emper/include/emper.h | 42 ++-- emper/include/emper.hpp | 5 +- emper/lib/DebugUtil.cpp | 2 +- emper/lib/adt/BoundedBumpArray.hpp | 24 +-- emper/lib/adt/LockedQueue.hpp | 71 ++++--- emper/lib/adt/LockedUnboundedQueue.hpp | 42 ++-- emper/lib/adt/MpscQueue.hpp | 8 +- emper/lib/adt/WsClQueue.hpp | 40 ++-- emper/lib/adt/WsClV2Queue.hpp | 48 ++--- emper/lib/sync/Latch.hpp | 7 +- emper/lib/sync/Semaphore.hpp | 15 +- emper/strategies/laws/LawsDispatcher.cpp | 37 ++-- emper/strategies/laws/LawsDispatcher.hpp | 23 +-- emper/strategies/laws/LawsScheduler.cpp | 14 +- emper/strategies/laws/LawsScheduler.hpp | 32 ++- emper/strategies/laws/LawsStrategy.hpp | 35 ++-- emper/strategies/laws/LawsStrategyStats.cpp | 41 ++-- emper/strategies/laws/LawsStrategyStats.hpp | 10 +- emper/strategies/ws/WsDispatcher.cpp | 4 +- emper/strategies/ws/WsDispatcher.hpp | 7 +- emper/strategies/ws/WsScheduler.cpp | 12 +- emper/strategies/ws/WsScheduler.hpp | 22 +-- emper/strategies/ws/WsStrategy.cpp | 2 +- emper/strategies/ws/WsStrategy.hpp | 20 +- emper/strategies/ws/WsStrategyStats.cpp | 29 ++- emper/strategies/ws/WsStrategyStats.hpp | 10 +- eval/Locality.cpp | 204 ++++++++++---------- eval/SpawnALot.cpp | 120 +++++------- eval/TimeToSpawn.cpp | 47 ++--- tests/CppApiTest.cpp | 9 +- tests/SimpleActorTest.cpp | 48 +++-- tests/SimpleFibTest.cpp | 26 +-- tests/SimpleLawsTest.cpp | 35 ++-- tests/SimplestFibTest.cpp | 25 +-- tests/c_api_test.c | 4 +- tools/check-format | 51 +++++ 74 files changed, 969 insertions(+), 1129 deletions(-) create mode 100644 .clang-format create mode 100644 .editorconfig create mode 100755 tools/check-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..5f8df3c8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,5 @@ +--- +BasedOnStyle: Google +ColumnLimit: 100 +TabWidth: 2 +UseTab: Always diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..8cfde3d9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +# top-most EditorConfig file +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +end_of_line = lf +insert_final_newline = true + +[*.{c,h,cpp,hpp}] +indent_style = tab +indent_size = 2 diff --git a/Makefile b/Makefile index 00ade082..00aac72a 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ -.PHONY: all build check clean distclean doc release debug stresstest test - SHELL = bash +.PHONY: all build check check-format clean distclean\ + doc release debug stresstest test + all: build export BUILDTYPE ?= debugoptimized @@ -23,7 +24,7 @@ debug: $(MAKE) build BUILDTYPE=$@ -smoke-test: all +smoke-test: all check-format cd build && meson test --suite smoke @@ -46,6 +47,8 @@ distclean: clean ./scripts/versionManager.sh -v clean git clean -x -d -f +check-format: + ./tools/check-format stresstest: test ./stresstest/stresstest.sh build/tests/simplest_fib_test diff --git a/apps/Main.cpp b/apps/Main.cpp index 367a2ce0..42d1e102 100644 --- a/apps/Main.cpp +++ b/apps/Main.cpp @@ -1,16 +1,17 @@ #include <stdio.h> #include <stdlib.h> + #include <iostream> #include <list> #include <string> #include <thread> -#include "Runtime.hpp" -#include "Common.hpp" -#include "PrivateSemaphore.hpp" #include "BinaryPrivateSemaphore.hpp" +#include "Common.hpp" #include "CountingPrivateSemaphore.hpp" #include "Debug.hpp" +#include "PrivateSemaphore.hpp" +#include "Runtime.hpp" typedef struct { int n; @@ -18,10 +19,10 @@ typedef struct { PS* sem; } fibParams; -static void fib(void *voidParams) { +static void fib(void* voidParams) { fibParams* params = static_cast<fibParams*>(voidParams); int n = params->n; - int *result = params->result; + int* result = params->result; PS* sem = params->sem; if (n < 2) { @@ -61,7 +62,7 @@ static void fibKickoff() { const int fibNum = 4; int result; BPS sem; - fibParams params = { fibNum, &result, &sem }; + fibParams params = {fibNum, &result, &sem}; fib(¶ms); @@ -71,8 +72,8 @@ static void fibKickoff() { exit(EXIT_SUCCESS); } -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { - //const unsigned nthreads = std::thread::hardware_concurrency(); +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { + // const unsigned nthreads = std::thread::hardware_concurrency(); const unsigned nthreads = 2; std::cout << "Number of threads: " << nthreads << std::endl; @@ -86,6 +87,6 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { runtime.schedule(*fibFiber); runtime.waitUntilFinished(); - + return 0; } diff --git a/apps/WorkerSleepExample.cpp b/apps/WorkerSleepExample.cpp index 9e0b848c..093ac184 100644 --- a/apps/WorkerSleepExample.cpp +++ b/apps/WorkerSleepExample.cpp @@ -1,18 +1,18 @@ #include <stdio.h> #include <stdlib.h> + #include <iostream> #include <list> #include <string> -#include "Runtime.hpp" -#include "Common.hpp" -#include "PrivateSemaphore.hpp" #include "BinaryPrivateSemaphore.hpp" +#include "Common.hpp" #include "CountingPrivateSemaphore.hpp" #include "Debug.hpp" - -#include "emper.hpp" +#include "PrivateSemaphore.hpp" +#include "Runtime.hpp" #include "emper-version.h" +#include "emper.hpp" static unsigned int ITERATIONS = 10; @@ -20,30 +20,32 @@ static std::chrono::milliseconds SINGLE_FIBER_DURATION = std::chrono::millisecon static std::chrono::milliseconds MULTI_FIBER_DURATION = std::chrono::milliseconds(2000); -template<typename Rep, typename Period> +template <typename Rep, typename Period> static void letsGetBusy(std::chrono::duration<Rep, Period> duration) { - const std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now(); + const std::chrono::time_point<std::chrono::high_resolution_clock> now = + std::chrono::high_resolution_clock::now(); const std::chrono::time_point<std::chrono::high_resolution_clock> deadline = now + duration; - while (std::chrono::high_resolution_clock::now() < deadline); + while (std::chrono::high_resolution_clock::now() < deadline) + ; } static void alphaFiber() { const Runtime* runtime = Runtime::getRuntime(); const workerid_t workerCount = runtime->getWorkerCount(); - std::cout << "Starting WorkerSleepExample with " << workerCount << " workers using " << ITERATIONS << " iterations." << std::endl - << "Single fiber duration: " << SINGLE_FIBER_DURATION.count() << ", Multi fiber duration: " << MULTI_FIBER_DURATION.count() << std::endl - << "EMPER version: " << EMPER_FULL_VERSION << std::endl; - + std::cout << "Starting WorkerSleepExample with " << workerCount << " workers using " << ITERATIONS + << " iterations." << std::endl + << "Single fiber duration: " << SINGLE_FIBER_DURATION.count() + << ", Multi fiber duration: " << MULTI_FIBER_DURATION.count() << std::endl + << "EMPER version: " << EMPER_FULL_VERSION << std::endl; + for (unsigned int i = 0; i < ITERATIONS; ++i) { letsGetBusy(SINGLE_FIBER_DURATION); CPS cps; for (workerid_t j = 0; j < workerCount; ++j) { - spawn([] { - letsGetBusy(MULTI_FIBER_DURATION); - }, cps); + spawn([] { letsGetBusy(MULTI_FIBER_DURATION); }, cps); } cps.wait(); } @@ -52,7 +54,7 @@ static void alphaFiber() { exit(EXIT_SUCCESS); } -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { Runtime runtime; Fiber* fibFiber = Fiber::from(&alphaFiber); @@ -62,6 +64,6 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { runtime.schedule(*fibFiber); runtime.waitUntilFinished(); - + return 0; } diff --git a/emper/Actor.hpp b/emper/Actor.hpp index 4f08e7bc..e43fd9ed 100644 --- a/emper/Actor.hpp +++ b/emper/Actor.hpp @@ -1,16 +1,14 @@ #pragma once -#include "UnboundedBlockingMpscQueue.hpp" -#include "Fiber.hpp" - #include <atomic> #include <chrono> -template<typename T> -class Actor { - -private: +#include "Fiber.hpp" +#include "UnboundedBlockingMpscQueue.hpp" +template <typename T> +class Actor { + private: enum State { Stopped, Retrieving, @@ -19,7 +17,7 @@ private: Runtime& runtime; - std::atomic<State> state = { Stopped }; + std::atomic<State> state = {Stopped}; UnboundedBlockingMpscQueue<T> queue; @@ -27,9 +25,7 @@ private: return state.compare_exchange_strong(oldState, newState, std::memory_order_acq_rel); } - void setState(State newState) { - state.store(newState, std::memory_order_release); - } + void setState(State newState) { state.store(newState, std::memory_order_release); } void actorLoop() { setState(Running); @@ -41,26 +37,22 @@ private: } T t = queue.get([this] { - // Prevent lost stop() - switchState(Retrieving, Running); - }); + // Prevent lost stop() + switchState(Retrieving, Running); + }); receive(t); } } -protected: - - Actor(Runtime& runtime) : runtime(runtime), queue(runtime) { - } + protected: + Actor(Runtime& runtime) : runtime(runtime), queue(runtime) {} virtual void receive(T t) = 0; - void stop() { - setState(Stopped); - } + void stop() { setState(Stopped); } -public: + public: void start() { if (state.load(std::memory_order_acquire) != Stopped) return; @@ -68,13 +60,9 @@ public: runtime.schedule(*actorFiber); } - void tell(T t) { - queue.put(t); - } + void tell(T t) { queue.put(t); } - size_t pendingMailboxItems() { - return queue.size(); - } + size_t pendingMailboxItems() { return queue.size(); } bool waitUntilIdle(long timeout) { const auto start = std::chrono::steady_clock::now(); diff --git a/emper/BinaryPrivateSemaphore.cpp b/emper/BinaryPrivateSemaphore.cpp index e0f5f294..491e9e28 100644 --- a/emper/BinaryPrivateSemaphore.cpp +++ b/emper/BinaryPrivateSemaphore.cpp @@ -19,22 +19,22 @@ void BinaryPrivateSemaphore::wait() { // If the binary signal was not yet signaled, then we need to // block here. That is, we perform a full context switch. blockedContext = Context::getCurrentContext(); - assert(blockedContext > (Context*) 4096); + assert(blockedContext > (Context*)4096); block([this] { - // N.B. wait() will have set the blockedContext at this point. - State newState = blocked; - State previousState = bpsState.exchange(newState); - if (previousState == signaled) { + // N.B. wait() will have set the blockedContext at this point. + State newState = blocked; + State previousState = bpsState.exchange(newState); + if (previousState == signaled) { #ifndef NDEBUG - // Reset the real signal state only in debug - // builds. As it is not required to set the state here - // for the correctnes of the synchronization primitive. - newState = signaled; - bpsState.store(newState, std::memory_order_relaxed); + // Reset the real signal state only in debug + // builds. As it is not required to set the state here + // for the correctnes of the synchronization primitive. + newState = signaled; + bpsState.store(newState, std::memory_order_relaxed); #endif - unblock(blockedContext); - } - }); + unblock(blockedContext); + } + }); } Context* BinaryPrivateSemaphore::signalInternal() { diff --git a/emper/BinaryPrivateSemaphore.hpp b/emper/BinaryPrivateSemaphore.hpp index ad3f536e..1da3ee81 100644 --- a/emper/BinaryPrivateSemaphore.hpp +++ b/emper/BinaryPrivateSemaphore.hpp @@ -3,13 +3,11 @@ #include <atomic> #include "Debug.hpp" -#include "PrivateSemaphore.hpp" #include "Dispatcher.hpp" - -#include "Debug.hpp" +#include "PrivateSemaphore.hpp" class BinaryPrivateSemaphore : public PrivateSemaphore { -private: + private: enum State { initial, signaled, @@ -20,12 +18,11 @@ private: Context* blockedContext; -protected: + protected: Context* signalInternal() override; -public: - BinaryPrivateSemaphore() : bpsState(initial) { - } + public: + BinaryPrivateSemaphore() : bpsState(initial) {} void wait() override; }; diff --git a/emper/Blockable.hpp b/emper/Blockable.hpp index 2e9c6350..61935a31 100644 --- a/emper/Blockable.hpp +++ b/emper/Blockable.hpp @@ -1,24 +1,19 @@ #pragma once #include "Common.hpp" +#include "Context.hpp" +#include "ContextManager.hpp" #include "Debug.hpp" #include "Runtime.hpp" -#include "ContextManager.hpp" -#include "Context.hpp" - -template<LogSubsystem logSubsystem> -class Blockable : - public Logger<logSubsystem> { - -protected: +template <LogSubsystem logSubsystem> +class Blockable : public Logger<logSubsystem> { + protected: Runtime& runtime; ContextManager& contextManager; - Blockable(Runtime& runtime) : runtime(runtime), - contextManager(runtime.getContextManager()) { - } + Blockable(Runtime& runtime) : runtime(runtime), contextManager(runtime.getContextManager()) {} void block(func_t freshContextHook) { LOGD("block() blockedContext is " << Context::getCurrentContext()); @@ -28,10 +23,8 @@ protected: void unblock(Context* context) { assert(context != nullptr); // cppcheck-suppress unsafeClassCanLeak - Fiber* unblockFiber = Fiber::from([this, context]() { - contextManager.discardAndResume(context); - }); + Fiber* unblockFiber = + Fiber::from([this, context]() { contextManager.discardAndResume(context); }); runtime.schedule(*unblockFiber); } - }; diff --git a/emper/Common.cpp b/emper/Common.cpp index fadfeb29..3655e119 100644 --- a/emper/Common.cpp +++ b/emper/Common.cpp @@ -1,9 +1,10 @@ +#include "Common.hpp" + #include <stdio.h> + +#include <cstdio> #include <cstdlib> #include <iostream> -#include <cstdio> - -#include "Common.hpp" void die(const char* message, bool usePerror) { if (usePerror) { diff --git a/emper/Common.hpp b/emper/Common.hpp index 66363e09..1407b979 100644 --- a/emper/Common.hpp +++ b/emper/Common.hpp @@ -15,8 +15,8 @@ typedef std::function<void(void)> func_t; // We compile with -fno-exceptions for the moment. //#define THROW(x) do { throw std::runtime_error(x); } while (false) -#define likely(x) __builtin_expect(!!(x),1) -#define unlikely(x) __builtin_expect(!!(x),0) +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) #define ALIGN_TO_CACHE_LINE alignas(64) diff --git a/emper/Context.cpp b/emper/Context.cpp index 56fa0447..755a125d 100644 --- a/emper/Context.cpp +++ b/emper/Context.cpp @@ -4,17 +4,15 @@ thread_local Context* Context::currentContext; -std::ostream& operator<<(std::ostream &strm, const Context& context) { - strm << "Context " - << &context - << " [tos: " << context.tos - << " bos: " << &context.context - /* - << " alphaFunLoc=" << context.alphaFunctionIpLocation - << " alphaFunValue=" << *((uintptr_t*) context.alphaFunctionIpLocation) - << " main=" << context.mainFunction.target<void(void)>() - << " hook=" << context.startAndResumeHook.target<void(void)>() - */ - << "]"; +std::ostream& operator<<(std::ostream& strm, const Context& context) { + strm << "Context " << &context << " [tos: " << context.tos << " bos: " + << &context.context + /* + << " alphaFunLoc=" << context.alphaFunctionIpLocation + << " alphaFunValue=" << *((uintptr_t*) context.alphaFunctionIpLocation) + << " main=" << context.mainFunction.target<void(void)>() + << " hook=" << context.startAndResumeHook.target<void(void)>() + */ + << "]"; return strm; } diff --git a/emper/Context.hpp b/emper/Context.hpp index 582f5e05..28169b47 100644 --- a/emper/Context.hpp +++ b/emper/Context.hpp @@ -1,10 +1,10 @@ #pragma once +#include <valgrind/valgrind.h> + #include <cassert> -#include <functional> #include <cstring> - -#include <valgrind/valgrind.h> +#include <functional> #include "Common.hpp" #include "Debug.hpp" @@ -15,12 +15,12 @@ extern "C" [[noreturn]] void switch_and_load_context(void** toTos); // *Not* marked as 'noreturn' because save_and_switch_context does // *actually return at some point, unlike the other switch_* // *functions. -extern "C" void save_and_switch_context(void** toTos, void** fromTos); +extern "C" void save_and_switch_context(void** toTos, void** fromTos); extern "C" [[noreturn]] void switch_context(void** toTos); class ALIGN_TO_CACHE_LINE Context : Logger<LogSubsystem::C> { -private: - static const unsigned int CONTEXT_SIZE = 0xffff; // 1024 * 1024 * 4; + private: + static const unsigned int CONTEXT_SIZE = 0xffff; // 1024 * 1024 * 4; static thread_local Context* currentContext; @@ -52,13 +52,11 @@ private: context->mainFunction(); } -public: + public: // cppcheck-suppress noExplicitConstructor selfInitialization Context(func_t mainFunction) - // Align the Top-of-Stack (tos) to 16 byte. - : tos((void*) ( (uintptr_t) (context + CONTEXT_SIZE) & (~0xf) )) - , mainFunction(mainFunction) { - + // Align the Top-of-Stack (tos) to 16 byte. + : tos((void*)((uintptr_t)(context + CONTEXT_SIZE) & (~0xf))), mainFunction(mainFunction) { // valgrindStackId = VALGRIND_STACK_REGISTER(context, context + CONTEXT_SI); #ifndef NDEBUG @@ -68,7 +66,7 @@ public: void* res = memset(context, 0xcc, (char*)tos - context); if (!res) DIE; // Mark the last valid 16 bytes just below the top of stack. - res = memset(((uintptr_t*) tos) - 1, 0xab, sizeof(uintptr_t)); + res = memset(((uintptr_t*)tos) - 1, 0xab, sizeof(uintptr_t)); if (!res) DIE; // Mark the eventually existing unused top stack bytes res = memset(tos, 0xee, &context[CONTEXT_SIZE] - (char*)tos); @@ -85,7 +83,7 @@ public: alphaFunctionIpLocation = savedStackpointer = (uintptr_t*)tos - 2; void** alphaSavedIp = reinterpret_cast<void**>(savedStackpointer); - void(*f)() = &kickoff; + void (*f)() = &kickoff; assert(f != nullptr); *(alphaSavedIp) = reinterpret_cast<void*>(f); } @@ -93,21 +91,17 @@ public: ~Context() { // VALGRIND_STACK_DEREGISTER(valgrindStackId); } - + inline void setEmptyHook() { - startAndResumeHook = []() { }; + startAndResumeHook = []() {}; } - inline void setHook(func_t hook) { - startAndResumeHook = hook; - } + inline void setHook(func_t hook) { startAndResumeHook = hook; } - inline const void* getTos() const { - return tos; - } + inline const void* getTos() const { return tos; } /** - * Start this context. + * Start this context. */ [[noreturn]] inline void start() { LOGD("starting"); @@ -150,8 +144,5 @@ public: switch_and_load_context(&(context->savedStackpointer)); } - inline static Context* getCurrentContext() { - return currentContext; - } - + inline static Context* getCurrentContext() { return currentContext; } }; diff --git a/emper/ContextManager.cpp b/emper/ContextManager.cpp index 88a651c8..90627f00 100644 --- a/emper/ContextManager.cpp +++ b/emper/ContextManager.cpp @@ -2,9 +2,9 @@ #include <ostream> -#include "Runtime.hpp" -#include "Debug.hpp" #include "Context.hpp" +#include "Debug.hpp" +#include "Runtime.hpp" ContextManager::ContextManager(Runtime& runtime) : MemoryManager(runtime), runtime(runtime) { auto newWorkerHook = [this]() { @@ -61,8 +61,8 @@ void ContextManager::discardAndResume(Context* context) { Context* contextToFree = Context::getCurrentContext(); context->setHook([this, contextToFree] { - LOGD("Freeing context " << contextToFree); - putFreeContext(contextToFree); + LOGD("Freeing context " << contextToFree); + putFreeContext(contextToFree); }); contextToFree->discardAndResume(context); } diff --git a/emper/ContextManager.hpp b/emper/ContextManager.hpp index e62b8afa..529bdb66 100644 --- a/emper/ContextManager.hpp +++ b/emper/ContextManager.hpp @@ -10,14 +10,15 @@ class Context; #define CONTEXT_MANAGER_FIRST_LAYER_QUEUE_SIZE 64 -class ContextManager : public Logger<LogSubsystem::CM>, protected MemoryManager<Context, 128, CONTEXT_MANAGER_FIRST_LAYER_QUEUE_SIZE> { - -private: +class ContextManager + : public Logger<LogSubsystem::CM>, + protected MemoryManager<Context, 128, CONTEXT_MANAGER_FIRST_LAYER_QUEUE_SIZE> { + private: const Runtime& runtime; friend Context; -public: + public: ContextManager(Runtime& runtime); Context* getFreeContext(); @@ -29,5 +30,4 @@ public: void saveAndStartNew(func_t freshContextHook); [[noreturn]] void discardAndResume(Context* context); - }; diff --git a/emper/CountingPrivateSemaphore.cpp b/emper/CountingPrivateSemaphore.cpp index e611f8f5..e1e3fae6 100644 --- a/emper/CountingPrivateSemaphore.cpp +++ b/emper/CountingPrivateSemaphore.cpp @@ -2,33 +2,28 @@ #include <cassert> -CountingPrivateSemaphore::CountingPrivateSemaphore() : CountingPrivateSemaphore(0) { -} +CountingPrivateSemaphore::CountingPrivateSemaphore() : CountingPrivateSemaphore(0) {} -CountingPrivateSemaphore::CountingPrivateSemaphore(unsigned int counter) : counter(counter), blockedContext(nullptr) { -} +CountingPrivateSemaphore::CountingPrivateSemaphore(unsigned int counter) + : counter(counter), blockedContext(nullptr) {} -void CountingPrivateSemaphore::incrementCounterByOne() { - counter++; -} +void CountingPrivateSemaphore::incrementCounterByOne() { counter++; } -void CountingPrivateSemaphore::incrementCounter(unsigned int count) { - counter+=count; -} +void CountingPrivateSemaphore::incrementCounter(unsigned int count) { counter += count; } void CountingPrivateSemaphore::wait() { if (counter > 0) { Context* blockedContext = Context::getCurrentContext(); block([this, blockedContext] { - this->blockedContext = blockedContext; - assert(blockedContext > (Context*) 4096); - if (this->getCounter() == 0) { - Context* readyContext = this->blockedContext.exchange(nullptr); - if (readyContext != nullptr) { - unblock(readyContext); - } + this->blockedContext = blockedContext; + assert(blockedContext > (Context*)4096); + if (this->getCounter() == 0) { + Context* readyContext = this->blockedContext.exchange(nullptr); + if (readyContext != nullptr) { + unblock(readyContext); } - }); + } + }); } } @@ -38,16 +33,14 @@ Context* CountingPrivateSemaphore::signalInternal() { // If the counter is still non-zero after the decrement, somebody // else is responsible for scheduling the fiber. - if (oldCounter > 1) - return nullptr; - + if (oldCounter > 1) return nullptr; if (blockedContext.load() != nullptr && counter == 0) { // Try to swap out a blocked context, it is fine if this // returns nullptr. In this case the block() function will // have won the race. Context* context = blockedContext.exchange(nullptr); - assert(context > (Context*) 4096); + assert(context > (Context*)4096); return context; } diff --git a/emper/CountingPrivateSemaphore.hpp b/emper/CountingPrivateSemaphore.hpp index 40a994c3..ee90f8a0 100644 --- a/emper/CountingPrivateSemaphore.hpp +++ b/emper/CountingPrivateSemaphore.hpp @@ -8,20 +8,17 @@ * A counting private semaphore. */ class CountingPrivateSemaphore : public PrivateSemaphore { - -private: + private: std::atomic_uint counter; std::atomic<Context*> blockedContext; inline Context* signalInternal() override; -public: + public: CountingPrivateSemaphore(); explicit CountingPrivateSemaphore(unsigned int counter); - inline unsigned int getCounter() { - return counter.load(); - }; + inline unsigned int getCounter() { return counter.load(); }; void incrementCounterByOne(); diff --git a/emper/Debug.cpp b/emper/Debug.cpp index 9fd357d1..2d34fe58 100644 --- a/emper/Debug.cpp +++ b/emper/Debug.cpp @@ -1,7 +1,7 @@ #include "Debug.hpp" -#include <mutex> #include <iostream> +#include <mutex> #include "Common.hpp" #include "Runtime.hpp" @@ -12,7 +12,7 @@ void worker_log(const std::string& prefix, const std::string& message) { const workerid_t workerId = Runtime::getWorkerId(); std::unique_lock<std::mutex> lock(worker_log_mutex); - std::cerr << (unsigned int) workerId; + std::cerr << (unsigned int)workerId; if (!prefix.empty()) { std::cerr << " " << prefix << " "; } else { diff --git a/emper/Debug.hpp b/emper/Debug.hpp index 1ed5fd46..0d5a5db3 100644 --- a/emper/Debug.hpp +++ b/emper/Debug.hpp @@ -1,9 +1,9 @@ #pragma once +#include <cstdlib> #include <iostream> -#include <sstream> #include <map> -#include <cstdlib> +#include <sstream> #ifdef NDEBUG @@ -16,28 +16,59 @@ #include <sstream> -#define DBG(x) do { std::cerr << x << std::endl; } while (false) -#define WDBG(x) do { std::stringstream sst; sst << x; worker_log("", sst.str()); } while (false) +#define DBG(x) \ + do { \ + std::cerr << x << std::endl; \ + } while (false) +#define WDBG(x) \ + do { \ + std::stringstream sst; \ + sst << x; \ + worker_log("", sst.str()); \ + } while (false) // To avoid "error: there are no arguments to ‘logD’ that depend on a // template parameter, so a declaration of ‘logD’ must be available" // we use "this->logD()" instead of simply "logD()" below. -#define LOGD(x) do { std::stringstream sst; sst << x; this->logD(sst.str()); } while (false) -#define LOGDD(x) do { std::stringstream sst; sst << x; this->logDD(sst.str()); } while (false) +#define LOGD(x) \ + do { \ + std::stringstream sst; \ + sst << x; \ + this->logD(sst.str()); \ + } while (false) +#define LOGDD(x) \ + do { \ + std::stringstream sst; \ + sst << x; \ + this->logDD(sst.str()); \ + } while (false) #endif -#define LOGI(x) do { std::cerr << "Info: " << x << std::endl; } while (false) -#define LOGW(x) do { std::cerr << "Warning: " << x << std::endl; } while (false) -#define LOGE(x) do { std::cerr << "Error: " << x << std::endl; } while (false) - -#define ABORT(x) do { std::stringstream sst; sst << x; logI(sst.str()); abort(); } while (false) +#define LOGI(x) \ + do { \ + std::cerr << "Info: " << x << std::endl; \ + } while (false) +#define LOGW(x) \ + do { \ + std::cerr << "Warning: " << x << std::endl; \ + } while (false) +#define LOGE(x) \ + do { \ + std::cerr << "Error: " << x << std::endl; \ + } while (false) + +#define ABORT(x) \ + do { \ + std::stringstream sst; \ + sst << x; \ + logI(sst.str()); \ + abort(); \ + } while (false) #define IGNORE_UNUSED_FUNCTION \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") + _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#define POP_DIAGNOSTIC \ - _Pragma("GCC diagnostic pop") +#define POP_DIAGNOSTIC _Pragma("GCC diagnostic pop") enum class LogSubsystem { PS, @@ -64,55 +95,48 @@ enum LogLevel { void worker_log(const std::string& prefix, const std::string& message); static const std::map<LogSubsystem, LogLevel> LOG_CONFIG = { - { LogSubsystem::PS, ALL }, - { LogSubsystem::F, ALL }, - { LogSubsystem::C, ALL }, - { LogSubsystem::CM, ALL }, - { LogSubsystem::DISP, ALL }, - { LogSubsystem::SCHED, ALL }, - { LogSubsystem::RUNTI, ALL }, - { LogSubsystem::U_B_MPSC_Q, ALL }, + {LogSubsystem::PS, ALL}, {LogSubsystem::F, ALL}, {LogSubsystem::C, ALL}, + {LogSubsystem::CM, ALL}, {LogSubsystem::DISP, ALL}, {LogSubsystem::SCHED, ALL}, + {LogSubsystem::RUNTI, ALL}, {LogSubsystem::U_B_MPSC_Q, ALL}, }; template <LogSubsystem logSubsystem> class Logger { -private: - - static constexpr char const * getTagFor(LogSubsystem system) { + private: + static constexpr char const* getTagFor(LogSubsystem system) { switch (system) { - case LogSubsystem::PS: - return "PS "; - case LogSubsystem::F: - return "F "; - case LogSubsystem::C: - return "C "; - case LogSubsystem::CM: - return "CM "; - case LogSubsystem::DISP: - return "DISP "; - case LogSubsystem::SCHED: - return "SCHED"; - case LogSubsystem::RUNTI: - return "RUNTI"; - case LogSubsystem::U_B_MPSC_Q: - return "UBSCQ"; - default: - return "UNKNOWN SUBSYSTEM (Add it *now*)"; + case LogSubsystem::PS: + return "PS "; + case LogSubsystem::F: + return "F "; + case LogSubsystem::C: + return "C "; + case LogSubsystem::CM: + return "CM "; + case LogSubsystem::DISP: + return "DISP "; + case LogSubsystem::SCHED: + return "SCHED"; + case LogSubsystem::RUNTI: + return "RUNTI"; + case LogSubsystem::U_B_MPSC_Q: + return "UBSCQ"; + default: + return "UNKNOWN SUBSYSTEM (Add it *now*)"; } } static constexpr bool shouldPrefixThis(LogSubsystem system) { switch (system) { - case LogSubsystem::RUNTI: - case LogSubsystem::SCHED: - return false; - default: - return true; + case LogSubsystem::RUNTI: + case LogSubsystem::SCHED: + return false; + default: + return true; } } -protected: - + protected: inline void log(LogLevel level, const std::string& string) const { #ifdef NDEBUG // Do not log any debug messages if NDEBUG is defined. @@ -120,7 +144,8 @@ protected: #endif if (level > LOG_CONFIG.at(logSubsystem)) return; - std::string subSystemTag = getTagFor(logSubsystem);; + std::string subSystemTag = getTagFor(logSubsystem); + ; std::ostringstream sst; sst << subSystemTag; @@ -131,19 +156,11 @@ protected: worker_log(sst.str(), string); } - inline void logE(const std::string& string) const { - log(Error, string); - } + inline void logE(const std::string& string) const { log(Error, string); } - inline void logI(const std::string& string) const { - log(Info, string); - } + inline void logI(const std::string& string) const { log(Info, string); } - inline void logD(const std::string& string) const { - log(Debug, string); - } + inline void logD(const std::string& string) const { log(Debug, string); } - inline void logDD(const std::string& string) const { - log(FineDebug, string); - } + inline void logDD(const std::string& string) const { log(FineDebug, string); } }; diff --git a/emper/Dispatcher.cpp b/emper/Dispatcher.cpp index dfe4e280..d789db77 100644 --- a/emper/Dispatcher.cpp +++ b/emper/Dispatcher.cpp @@ -3,15 +3,11 @@ //#include <pthread.h> #include <functional> -#include "Runtime.hpp" #include "Debug.hpp" +#include "Runtime.hpp" thread_local const Fiber* Dispatcher::currentFiber; -func_t Dispatcher::getDispatchLoop() { - return std::bind(&Dispatcher::dispatchLoop, this); -} +func_t Dispatcher::getDispatchLoop() { return std::bind(&Dispatcher::dispatchLoop, this); } -void Dispatcher::putRuntimeWorkerToSleep() { - runtime.dispatcherLoopSleep(); -} +void Dispatcher::putRuntimeWorkerToSleep() { runtime.dispatcherLoopSleep(); } diff --git a/emper/Dispatcher.hpp b/emper/Dispatcher.hpp index 16a6b884..2ab0e971 100644 --- a/emper/Dispatcher.hpp +++ b/emper/Dispatcher.hpp @@ -1,14 +1,14 @@ #pragma once #include "Common.hpp" -#include "Fiber.hpp" #include "Debug.hpp" +#include "Fiber.hpp" class Runtime; class ContextManager; class Dispatcher : public Logger<LogSubsystem::DISP> { -protected: + protected: static thread_local const Fiber* currentFiber; Runtime& runtime; @@ -23,10 +23,8 @@ protected: fiber->run(); } - static inline bool isRunnable(Fiber* fiber) { - return fiber->setRunnableFalse(); - } - + static inline bool isRunnable(Fiber* fiber) { return fiber->setRunnableFalse(); } + static inline workeraffinity_t* getAffinityBuffer(Fiber* fiber) { return fiber->getAffinityBuffer(); } @@ -35,16 +33,12 @@ protected: return fiber->doAtomicDecrRefCount(); } - inline void recycle(const Fiber* fiber) { - delete fiber; - } + inline void recycle(const Fiber* fiber) { delete fiber; } void putRuntimeWorkerToSleep(); -public: - Dispatcher(Runtime& runtime) : runtime(runtime) { - } - + public: + Dispatcher(Runtime& runtime) : runtime(runtime) {} static const Fiber& getCurrentFiber() { const Fiber* fiber = getCurrentFiberPtr(); @@ -56,9 +50,7 @@ public: return currentFiber; } - static bool isDispatchedControlFlow() { - return currentFiber != nullptr; - } + static bool isDispatchedControlFlow() { return currentFiber != nullptr; } friend ContextManager; }; diff --git a/emper/Fiber.cpp b/emper/Fiber.cpp index c6e578ca..32109563 100644 --- a/emper/Fiber.cpp +++ b/emper/Fiber.cpp @@ -3,17 +3,14 @@ #include <ostream> void Fiber::run() const { - LOGD("run() calling " - << function.target<FIBER_FUN_TEMPLATE_ARG>() - << " (" << function.target_type().name() - << ") with arg " << arg); + LOGD("run() calling " << function.target<FIBER_FUN_TEMPLATE_ARG>() << " (" + << function.target_type().name() << ") with arg " << arg); function(arg); } std::ostream& operator<<(std::ostream& strm, const Fiber& fiber) { - strm << "Fiber [ptr=" << &fiber - << " func=" << fiber.function.target<void(void*)>() - << " arg=" << fiber.arg; + strm << "Fiber [ptr=" << &fiber << " func=" << fiber.function.target<void(void*)>() + << " arg=" << fiber.arg; if (fiber.affinity) { strm << " aff=" << fiber.affinity; @@ -26,6 +23,4 @@ std::ostream& operator<<(std::ostream& strm, const Fiber& fiber) { return strm; } -void Fiber::print() const { - std::cout << this << std::endl; -} +void Fiber::print() const { std::cout << this << std::endl; } diff --git a/emper/Fiber.hpp b/emper/Fiber.hpp index 27104b34..8132274d 100644 --- a/emper/Fiber.hpp +++ b/emper/Fiber.hpp @@ -1,13 +1,13 @@ #pragma once -#include "Common.hpp" -#include "Debug.hpp" -#include "lib/adt/MpscQueue.hpp" - -#include <functional> #include <atomic> #include <cassert> #include <climits> +#include <functional> + +#include "Common.hpp" +#include "Debug.hpp" +#include "lib/adt/MpscQueue.hpp" #define FIBER_FUN_TEMPLATE_ARG void(void*) #define FIBER_FUN0_TEMPLATE_ARG void(void) @@ -17,19 +17,19 @@ class Dispatcher; class LawsScheduler; class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> { -public: + public: typedef std::function<FIBER_FUN_TEMPLATE_ARG> fiber_fun_t; typedef std::function<FIBER_FUN0_TEMPLATE_ARG> fiber_fun0_t; static const workeraffinity_t NOT_AFFINE = -1; -private: + private: const fiber_fun_t function; void* const arg; - std::atomic<bool> runnable = { true }; + std::atomic<bool> runnable = {true}; - ALIGN_TO_CACHE_LINE std::atomic_uint referenceCounter = { 1 }; + ALIGN_TO_CACHE_LINE std::atomic_uint referenceCounter = {1}; workeraffinity_t* const affinity; @@ -43,45 +43,31 @@ private: /** * Dummy constructor. Used for example by the MpscQueue. */ - Fiber() : Fiber([]() {}) { - } + Fiber() : Fiber([]() {}) {} -protected: - Fiber(fiber_fun_t function, void* arg, workeraffinity_t* affinity) : function(function) - , arg(arg) - , affinity(affinity) { - }; + protected: + Fiber(fiber_fun_t function, void* arg, workeraffinity_t* affinity) + : function(function), arg(arg), affinity(affinity){}; // cppcheck-suppress uninitMemberVar explicit Fiber(fiber_fun0_t function, workeraffinity_t* affinity) - : Fiber([function] (UNUSED_ARG void* arg) { - function(); - }, nullptr, affinity) { - } + : Fiber([function](UNUSED_ARG void* arg) { function(); }, nullptr, affinity) {} - Fiber(fiber_fun_t function, void* arg) : Fiber(function, arg, nullptr) { - }; + Fiber(fiber_fun_t function, void* arg) : Fiber(function, arg, nullptr){}; // cppcheck-suppress uninitMemberVar - explicit Fiber(fiber_fun0_t function) : Fiber(function, nullptr) { - } + explicit Fiber(fiber_fun0_t function) : Fiber(function, nullptr) {} virtual ~Fiber() = default; virtual void run() const; -private: - inline void setMpscNext(Fiber* next) { - mpscNext = next; - } + private: + inline void setMpscNext(Fiber* next) { mpscNext = next; } - inline Fiber* getMpscNext() { - return mpscNext; - } + inline Fiber* getMpscNext() { return mpscNext; } - inline workeraffinity_t* getAffinityBuffer() const { - return affinity; - } + inline workeraffinity_t* getAffinityBuffer() const { return affinity; } inline bool setRunnableFalse() { bool res = runnable.load(std::memory_order_relaxed); @@ -105,20 +91,15 @@ private: return --referenceCounter; } - inline void setFlag(unsigned int flag) { - this->flag = flag; - } + inline void setFlag(unsigned int flag) { this->flag = flag; } friend class adt::MpscQueue<Fiber>; friend class Scheduler; friend class Dispatcher; friend class LawsScheduler; -public: - - unsigned int getFlag() const { - return flag; - } + public: + unsigned int getFlag() const { return flag; } workeraffinity_t getAffinity() const { if (affinity == nullptr) { @@ -131,13 +112,9 @@ public: friend std::ostream& operator<<(std::ostream&, const Fiber&); - static inline Fiber* from(fiber_fun_t function, void* arg) { - return new Fiber(function, arg); - } + static inline Fiber* from(fiber_fun_t function, void* arg) { return new Fiber(function, arg); } - static inline Fiber* from(fiber_fun0_t function) { - return new Fiber(function); - } + static inline Fiber* from(fiber_fun0_t function) { return new Fiber(function); } static inline Fiber* from(fiber_fun_t function, void* arg, workeraffinity_t* affinity) { return new Fiber(function, arg, affinity); diff --git a/emper/FiberManager.cpp b/emper/FiberManager.cpp index 21b4c461..01efdc3b 100644 --- a/emper/FiberManager.cpp +++ b/emper/FiberManager.cpp @@ -2,8 +2,7 @@ #include <cstdlib> -FiberManager::FiberManager(Runtime& runtime) : MemoryManager(runtime) { -} +FiberManager::FiberManager(Runtime& runtime) : MemoryManager(runtime) {} void* FiberManager::getFiberMemory() { #ifdef FM_WITH_MEMORY_MANAGER @@ -16,7 +15,7 @@ void* FiberManager::getFiberMemory() { abort(); } return mem; -#endif // FM_WITH_MEMORY_MANAGER +#endif // FM_WITH_MEMORY_MANAGER } void FiberManager::putFiberMemory(Fiber* fiber) { @@ -24,5 +23,5 @@ void FiberManager::putFiberMemory(Fiber* fiber) { putMemory(fiber); #else free(fiber); -#endif // FM_WITH_MEMORY_MANAGER +#endif // FM_WITH_MEMORY_MANAGER } diff --git a/emper/FiberManager.hpp b/emper/FiberManager.hpp index 5d0e5236..ae745e18 100644 --- a/emper/FiberManager.hpp +++ b/emper/FiberManager.hpp @@ -5,15 +5,11 @@ #include "Runtime.hpp" class FiberManager : protected MemoryManager<Fiber, 128, 64> { -private: - + private: void* getFiberMemory(); void putFiberMemory(Fiber* fiber); -public: - + public: FiberManager(Runtime& runtime); - }; - diff --git a/emper/MemoryManager.hpp b/emper/MemoryManager.hpp index 0bbbe89d..7239886f 100644 --- a/emper/MemoryManager.hpp +++ b/emper/MemoryManager.hpp @@ -5,16 +5,15 @@ #include "lib/adt/BoundedBumpArray.hpp" #include "lib/adt/WsClQueue.hpp" -template<typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> +template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> class MemoryManager { - -private: + private: const workerid_t workerCount; adt::WsClQueue<void*, WS_QUEUE_SIZE>** queues; static thread_local adt::BoundedBumpArray<void, WORKER_EXCLUSIVE_QUEUE_SIZE> workerExclusiveQueue; - + static thread_local adt::WsClQueue<void*, WS_QUEUE_SIZE> queue; static void* mallocMemory() { @@ -26,14 +25,13 @@ private: return memory; } -public: + public: MemoryManager(Runtime& runtime); void* getMemory(bool* malloced) { *malloced = false; void* memory = workerExclusiveQueue.get(); - if (memory) - return memory; + if (memory) return memory; bool poped = queue.popTop(&memory); @@ -59,29 +57,28 @@ public: void putMemory(T* memory) { assert(memory); bool pushed = workerExclusiveQueue.put(memory); - if (pushed) - return; + if (pushed) return; pushed = queue.pushBottom(memory); - if (pushed) - return; + if (pushed) return; free(memory); } }; -template<typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> -thread_local adt::BoundedBumpArray<void, WORKER_EXCLUSIVE_QUEUE_SIZE> MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::workerExclusiveQueue; +template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> +thread_local adt::BoundedBumpArray<void, WORKER_EXCLUSIVE_QUEUE_SIZE> + MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::workerExclusiveQueue; -template<typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> -thread_local adt::WsClQueue<void*, WS_QUEUE_SIZE> MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::queue; +template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> +thread_local adt::WsClQueue<void*, WS_QUEUE_SIZE> + MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::queue; -template<typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> -MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::MemoryManager(Runtime& runtime) : workerCount(runtime.getWorkerCount()) { +template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> +MemoryManager<T, WS_QUEUE_SIZE, WORKER_EXCLUSIVE_QUEUE_SIZE>::MemoryManager(Runtime& runtime) + : workerCount(runtime.getWorkerCount()) { queues = new adt::WsClQueue<void*, WS_QUEUE_SIZE>*[workerCount]; - auto newWorkerHook = [this]() { - queues[Runtime::getWorkerId()] = &queue; - }; + auto newWorkerHook = [this]() { queues[Runtime::getWorkerId()] = &queue; }; runtime.addNewWorkerHook(newWorkerHook); } diff --git a/emper/PrivateSemaphore.hpp b/emper/PrivateSemaphore.hpp index e3117500..4c9b4ce0 100644 --- a/emper/PrivateSemaphore.hpp +++ b/emper/PrivateSemaphore.hpp @@ -4,32 +4,23 @@ #include "Context.hpp" #include "ContextManager.hpp" #include "Debug.hpp" -#include "Runtime.hpp" #include "Fiber.hpp" +#include "Runtime.hpp" -class PrivateSemaphore : - protected Blockable<LogSubsystem::PS> { - -protected: - +class PrivateSemaphore : protected Blockable<LogSubsystem::PS> { + protected: // cppcheck-suppress uninitMemberVar - PrivateSemaphore() : Blockable(*Runtime::getRuntime()) - { + PrivateSemaphore() : Blockable(*Runtime::getRuntime()) { LOGD("constructed by fiber " << Dispatcher::getCurrentFiber()); } - [[noreturn]] void unblockAndExit(Context* context) { - contextManager.discardAndResume(context); - } + [[noreturn]] void unblockAndExit(Context* context) { contextManager.discardAndResume(context); } virtual Context* signalInternal() = 0; - virtual void debugLog(const std::string& string) const { - Logger::logD(string); - } - -public: + virtual void debugLog(const std::string& string) const { Logger::logD(string); } + public: virtual void wait() = 0; void signal() { diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp index dda344bc..273e6936 100644 --- a/emper/Runtime.cpp +++ b/emper/Runtime.cpp @@ -1,33 +1,35 @@ #include "Runtime.hpp" #include <pthread.h> +#include <sys/syscall.h> #include <sys/sysinfo.h> #include <unistd.h> -#include <sys/syscall.h> + #include <cstdlib> #include <ctime> // Non portable. #include <sched.h> -#include "emper-config.h" -#include "ContextManager.hpp" #include "Common.hpp" +#include "ContextManager.hpp" #include "Debug.hpp" +#include "emper-config.h" std::mutex Runtime::currentRuntimeMutex; Runtime* Runtime::currentRuntime; thread_local unsigned int Runtime::seed; thread_local workerid_t Runtime::workerId; -RuntimeStrategy& Runtime::DEFAULT_STRATEGY = WsStrategy::INSTANCE; - -Runtime::Runtime(workerid_t workerCount, RuntimeStrategy& strategy) : workerCount(workerCount) - , workerLatch(workerCount) - , strategy(strategy) - , scheduler(strategy.getScheduler(*this)) - , dispatcher(strategy.getDispatcher(*this)) - , contextManager(*(new ContextManager(*this))) - , atLeastOneWorkerIsSleeping(false) { +RuntimeStrategy& Runtime::DEFAULT_STRATEGY = WsStrategy::INSTANCE; + +Runtime::Runtime(workerid_t workerCount, RuntimeStrategy& strategy) + : workerCount(workerCount), + workerLatch(workerCount), + strategy(strategy), + scheduler(strategy.getScheduler(*this)), + dispatcher(strategy.getDispatcher(*this)), + contextManager(*(new ContextManager(*this))), + atLeastOneWorkerIsSleeping(false) { threads = new pthread_t[workerCount]; workerIds = new workerid_t[workerCount]; @@ -60,7 +62,9 @@ Runtime::Runtime(workerid_t workerCount, RuntimeStrategy& strategy) : workerCoun // Load the worker ID into the worker ID map. workerIds[i] = i; - auto thread_function = [](void* voidWorkerId) -> void* { return currentRuntime->workerLoop(voidWorkerId); }; + auto thread_function = [](void* voidWorkerId) -> void* { + return currentRuntime->workerLoop(voidWorkerId); + }; errno = pthread_create(&threads[i], &attr, thread_function, &workerIds[i]); if (errno) DIE_MSG_ERRNO("pthread_create() failed"); } @@ -90,7 +94,7 @@ Runtime::~Runtime() { } void* Runtime::workerLoop(void* voidWorkerId) { - workerId = *(workerid_t*) voidWorkerId; + workerId = *(workerid_t*)voidWorkerId; LOGD("Worker loop started by thread " << syscall(SYS_gettid)); int oldType; @@ -112,9 +116,7 @@ void* Runtime::workerLoop(void* voidWorkerId) { return nullptr; } -Fiber* Runtime::nextFiber() { - return scheduler.nextFiber(); -} +Fiber* Runtime::nextFiber() { return scheduler.nextFiber(); } void Runtime::waitUntilFinished() { for (workerid_t i = 0; i < workerCount; ++i) { @@ -137,9 +139,7 @@ void Runtime::printLastRuntimeStats() { currentRuntime->printStats(); } -bool Runtime::inRuntime() { - return dispatcher.isDispatchedControlFlow(); -} +bool Runtime::inRuntime() { return dispatcher.isDispatchedControlFlow(); } void Runtime::executeAndWait(std::function<void()> f) { if (inRuntime()) { @@ -150,10 +150,10 @@ void Runtime::executeAndWait(std::function<void()> f) { fiberFinished.lock(); Fiber* fiber = Fiber::from([&] { - f(); + f(); - fiberFinished.unlock(); - }); + fiberFinished.unlock(); + }); schedule(*fiber); diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp index cc98834d..c446473e 100644 --- a/emper/Runtime.hpp +++ b/emper/Runtime.hpp @@ -8,13 +8,13 @@ #include "Dispatcher.hpp" #include "RuntimeStrategy.hpp" #include "Scheduler.hpp" -#include "strategies/ws/WsStrategy.hpp" #include "lib/sync/Latch.hpp" +#include "strategies/ws/WsStrategy.hpp" class ContextManager; class Runtime : public Logger<LogSubsystem::RUNTI> { -private: + private: static std::mutex currentRuntimeMutex; static Runtime* currentRuntime; @@ -44,10 +44,8 @@ private: static void printLastRuntimeStats(); -protected: - void addNewWorkerHook(std::function<void(void)> hook) { - newWorkerHooks.push_back(hook); - }; + protected: + void addNewWorkerHook(std::function<void(void)> hook) { newWorkerHooks.push_back(hook); }; inline void notifyAboutNewWork() { if (!atLeastOneWorkerIsSleeping.load(std::memory_order_relaxed)) return; @@ -63,24 +61,18 @@ protected: atLeastOneWorkerIsSleeping.store(false, std::memory_order_relaxed); } -public: - - Runtime() : Runtime(std::thread::hardware_concurrency()) { - } + public: + Runtime() : Runtime(std::thread::hardware_concurrency()) {} - Runtime(workerid_t workerCount) : Runtime(workerCount, DEFAULT_STRATEGY) { - } + Runtime(workerid_t workerCount) : Runtime(workerCount, DEFAULT_STRATEGY) {} - Runtime(RuntimeStrategy& strategy) : Runtime(std::thread::hardware_concurrency(), strategy) { - } + Runtime(RuntimeStrategy& strategy) : Runtime(std::thread::hardware_concurrency(), strategy) {} Runtime(workerid_t workerCount, RuntimeStrategy& strategy); ~Runtime(); - inline void schedule(Fiber& fiber) { - scheduler.schedule(fiber); - } + inline void schedule(Fiber& fiber) { scheduler.schedule(fiber); } Fiber* nextFiber(); @@ -90,25 +82,15 @@ public: return (seed >> 16) & 0x7FFF; } - static inline workerid_t getWorkerId() { - return workerId; - } + static inline workerid_t getWorkerId() { return workerId; } - inline workerid_t getWorkerCount() const { - return workerCount; - } + inline workerid_t getWorkerCount() const { return workerCount; } - static inline Runtime* getRuntime() { - return currentRuntime; - } + static inline Runtime* getRuntime() { return currentRuntime; } - inline ContextManager& getContextManager() { - return contextManager; - } + inline ContextManager& getContextManager() { return contextManager; } - inline RuntimeStrategy& getStrategy() { - return strategy; - } + inline RuntimeStrategy& getStrategy() { return strategy; } void waitUntilFinished(); @@ -121,6 +103,6 @@ public: friend ContextManager; friend Scheduler; friend Dispatcher; - template<typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> + template <typename T, intptr_t WS_QUEUE_SIZE, size_t WORKER_EXCLUSIVE_QUEUE_SIZE> friend class MemoryManager; }; diff --git a/emper/RuntimeStrategy.hpp b/emper/RuntimeStrategy.hpp index 8f8a31df..76c32d48 100644 --- a/emper/RuntimeStrategy.hpp +++ b/emper/RuntimeStrategy.hpp @@ -8,16 +8,13 @@ class RuntimeStrategyStats; #include <memory> class RuntimeStrategy { - friend class Runtime; -private: - + private: virtual Scheduler& getScheduler(Runtime& runtime) = 0; virtual Dispatcher& getDispatcher(Runtime& runtime) = 0; -public: - + public: virtual std::shared_ptr<RuntimeStrategyStats> getStats() = 0; }; diff --git a/emper/RuntimeStrategyStats.hpp b/emper/RuntimeStrategyStats.hpp index 23c61764..27f581a9 100644 --- a/emper/RuntimeStrategyStats.hpp +++ b/emper/RuntimeStrategyStats.hpp @@ -1,9 +1,6 @@ #pragma once class RuntimeStrategyStats { - -public: - + public: virtual void print() = 0; - }; diff --git a/emper/Scheduler.cpp b/emper/Scheduler.cpp index 222a1a37..156a7a69 100644 --- a/emper/Scheduler.cpp +++ b/emper/Scheduler.cpp @@ -2,13 +2,8 @@ #include "Runtime.hpp" -Scheduler::Scheduler(Runtime& runtime) : runtime(runtime) { -} +Scheduler::Scheduler(Runtime& runtime) : runtime(runtime) {} -void Scheduler::addNewWorkerHook(std::function<void(void)> hook) { - runtime.addNewWorkerHook(hook); -} +void Scheduler::addNewWorkerHook(std::function<void(void)> hook) { runtime.addNewWorkerHook(hook); } -void Scheduler::notifyRuntimeAboutNewWork() { - runtime.notifyAboutNewWork(); -} +void Scheduler::notifyRuntimeAboutNewWork() { runtime.notifyAboutNewWork(); } diff --git a/emper/Scheduler.hpp b/emper/Scheduler.hpp index 043165b1..a14b7a06 100644 --- a/emper/Scheduler.hpp +++ b/emper/Scheduler.hpp @@ -1,16 +1,15 @@ #pragma once -#include "Debug.hpp" - #include <functional> -#include "Fiber.hpp" #include "Common.hpp" +#include "Debug.hpp" +#include "Fiber.hpp" class Runtime; -class Scheduler : public Logger<LogSubsystem::SCHED>{ -protected: +class Scheduler : public Logger<LogSubsystem::SCHED> { + protected: Runtime& runtime; Scheduler(Runtime& runtime); @@ -20,15 +19,12 @@ protected: return fiber.getAffinityBuffer(); } - static inline void increaseRefCount(Fiber& fiber) { - fiber.doAtomicIncrRefCount(); - } + static inline void increaseRefCount(Fiber& fiber) { fiber.doAtomicIncrRefCount(); } void notifyRuntimeAboutNewWork(); -public: + public: virtual void schedule(Fiber& fiber) = 0; virtual Fiber* nextFiber() = 0; - }; diff --git a/emper/Semaphore.cpp b/emper/Semaphore.cpp index d6df0b44..91c92144 100644 --- a/emper/Semaphore.cpp +++ b/emper/Semaphore.cpp @@ -11,7 +11,5 @@ void Semaphore::print() { } std::cout << "Semaphore" - << " count=" << count - << " waiterListSize=" << waiterListSize - << std::endl; + << " count=" << count << " waiterListSize=" << waiterListSize << std::endl; } diff --git a/emper/Semaphore.hpp b/emper/Semaphore.hpp index 83b13d09..1f32b0e3 100644 --- a/emper/Semaphore.hpp +++ b/emper/Semaphore.hpp @@ -1,20 +1,19 @@ #pragma once -#include <queue> #include <mutex> +#include <queue> #include "BinaryPrivateSemaphore.hpp" namespace emper { class Semaphore { -private: - + private: std::queue<BinaryPrivateSemaphore*> waiterList; unsigned int count; std::mutex mutex; -public: + public: bool acquire() { bool blocked; mutex.lock(); @@ -50,4 +49,4 @@ public: void print(); }; -} +} // namespace emper diff --git a/emper/SynchronizedFiber.hpp b/emper/SynchronizedFiber.hpp index cbdf6b88..d666530b 100644 --- a/emper/SynchronizedFiber.hpp +++ b/emper/SynchronizedFiber.hpp @@ -1,42 +1,37 @@ #pragma once -#include "Fiber.hpp" -#include "PrivateSemaphore.hpp" #include "BinaryPrivateSemaphore.hpp" #include "CountingPrivateSemaphore.hpp" +#include "Fiber.hpp" +#include "PrivateSemaphore.hpp" class SynchronizedFiber : public Fiber { - -private: - + private: PrivateSemaphore& semaphore; - SynchronizedFiber(fiber_fun_t function, void* arg, - workeraffinity_t* affinity, - PrivateSemaphore& semaphore) : Fiber(function, arg, affinity) - , semaphore(semaphore) { - }; + SynchronizedFiber(fiber_fun_t function, void* arg, workeraffinity_t* affinity, + PrivateSemaphore& semaphore) + : Fiber(function, arg, affinity), semaphore(semaphore){}; // cppcheck-suppress uninitMemberVar - explicit SynchronizedFiber(fiber_fun0_t function, workeraffinity_t* affinity, PrivateSemaphore& semaphore) - : SynchronizedFiber([function] (UNUSED_ARG void* arg) { - function(); - }, nullptr, affinity, semaphore) { - } + explicit SynchronizedFiber(fiber_fun0_t function, workeraffinity_t* affinity, + PrivateSemaphore& semaphore) + : SynchronizedFiber([function](UNUSED_ARG void* arg) { function(); }, nullptr, affinity, + semaphore) {} - SynchronizedFiber(fiber_fun_t function, void* arg, PrivateSemaphore& semaphore) : SynchronizedFiber(function, arg, nullptr, semaphore) { - }; + SynchronizedFiber(fiber_fun_t function, void* arg, PrivateSemaphore& semaphore) + : SynchronizedFiber(function, arg, nullptr, semaphore){}; // cppcheck-suppress uninitMemberVar - explicit SynchronizedFiber(fiber_fun0_t function, PrivateSemaphore& semaphore) : SynchronizedFiber(function, nullptr, semaphore) { - } + explicit SynchronizedFiber(fiber_fun0_t function, PrivateSemaphore& semaphore) + : SynchronizedFiber(function, nullptr, semaphore) {} void run() const override { Fiber::run(); semaphore.signalAndExit(); } -public: + public: static inline Fiber* from(fiber_fun_t function, void* arg, BinaryPrivateSemaphore& semaphore) { return new SynchronizedFiber(function, arg, semaphore); } @@ -45,11 +40,13 @@ public: return new SynchronizedFiber(function, semaphore); } - static inline Fiber* from(fiber_fun_t function, void* arg, workeraffinity_t* affinity, BinaryPrivateSemaphore& semaphore) { + static inline Fiber* from(fiber_fun_t function, void* arg, workeraffinity_t* affinity, + BinaryPrivateSemaphore& semaphore) { return new SynchronizedFiber(function, arg, affinity, semaphore); } - static inline Fiber* from(fiber_fun0_t function, workeraffinity_t* affinity, BinaryPrivateSemaphore& semaphore) { + static inline Fiber* from(fiber_fun0_t function, workeraffinity_t* affinity, + BinaryPrivateSemaphore& semaphore) { return new SynchronizedFiber(function, affinity, semaphore); } @@ -63,12 +60,14 @@ public: return new SynchronizedFiber(function, semaphore); } - static inline Fiber* from(fiber_fun_t function, void* arg, workeraffinity_t* affinity, CountingPrivateSemaphore& semaphore) { + static inline Fiber* from(fiber_fun_t function, void* arg, workeraffinity_t* affinity, + CountingPrivateSemaphore& semaphore) { semaphore.incrementCounterByOne(); return new SynchronizedFiber(function, arg, affinity, semaphore); } - static inline Fiber* from(fiber_fun0_t function, workeraffinity_t* affinity, CountingPrivateSemaphore& semaphore) { + static inline Fiber* from(fiber_fun0_t function, workeraffinity_t* affinity, + CountingPrivateSemaphore& semaphore) { semaphore.incrementCounterByOne(); return new SynchronizedFiber(function, affinity, semaphore); } diff --git a/emper/UnboundedBlockingMpscQueue.hpp b/emper/UnboundedBlockingMpscQueue.hpp index 51e3501a..aee0caa5 100644 --- a/emper/UnboundedBlockingMpscQueue.hpp +++ b/emper/UnboundedBlockingMpscQueue.hpp @@ -1,16 +1,14 @@ #pragma once -#include "Blockable.hpp" -#include "Context.hpp" - -#include <queue> #include <mutex> +#include <queue> -template<typename T> -class UnboundedBlockingMpscQueue : - public Blockable<LogSubsystem::U_B_MPSC_Q> { +#include "Blockable.hpp" +#include "Context.hpp" -private: +template <typename T> +class UnboundedBlockingMpscQueue : public Blockable<LogSubsystem::U_B_MPSC_Q> { + private: std::atomic<Context*> blockedContext = nullptr; bool tPopped; @@ -40,10 +38,8 @@ private: } } -public: - - UnboundedBlockingMpscQueue(Runtime& runtime) : Blockable(runtime) { - } + public: + UnboundedBlockingMpscQueue(Runtime& runtime) : Blockable(runtime) {} void put(T t) { { @@ -65,13 +61,13 @@ public: if (!tPopped) { Context* context = Context::getCurrentContext(); block([this, context, postRetrieve] { - blockedContext = context; + blockedContext = context; - tryToGetElement(postRetrieve); - if (tPopped) { - tryToWakeupBlockedContext(); - } - }); + tryToGetElement(postRetrieve); + if (tPopped) { + tryToWakeupBlockedContext(); + } + }); if (!tPopped) { std::lock_guard<std::mutex> lock(queueMutex); // If 't' isn't already set, then mspcQueue.get() MUST diff --git a/emper/c_emper.cpp b/emper/c_emper.cpp index 4e2a4718..6b8a9211 100644 --- a/emper/c_emper.cpp +++ b/emper/c_emper.cpp @@ -1,9 +1,8 @@ -#include "emper.h" - -#include "Runtime.hpp" -#include "Fiber.hpp" #include "BinaryPrivateSemaphore.hpp" #include "CountingPrivateSemaphore.hpp" +#include "Fiber.hpp" +#include "Runtime.hpp" +#include "emper.h" runtime* init_runtime(void) { Runtime* r = new Runtime(); @@ -15,41 +14,38 @@ void wait_until_runtime_finished() { r->waitUntilFinished(); } -fiber* fiber_from(void(*function)(void*), void* arg) { +fiber* fiber_from(void (*function)(void*), void* arg) { Fiber* f = Fiber::from(function, arg); return reinterpret_cast<fiber*>(f); } -fiber* fiber_from0(void(*function)(void)) { +fiber* fiber_from0(void (*function)(void)) { Fiber* f = Fiber::from(function); return reinterpret_cast<fiber*>(f); } -fiber* aff_fiber_from(void(*function)(void*), void* arg, workeraffinity_t* affinity) { +fiber* aff_fiber_from(void (*function)(void*), void* arg, workeraffinity_t* affinity) { Fiber* f = Fiber::from(function, arg, affinity); return reinterpret_cast<fiber*>(f); } -fiber* aff_fiber_from0(void(*function)(void), workeraffinity_t* affinity) { +fiber* aff_fiber_from0(void (*function)(void), workeraffinity_t* affinity) { Fiber* f = Fiber::from(function, affinity); return reinterpret_cast<fiber*>(f); } - void init_affinity(workeraffinity_t affinity[], unsigned int n) { for (unsigned int i = 0; i < n; ++i) { affinity[i] = Fiber::NOT_AFFINE; } } - void schedule(fiber* fiber) { Runtime* runtime = Runtime::getRuntime(); Fiber* f = reinterpret_cast<Fiber*>(fiber); runtime->schedule(*f); } - bps* new_binary_sem() { BPS* sem = new BPS(); return reinterpret_cast<bps*>(sem); @@ -70,7 +66,6 @@ void wait_bps(bps* sem) { binaryPrivateSemaphore->wait(); } - cps* new_counting_sem() { CPS* sem = new CPS(); return reinterpret_cast<cps*>(sem); @@ -82,17 +77,19 @@ cps* new_counting_sem_with(unsigned int i) { } void signal_cps(cps* sem) { - CountingPrivateSemaphore* countingPrivateSemaphore = reinterpret_cast<CountingPrivateSemaphore*>(sem); + CountingPrivateSemaphore* countingPrivateSemaphore = + reinterpret_cast<CountingPrivateSemaphore*>(sem); countingPrivateSemaphore->signal(); } void signal_and_exit_cps(cps* sem) { - CountingPrivateSemaphore* countingPrivateSemaphore = reinterpret_cast<CountingPrivateSemaphore*>(sem); + CountingPrivateSemaphore* countingPrivateSemaphore = + reinterpret_cast<CountingPrivateSemaphore*>(sem); countingPrivateSemaphore->signalAndExit(); } void wait_cps(cps* sem) { - CountingPrivateSemaphore* countingPrivateSemaphore = reinterpret_cast<CountingPrivateSemaphore*>(sem); + CountingPrivateSemaphore* countingPrivateSemaphore = + reinterpret_cast<CountingPrivateSemaphore*>(sem); countingPrivateSemaphore->wait(); } - diff --git a/emper/include/emper.h b/emper/include/emper.h index 981850c5..4c5c5d5d 100644 --- a/emper/include/emper.h +++ b/emper/include/emper.h @@ -14,47 +14,39 @@ typedef struct cps cps; extern "C" { #endif +runtime* init_runtime(void); - runtime* init_runtime(void); +void wait_until_runtime_finished(); - void wait_until_runtime_finished(); +fiber* fiber_from(void (*function)(void*), void* arg); +fiber* fiber_from0(void (*function)(void)); - fiber* fiber_from(void(*function)(void*), void* arg); +fiber* aff_fiber_from(void (*function)(void*), void* arg, workeraffinity_t* affinity); - fiber* fiber_from0(void(*function)(void)); +fiber* aff_fiber_from0(void (*function)(void), workeraffinity_t* affinity); +void init_affinity(workeraffinity_t affinity[], unsigned int n); - fiber* aff_fiber_from(void(*function)(void*), void* arg, workeraffinity_t* affinity); +void schedule(fiber* fiber); - fiber* aff_fiber_from0(void(*function)(void), workeraffinity_t* affinity); +bps* new_binary_sem(void); +void signal_bps(bps* sem); - void init_affinity(workeraffinity_t affinity[], unsigned int n); +void signal_and_exit_bps(bps* sem); +void wait_bps(bps* sem); - void schedule(fiber* fiber); +cps* new_counting_sem(void); +cps* new_counting_sem_with(unsigned int i); - bps* new_binary_sem(void); +void signal_cps(cps* sem); - void signal_bps(bps* sem); - - void signal_and_exit_bps(bps* sem); - - void wait_bps(bps* sem); - - - cps* new_counting_sem(void); - - cps* new_counting_sem_with(unsigned int i); - - void signal_cps(cps* sem); - - void signal_and_exit_cps(cps* sem); - - void wait_cps(cps* sem); +void signal_and_exit_cps(cps* sem); +void wait_cps(cps* sem); #ifdef __cplusplus } diff --git a/emper/include/emper.hpp b/emper/include/emper.hpp index 9fb63c84..a59e6647 100644 --- a/emper/include/emper.hpp +++ b/emper/include/emper.hpp @@ -1,10 +1,10 @@ #pragma once -#include <functional> #include <cassert> +#include <functional> -#include "Runtime.hpp" #include "Fiber.hpp" +#include "Runtime.hpp" #include "SynchronizedFiber.hpp" void async(Fiber* fiber) { @@ -13,7 +13,6 @@ void async(Fiber* fiber) { runtime->schedule(*fiber); } - void async(Fiber::fiber_fun_t function, void* arg) { Fiber* fiber = Fiber::from(function, arg); async(fiber); diff --git a/emper/lib/DebugUtil.cpp b/emper/lib/DebugUtil.cpp index f6841ca1..11569f56 100644 --- a/emper/lib/DebugUtil.cpp +++ b/emper/lib/DebugUtil.cpp @@ -1,8 +1,8 @@ #include "DebugUtil.hpp" -#include <stdio.h> #include <execinfo.h> #include <signal.h> +#include <stdio.h> #include <stdlib.h> #include <unistd.h> diff --git a/emper/lib/adt/BoundedBumpArray.hpp b/emper/lib/adt/BoundedBumpArray.hpp index 087bec67..a744c92a 100644 --- a/emper/lib/adt/BoundedBumpArray.hpp +++ b/emper/lib/adt/BoundedBumpArray.hpp @@ -2,40 +2,32 @@ namespace adt { -template<typename T, size_t N> +template <typename T, size_t N> class BoundedBumpArray { -private: - + private: static_assert(N > 1, "BoundedBumpArray size N must be greater than 1"); size_t nextFreeElement = 0; T* array[N]; -public: + public: + bool isFull() { return nextFreeElement + 1 == N; } - bool isFull() { - return nextFreeElement + 1 == N; - } + bool isEmpty() { return nextFreeElement == 0; } - bool isEmpty() { - return nextFreeElement == 0; - } - bool put(T* t) { - if (isFull()) - return false; + if (isFull()) return false; array[nextFreeElement++] = t; return true; } T* get() { - if (isEmpty()) - return nullptr; + if (isEmpty()) return nullptr; return array[--nextFreeElement]; } }; -} +} // namespace adt diff --git a/emper/lib/adt/LockedQueue.hpp b/emper/lib/adt/LockedQueue.hpp index fa24f875..267653e6 100644 --- a/emper/lib/adt/LockedQueue.hpp +++ b/emper/lib/adt/LockedQueue.hpp @@ -1,58 +1,57 @@ #pragma once -#include "Common.hpp" - -#include <mutex> #include <deque> +#include <mutex> -namespace adt { +#include "Common.hpp" - template<typename I, const uintptr_t SIZE> - class LockedQueue { +namespace adt { - private: - std::mutex queue_mutex; +template <typename I, const uintptr_t SIZE> +class LockedQueue { + private: + std::mutex queue_mutex; - std::deque<I> deque; + std::deque<I> deque; - public: - bool isFull() const { - std::lock_guard<std::mutex> lock(queue_mutex); - return deque.size() == SIZE; - } + public: + bool isFull() const { + std::lock_guard<std::mutex> lock(queue_mutex); + return deque.size() == SIZE; + } - bool pushBottom(const I item) { - std::lock_guard<std::mutex> lock(queue_mutex); + bool pushBottom(const I item) { + std::lock_guard<std::mutex> lock(queue_mutex); - if (deque.size() == SIZE) return false; + if (deque.size() == SIZE) return false; - deque.push_back(item); + deque.push_back(item); - return true; - } + return true; + } - bool popTop(I* itemPtr) { - std::lock_guard<std::mutex> lock(queue_mutex); + bool popTop(I* itemPtr) { + std::lock_guard<std::mutex> lock(queue_mutex); - if (deque.empty()) return false; + if (deque.empty()) return false; - *itemPtr = deque.front(); + *itemPtr = deque.front(); - deque.pop_front(); + deque.pop_front(); - return true; - } + return true; + } - bool popBottom(I* itemPtr) { - std::lock_guard<std::mutex> lock(queue_mutex); + bool popBottom(I* itemPtr) { + std::lock_guard<std::mutex> lock(queue_mutex); - if (deque.empty()) return false; + if (deque.empty()) return false; - *itemPtr = deque.back(); + *itemPtr = deque.back(); - deque.pop_back(); + deque.pop_back(); - return true; - } - }; -} + return true; + } +}; +} // namespace adt diff --git a/emper/lib/adt/LockedUnboundedQueue.hpp b/emper/lib/adt/LockedUnboundedQueue.hpp index 820d1cf5..8c510001 100644 --- a/emper/lib/adt/LockedUnboundedQueue.hpp +++ b/emper/lib/adt/LockedUnboundedQueue.hpp @@ -2,29 +2,27 @@ namespace adt { - template<typename I> - class LockedUnboundedQueue { +template <typename I> +class LockedUnboundedQueue { + private: + std::mutex queue_mutex; - private: - std::mutex queue_mutex; + std::deque<I*> deque; - std::deque<I*> deque; + public: + void enqueue(I* item) { + std::lock_guard<std::mutex> lock(queue_mutex); + deque.push_front(item); + } - public: - - void enqueue(I* item) { - std::lock_guard<std::mutex> lock(queue_mutex); - deque.push_front(item); - } - - I* dequeue() { - std::lock_guard<std::mutex> lock(queue_mutex); - if (deque.empty()) { - return nullptr; - } - I* res = deque.back(); - deque.pop_back(); - return res; + I* dequeue() { + std::lock_guard<std::mutex> lock(queue_mutex); + if (deque.empty()) { + return nullptr; } - }; -} + I* res = deque.back(); + deque.pop_back(); + return res; + } +}; +} // namespace adt diff --git a/emper/lib/adt/MpscQueue.hpp b/emper/lib/adt/MpscQueue.hpp index 00d0c540..536c9936 100644 --- a/emper/lib/adt/MpscQueue.hpp +++ b/emper/lib/adt/MpscQueue.hpp @@ -4,16 +4,14 @@ namespace adt { -template<typename T> +template <typename T> class MpscQueue { - private: T* head; std::atomic<T*> tail; T dummy; -public: - + public: MpscQueue() { head = &dummy; tail = head; @@ -49,4 +47,4 @@ public: } }; -} +} // namespace adt diff --git a/emper/lib/adt/WsClQueue.hpp b/emper/lib/adt/WsClQueue.hpp index ec90f919..2d8700b0 100644 --- a/emper/lib/adt/WsClQueue.hpp +++ b/emper/lib/adt/WsClQueue.hpp @@ -1,7 +1,7 @@ #pragma once -#include <cstdint> #include <atomic> +#include <cstdint> #include "Common.hpp" @@ -28,37 +28,31 @@ namespace adt { * of pushes, pops and steals executing at a rate of 4 billtion * operations per second", so overflows should be no problem. */ -template<typename _PAYLOAD, const uintptr_t _CAPACITY> +template <typename _PAYLOAD, const uintptr_t _CAPACITY> class WsClQueue { ALIGN_TO_CACHE_LINE std::atomic<uint64_t> bottom; ALIGN_TO_CACHE_LINE std::atomic<uint64_t> top; _PAYLOAD queue[_CAPACITY]; -public: + public: // 'bottom' and 'top' are initialized to '1', instead of '0' as // it's done in the "Dynamic Circular Work-Stealing Deque" paper // because popBottom will decrement bottom, which will result in // an underflow if bottom is '0'. The paper's queue uses Java // 'long' for bottom and top and is thus safe since it's signed. - WsClQueue() : bottom(1), top(1) { } + WsClQueue() : bottom(1), top(1) {} bool pushBottom(const _PAYLOAD item); bool popTop(_PAYLOAD *item); bool popBottom(_PAYLOAD *item); bool isFull() const; bool isEmpty() const; void print() const; - inline uintptr_t capacity() const { - return _CAPACITY; - } - inline uint64_t usedSlots() const { - return bottom - top; - } - inline uintptr_t freeSlots() const { - return capacity() - usedSlots(); - } + inline uintptr_t capacity() const { return _CAPACITY; } + inline uint64_t usedSlots() const { return bottom - top; } + inline uintptr_t freeSlots() const { return capacity() - usedSlots(); } }; -template<typename _PAYLOAD, const uintptr_t _CAPACITY> +template <typename _PAYLOAD, const uintptr_t _CAPACITY> bool WsClQueue<_PAYLOAD, _CAPACITY>::pushBottom(const _PAYLOAD item) { if (isFull()) return false; @@ -71,9 +65,9 @@ bool WsClQueue<_PAYLOAD, _CAPACITY>::pushBottom(const _PAYLOAD item) { return true; } -template<typename _PAYLOAD, const uintptr_t _CAPACITY> +template <typename _PAYLOAD, const uintptr_t _CAPACITY> bool WsClQueue<_PAYLOAD, _CAPACITY>::popTop(_PAYLOAD *item) { - start: +start: uint64_t oldTop = top; if (bottom <= oldTop) return false; @@ -88,13 +82,14 @@ bool WsClQueue<_PAYLOAD, _CAPACITY>::popTop(_PAYLOAD *item) { // If cas fails, then this popTop() lost the race against another // popTop(). - if (!top.compare_exchange_weak(oldTop, newTop)) //, std::memory_order_release, std::memory_order_relaxed)) + if (!top.compare_exchange_weak( + oldTop, newTop)) //, std::memory_order_release, std::memory_order_relaxed)) goto start; return true; } -template<typename _PAYLOAD, const uintptr_t _CAPACITY> +template <typename _PAYLOAD, const uintptr_t _CAPACITY> bool WsClQueue<_PAYLOAD, _CAPACITY>::popBottom(_PAYLOAD *item) { uint64_t localBottom = --bottom; uint64_t localTop = top; @@ -107,7 +102,8 @@ bool WsClQueue<_PAYLOAD, _CAPACITY>::popBottom(_PAYLOAD *item) { *item = queue[localBottom % _CAPACITY]; if (localBottom > localTop) return true; - // bool res = top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, std::memory_order_relaxed); + // bool res = top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, + // std::memory_order_relaxed); bool res = top.compare_exchange_weak(localTop, localTop + 1); // Either a popTop() removed the element ('res' is false) or we // removed the element ('res' is true), but we need to increment @@ -118,14 +114,14 @@ bool WsClQueue<_PAYLOAD, _CAPACITY>::popBottom(_PAYLOAD *item) { return res; } -template<typename _PAYLOAD, const uintptr_t _CAPACITY> +template <typename _PAYLOAD, const uintptr_t _CAPACITY> bool WsClQueue<_PAYLOAD, _CAPACITY>::isFull() const { return usedSlots() >= _CAPACITY; } -template<typename _PAYLOAD, const uintptr_t _CAPACITY> +template <typename _PAYLOAD, const uintptr_t _CAPACITY> bool WsClQueue<_PAYLOAD, _CAPACITY>::isEmpty() const { return top >= bottom; } -} // namespace adt +} // namespace adt diff --git a/emper/lib/adt/WsClV2Queue.hpp b/emper/lib/adt/WsClV2Queue.hpp index 102f8867..e080a299 100644 --- a/emper/lib/adt/WsClV2Queue.hpp +++ b/emper/lib/adt/WsClV2Queue.hpp @@ -1,7 +1,7 @@ #pragma once -#include <cstdint> #include <atomic> +#include <cstdint> #include "Common.hpp" @@ -28,9 +28,8 @@ namespace adt { * of pushes, pops and steals executing at a rate of 4 billtion * operations per second", so overflows should be no problem. */ -template<typename ITEM_TYPE, const uintptr_t CAPACITY> +template <typename ITEM_TYPE, const uintptr_t CAPACITY> class WsClV2Queue { - // Bottom of the queue is only modified in pushBottom() and // popBottom() methods, which are only used by the same // thread. Thus we don't need to make it atomic. @@ -41,36 +40,29 @@ class WsClV2Queue { ITEM_TYPE queue[CAPACITY]; -public: + public: // 'bottom' and 'top' are initialized to '1', instead of '0' as // it's done in the "Dynamic Circular Work-Stealing Deque" paper // because popBottom will decrement bottom, which will result in // an underflow if bottom is '0'. The paper's queue uses Java // 'long' for bottom and top and is thus safe since it's signed. - WsClV2Queue() : bottom(1), top(1) { } + WsClV2Queue() : bottom(1), top(1) {} bool pushBottom(const ITEM_TYPE item); bool popBottom(ITEM_TYPE *item); bool popTop(ITEM_TYPE *item); bool isFull() const; bool isEmpty() const; void print() const; - inline uintptr_t capacity() const { - return CAPACITY; - } - inline uint64_t usedSlots() const { - return bottom - top; - } - inline uintptr_t freeSlots() const { - return capacity() - usedSlots(); - } + inline uintptr_t capacity() const { return CAPACITY; } + inline uint64_t usedSlots() const { return bottom - top; } + inline uintptr_t freeSlots() const { return capacity() - usedSlots(); } }; -template<typename ITEM_TYPE, const uintptr_t CAPACITY> +template <typename ITEM_TYPE, const uintptr_t CAPACITY> bool WsClV2Queue<ITEM_TYPE, CAPACITY>::pushBottom(const ITEM_TYPE item) { // Check if queue is full. - if (isFull()) - return false; - + if (isFull()) return false; + queue[bottom % CAPACITY] = item; // TODO: Possible to move after fence? @@ -78,11 +70,11 @@ bool WsClV2Queue<ITEM_TYPE, CAPACITY>::pushBottom(const ITEM_TYPE item) { // Write fence / memory barrier atomic_thread_fence(std::memory_order_release); - + return true; } -template<typename ITEM_TYPE, const uintptr_t CAPACITY> +template <typename ITEM_TYPE, const uintptr_t CAPACITY> bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popBottom(ITEM_TYPE *item) { // TODO: new bottom value must be flushed out of the store buffer const uint64_t localBottom = --bottom; @@ -99,7 +91,8 @@ bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popBottom(ITEM_TYPE *item) { // There was no possiblity of a race. No atomic CAS required. if (localBottom > localTop) return true; - bool res = top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, std::memory_order_relaxed); + bool res = top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, + std::memory_order_relaxed); // Either a popTop() removed the element ('res' is false) or we // removed the element ('res' is true), but we need to increment // the 'bottom' value, since the element bottom pointed at is now @@ -109,9 +102,9 @@ bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popBottom(ITEM_TYPE *item) { return res; } -template<typename ITEM_TYPE, const uintptr_t CAPACITY> +template <typename ITEM_TYPE, const uintptr_t CAPACITY> bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popTop(ITEM_TYPE *item) { - start: +start: uint64_t localTop = top.load(std::memory_order_acquire); // Initially this fence was after the check if the queue is @@ -127,7 +120,8 @@ bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popTop(ITEM_TYPE *item) { // If cas fails, then this popTop() lost the race against another // popTop() or a rare-case popBottom(). - if (!top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, std::memory_order_relaxed)) { + if (!top.compare_exchange_weak(localTop, localTop + 1, std::memory_order_release, + std::memory_order_relaxed)) { // TODO: Return 'ABORT' enum value here. #ifdef WAIT_FREE_WS_QUEUE return false; @@ -139,14 +133,14 @@ bool WsClV2Queue<ITEM_TYPE, CAPACITY>::popTop(ITEM_TYPE *item) { return true; } -template<typename ITEM_TYPE, const uintptr_t CAPACITY> +template <typename ITEM_TYPE, const uintptr_t CAPACITY> bool WsClV2Queue<ITEM_TYPE, CAPACITY>::isFull() const { return usedSlots() >= CAPACITY; } -template<typename ITEM_TYPE, const uintptr_t CAPACITY> +template <typename ITEM_TYPE, const uintptr_t CAPACITY> bool WsClV2Queue<ITEM_TYPE, CAPACITY>::isEmpty() const { return top >= bottom; } -} // namespace adt +} // namespace adt diff --git a/emper/lib/sync/Latch.hpp b/emper/lib/sync/Latch.hpp index 2eb144cd..d13ee083 100644 --- a/emper/lib/sync/Latch.hpp +++ b/emper/lib/sync/Latch.hpp @@ -5,14 +5,13 @@ #include "Semaphore.hpp" class Latch { -private: + private: const unsigned int num; std::atomic<unsigned int> counter; emper::lib::sync::Semaphore semaphore; -public: - Latch(unsigned int counter) : num(counter), counter(counter), semaphore(0) { - } + public: + Latch(unsigned int counter) : num(counter), counter(counter), semaphore(0) {} inline void count_down_and_wait() { unsigned int current = counter.fetch_sub(1) - 1; diff --git a/emper/lib/sync/Semaphore.hpp b/emper/lib/sync/Semaphore.hpp index 46be64ec..a5d43ef1 100644 --- a/emper/lib/sync/Semaphore.hpp +++ b/emper/lib/sync/Semaphore.hpp @@ -1,7 +1,7 @@ #pragma once -#include <mutex> #include <condition_variable> +#include <mutex> namespace emper { @@ -10,14 +10,13 @@ namespace lib { namespace sync { class Semaphore { -private: + private: std::mutex m; std::condition_variable c; unsigned int counter; -public: - Semaphore(unsigned int counter = 0) : counter(counter) { - } + public: + Semaphore(unsigned int counter = 0) : counter(counter) {} inline void notify() { std::unique_lock<std::mutex> lock(m); @@ -38,8 +37,8 @@ public: } }; -} +} // namespace sync -} +} // namespace lib -} +} // namespace emper diff --git a/emper/strategies/laws/LawsDispatcher.cpp b/emper/strategies/laws/LawsDispatcher.cpp index 81dbd6f1..06a8566a 100644 --- a/emper/strategies/laws/LawsDispatcher.cpp +++ b/emper/strategies/laws/LawsDispatcher.cpp @@ -1,8 +1,8 @@ #include "LawsDispatcher.hpp" -#include "emper-config.h" -#include "Runtime.hpp" #include "LawsStrategy.hpp" +#include "Runtime.hpp" +#include "emper-config.h" void LawsDispatcher::dispatchLoop() { while (true) { @@ -21,23 +21,24 @@ void LawsDispatcher::dispatchLoop() { // is runnable. if (isRunnable(fiber)) { #ifdef EMPER_STATS - LawsStrategy::FiberSource fiberSource = static_cast<LawsStrategy::FiberSource>(fiber->getFlag()); + LawsStrategy::FiberSource fiberSource = + static_cast<LawsStrategy::FiberSource>(fiber->getFlag()); switch (fiberSource) { - case LawsStrategy::FiberSource::fromPriority: - lawsStrategy.dispatchedFiberFromPriority.fetch_add(1, std::memory_order_relaxed); - break; - case LawsStrategy::FiberSource::fromLocal: - lawsStrategy.dispatchedFiberFromLocal.fetch_add(1, std::memory_order_relaxed); - break; - case LawsStrategy::FiberSource::stolen: - lawsStrategy.dispatchedFiberStolen.fetch_add(1, std::memory_order_relaxed); - break; - case LawsStrategy::FiberSource::mainThread: - lawsStrategy.dispatchedFiberFromMainThread.fetch_add(1, std::memory_order_relaxed); - break; - default: - DIE_MSG("Unknown fiber flag: " << flag); - break; + case LawsStrategy::FiberSource::fromPriority: + lawsStrategy.dispatchedFiberFromPriority.fetch_add(1, std::memory_order_relaxed); + break; + case LawsStrategy::FiberSource::fromLocal: + lawsStrategy.dispatchedFiberFromLocal.fetch_add(1, std::memory_order_relaxed); + break; + case LawsStrategy::FiberSource::stolen: + lawsStrategy.dispatchedFiberStolen.fetch_add(1, std::memory_order_relaxed); + break; + case LawsStrategy::FiberSource::mainThread: + lawsStrategy.dispatchedFiberFromMainThread.fetch_add(1, std::memory_order_relaxed); + break; + default: + DIE_MSG("Unknown fiber flag: " << flag); + break; } #endif // The fiber was marked das runnable. Run it now. diff --git a/emper/strategies/laws/LawsDispatcher.hpp b/emper/strategies/laws/LawsDispatcher.hpp index 789fffd0..f45b6dce 100644 --- a/emper/strategies/laws/LawsDispatcher.hpp +++ b/emper/strategies/laws/LawsDispatcher.hpp @@ -1,27 +1,24 @@ #pragma once -#include "emper-config.h" #include "Dispatcher.hpp" +#include "emper-config.h" class LawsStrategy; class LawsDispatcher : public Dispatcher { - -private: - - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wattributes" + private: +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" LawsStrategy& lawsStrategy #ifndef EMPER_STATS - ATTR_UNUSED + ATTR_UNUSED #endif - ; - #pragma GCC diagnostic pop + ; +#pragma GCC diagnostic pop -public: - LawsDispatcher(Runtime& runtime, LawsStrategy& lawsStrategy) : Dispatcher(runtime) - , lawsStrategy(lawsStrategy) { - } + public: + LawsDispatcher(Runtime& runtime, LawsStrategy& lawsStrategy) + : Dispatcher(runtime), lawsStrategy(lawsStrategy) {} void dispatchLoop() override; }; diff --git a/emper/strategies/laws/LawsScheduler.cpp b/emper/strategies/laws/LawsScheduler.cpp index 2856e488..a9fea701 100644 --- a/emper/strategies/laws/LawsScheduler.cpp +++ b/emper/strategies/laws/LawsScheduler.cpp @@ -1,10 +1,10 @@ #include "LawsScheduler.hpp" -#include "emper-config.h" -#include "LawsStrategy.hpp" -#include "Debug.hpp" #include "Common.hpp" +#include "Debug.hpp" +#include "LawsStrategy.hpp" #include "Runtime.hpp" +#include "emper-config.h" #define EMPER_OVERFLOW_QUEUE @@ -12,8 +12,8 @@ thread_local LawsScheduler::LawsMpscQueue LawsScheduler::priorityQueue; thread_local LawsScheduler::WsQueue<LawsScheduler::QUEUE_SIZE> LawsScheduler::queue; -LawsScheduler::LawsScheduler(Runtime& runtime, LawsStrategy& lawsStrategy) : Scheduler(runtime) - , lawsStrategy(lawsStrategy) { +LawsScheduler::LawsScheduler(Runtime& runtime, LawsStrategy& lawsStrategy) + : Scheduler(runtime), lawsStrategy(lawsStrategy) { const workerid_t workerCount = runtime.getWorkerCount(); queues = new LawsScheduler::WsQueue<QUEUE_SIZE>*[workerCount]; priorityQueues = new LawsScheduler::LawsMpscQueue*[workerCount]; @@ -50,7 +50,7 @@ void LawsScheduler::schedule(Fiber& fiber) { #endif } - scheduleToLocalWsQueue: +scheduleToLocalWsQueue: bool pushed = queue.pushBottom(&fiber); if (unlikely(!pushed)) { #ifdef EMPER_OVERFLOW_QUEUE @@ -99,7 +99,7 @@ Fiber* LawsScheduler::nextFiber() { poped = queues[victim]->popTop(&fiber); if (poped) { #ifdef EMPER_STATS - unsigned int flag = static_cast<unsigned int>(LawsStrategy::FiberSource::stolen); + unsigned int flag = static_cast<unsigned int>(LawsStrategy::FiberSource::stolen); fiber->setFlag(flag); #endif return fiber; diff --git a/emper/strategies/laws/LawsScheduler.hpp b/emper/strategies/laws/LawsScheduler.hpp index 598fc2c9..5a8e1131 100644 --- a/emper/strategies/laws/LawsScheduler.hpp +++ b/emper/strategies/laws/LawsScheduler.hpp @@ -1,8 +1,8 @@ #pragma once -#include "emper-config.h" #include "Fiber.hpp" #include "Scheduler.hpp" +#include "emper-config.h" #include "lib/adt/LockedQueue.hpp" #include "lib/adt/LockedUnboundedQueue.hpp" #include "lib/adt/MpscQueue.hpp" @@ -10,7 +10,7 @@ class LawsStrategy; -class LawsScheduler: public Scheduler { +class LawsScheduler : public Scheduler { template <size_t SIZE> #ifdef EMPER_LOCKED_WS_QUEUE using WsQueue = adt::LockedQueue<Fiber*, SIZE>; @@ -20,17 +20,17 @@ class LawsScheduler: public Scheduler { typedef #ifdef EMPER_LOCKED_MPSC_QUEUE - adt::LockedUnboundedQueue + adt::LockedUnboundedQueue #else - adt::MpscQueue + adt::MpscQueue #endif - <Fiber> LawsMpscQueue; - + <Fiber> + LawsMpscQueue; -public: + public: static const int QUEUE_SIZE = 1024; -private: + private: LawsMpscQueue** priorityQueues; WsQueue<QUEUE_SIZE>** queues; @@ -41,21 +41,19 @@ private: WsQueue<QUEUE_SIZE>* mainThreadQueue; - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wattributes" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" LawsStrategy& lawsStrategy #ifndef EMPER_STATS - ATTR_UNUSED + ATTR_UNUSED #endif - ; - #pragma GCC diagnostic pop - -public: + ; +#pragma GCC diagnostic pop + public: LawsScheduler(Runtime& runtime, LawsStrategy& lawsStrategy); - + void schedule(Fiber& fiber) override; Fiber* nextFiber() override; - }; diff --git a/emper/strategies/laws/LawsStrategy.hpp b/emper/strategies/laws/LawsStrategy.hpp index b703e8e0..3b692dcf 100644 --- a/emper/strategies/laws/LawsStrategy.hpp +++ b/emper/strategies/laws/LawsStrategy.hpp @@ -1,22 +1,20 @@ #pragma once -#include "RuntimeStrategy.hpp" -#include "LawsScheduler.hpp" -#include "LawsDispatcher.hpp" -#include "LawsStrategyStats.hpp" - -#include <cstdint> #include <atomic> +#include <cstdint> #include <memory> +#include "LawsDispatcher.hpp" +#include "LawsScheduler.hpp" +#include "LawsStrategyStats.hpp" +#include "RuntimeStrategy.hpp" + class LawsScheduler; class LawsDispater; class LawsStrategy : public RuntimeStrategy { - -private: - - enum struct FiberSource: unsigned int { + private: + enum struct FiberSource : unsigned int { fromPriority, fromLocal, stolen, @@ -30,20 +28,19 @@ private: std::atomic<std::uint64_t> dispatchedFiberStolen; std::atomic<std::uint64_t> dispatchedFiberFromMainThread; - LawsStrategy() : scheduledFibersToRemotePriority(0) - , scheduledFibersToLocal(0) - , dispatchedFiberFromPriority(0) - , dispatchedFiberFromLocal(0) - , dispatchedFiberStolen(0) - , dispatchedFiberFromMainThread(0) { - } + LawsStrategy() + : scheduledFibersToRemotePriority(0), + scheduledFibersToLocal(0), + dispatchedFiberFromPriority(0), + dispatchedFiberFromLocal(0), + dispatchedFiberStolen(0), + dispatchedFiberFromMainThread(0) {} Scheduler& getScheduler(Runtime& runtime); Dispatcher& getDispatcher(Runtime& runtime); -public: - + public: virtual std::shared_ptr<RuntimeStrategyStats> getStats(); static LawsStrategy INSTANCE; diff --git a/emper/strategies/laws/LawsStrategyStats.cpp b/emper/strategies/laws/LawsStrategyStats.cpp index 2046668f..81584dac 100644 --- a/emper/strategies/laws/LawsStrategyStats.cpp +++ b/emper/strategies/laws/LawsStrategyStats.cpp @@ -1,36 +1,30 @@ -#include "LawsStrategy.hpp" #include "LawsStrategyStats.hpp" #include <iostream> +#include "LawsStrategy.hpp" + LawsStrategyStats::LawsStrategyStats(LawsStrategy& lawsStrategy) - : scheduledFibersToRemotePriority(lawsStrategy.scheduledFibersToRemotePriority) - , scheduledFibersToLocal(lawsStrategy.scheduledFibersToLocal) - , dispatchedFiberFromPriority(lawsStrategy.dispatchedFiberFromPriority) - , dispatchedFiberFromLocal(lawsStrategy.dispatchedFiberFromLocal) - , dispatchedFiberStolen(lawsStrategy.dispatchedFiberStolen) - , dispatchedFiberFromMainThread(lawsStrategy.dispatchedFiberFromMainThread) { -} + : scheduledFibersToRemotePriority(lawsStrategy.scheduledFibersToRemotePriority), + scheduledFibersToLocal(lawsStrategy.scheduledFibersToLocal), + dispatchedFiberFromPriority(lawsStrategy.dispatchedFiberFromPriority), + dispatchedFiberFromLocal(lawsStrategy.dispatchedFiberFromLocal), + dispatchedFiberStolen(lawsStrategy.dispatchedFiberStolen), + dispatchedFiberFromMainThread(lawsStrategy.dispatchedFiberFromMainThread) {} uint64_t LawsStrategyStats::getScheduledFibersToRemotePriority() const { return scheduledFibersToRemotePriority; } -uint64_t LawsStrategyStats::getScheduledFibersToLocal() const { - return scheduledFibersToLocal; -} +uint64_t LawsStrategyStats::getScheduledFibersToLocal() const { return scheduledFibersToLocal; } uint64_t LawsStrategyStats::getDispatchedFiberFromPriority() const { return dispatchedFiberFromPriority; } -uint64_t LawsStrategyStats::getDispatchedFiberFromLocal() const { - return dispatchedFiberFromLocal; -} +uint64_t LawsStrategyStats::getDispatchedFiberFromLocal() const { return dispatchedFiberFromLocal; } -uint64_t LawsStrategyStats::getDispatchedFiberStolen() const { - return dispatchedFiberStolen; -} +uint64_t LawsStrategyStats::getDispatchedFiberStolen() const { return dispatchedFiberStolen; } uint64_t LawsStrategyStats::getDispatchedFiberFromMainThread() const { return dispatchedFiberFromMainThread; @@ -38,11 +32,10 @@ uint64_t LawsStrategyStats::getDispatchedFiberFromMainThread() const { void LawsStrategyStats::print() { std::cout << "LawsStrategyStats" - << " scheduledFibersToRemotePriority:" << scheduledFibersToRemotePriority - << " scheduledFibersToLocal:" << scheduledFibersToLocal - << " dispatchedFiberFromPriority:" << dispatchedFiberFromPriority - << " dispatchedFiberFromLocal:" << dispatchedFiberFromLocal - << " dispatchedFiberStolen:" << dispatchedFiberStolen - << " dispatchedFiberFromMainThread:" << dispatchedFiberFromMainThread - << std::endl; + << " scheduledFibersToRemotePriority:" << scheduledFibersToRemotePriority + << " scheduledFibersToLocal:" << scheduledFibersToLocal + << " dispatchedFiberFromPriority:" << dispatchedFiberFromPriority + << " dispatchedFiberFromLocal:" << dispatchedFiberFromLocal + << " dispatchedFiberStolen:" << dispatchedFiberStolen + << " dispatchedFiberFromMainThread:" << dispatchedFiberFromMainThread << std::endl; } diff --git a/emper/strategies/laws/LawsStrategyStats.hpp b/emper/strategies/laws/LawsStrategyStats.hpp index 6c9e8292..d8cf7cf1 100644 --- a/emper/strategies/laws/LawsStrategyStats.hpp +++ b/emper/strategies/laws/LawsStrategyStats.hpp @@ -1,14 +1,13 @@ #pragma once -#include "RuntimeStrategyStats.hpp" - #include <cstdint> +#include "RuntimeStrategyStats.hpp" + class LawsStrategy; class LawsStrategyStats : public RuntimeStrategyStats { - -private: + private: const uint64_t scheduledFibersToRemotePriority; const uint64_t scheduledFibersToLocal; const uint64_t dispatchedFiberFromPriority; @@ -16,8 +15,7 @@ private: const uint64_t dispatchedFiberStolen; const uint64_t dispatchedFiberFromMainThread; -public: - + public: LawsStrategyStats(LawsStrategy& lawsStrategy); uint64_t getScheduledFibersToRemotePriority() const; diff --git a/emper/strategies/ws/WsDispatcher.cpp b/emper/strategies/ws/WsDispatcher.cpp index 9bbe4793..5f070d6e 100644 --- a/emper/strategies/ws/WsDispatcher.cpp +++ b/emper/strategies/ws/WsDispatcher.cpp @@ -1,8 +1,8 @@ #include "WsDispatcher.hpp" -#include "emper-config.h" -#include "Runtime.hpp" #include "Debug.hpp" +#include "Runtime.hpp" +#include "emper-config.h" void WsDispatcher::dispatchLoop() { while (true) { diff --git a/emper/strategies/ws/WsDispatcher.hpp b/emper/strategies/ws/WsDispatcher.hpp index 6e0be542..c3d70015 100644 --- a/emper/strategies/ws/WsDispatcher.hpp +++ b/emper/strategies/ws/WsDispatcher.hpp @@ -3,11 +3,8 @@ #include "Dispatcher.hpp" class WsDispatcher : public Dispatcher { + public: + WsDispatcher(Runtime& runtime) : Dispatcher(runtime){}; -public: - WsDispatcher(Runtime& runtime) : Dispatcher(runtime) { - }; - void dispatchLoop() override; - }; diff --git a/emper/strategies/ws/WsScheduler.cpp b/emper/strategies/ws/WsScheduler.cpp index 7dd98d97..eec4cfa6 100644 --- a/emper/strategies/ws/WsScheduler.cpp +++ b/emper/strategies/ws/WsScheduler.cpp @@ -1,14 +1,14 @@ #include "WsScheduler.hpp" -#include "emper-config.h" -#include "Debug.hpp" #include "Common.hpp" +#include "Debug.hpp" #include "Runtime.hpp" +#include "emper-config.h" thread_local WsScheduler::WsQueue<WsScheduler::QUEUE_SIZE> WsScheduler::queue; -WsScheduler::WsScheduler(Runtime& runtime, WsStrategy& wsStrategy) : Scheduler(runtime) - , wsStrategy(wsStrategy) { +WsScheduler::WsScheduler(Runtime& runtime, WsStrategy& wsStrategy) + : Scheduler(runtime), wsStrategy(wsStrategy) { const workerid_t workerCount = runtime.getWorkerCount(); queues = new WsScheduler::WsQueue<QUEUE_SIZE>*[workerCount]; mainThreadQueue = &queue; @@ -44,7 +44,7 @@ Fiber* WsScheduler::nextFiber() { if (likely(poped)) { #ifdef EMPER_STATS - wsStrategy.nextFiberFromLocal.fetch_add(1, std::memory_order_relaxed); + wsStrategy.nextFiberFromLocal.fetch_add(1, std::memory_order_relaxed); #endif return fiber; } @@ -61,7 +61,7 @@ Fiber* WsScheduler::nextFiber() { poped = queues[victim]->popTop(&fiber); if (poped) { #ifdef EMPER_STATS - wsStrategy.nextFiberStolen.fetch_add(1, std::memory_order_relaxed); + wsStrategy.nextFiberStolen.fetch_add(1, std::memory_order_relaxed); #endif return fiber; } diff --git a/emper/strategies/ws/WsScheduler.hpp b/emper/strategies/ws/WsScheduler.hpp index 4667475a..9d1c3454 100644 --- a/emper/strategies/ws/WsScheduler.hpp +++ b/emper/strategies/ws/WsScheduler.hpp @@ -8,7 +8,7 @@ class WsStrategy; -class WsScheduler: public Scheduler { +class WsScheduler : public Scheduler { template <size_t SIZE> #ifdef EMPER_LOCKED_WS_QUEUE using WsQueue = adt::LockedQueue<Fiber*, SIZE>; @@ -16,30 +16,28 @@ class WsScheduler: public Scheduler { using WsQueue = adt::WsClQueue<Fiber*, SIZE>; #endif -public: + public: static const int QUEUE_SIZE = 1024; -private: + private: WsQueue<QUEUE_SIZE>** queues; static thread_local WsQueue<QUEUE_SIZE> queue; WsQueue<QUEUE_SIZE>* mainThreadQueue; - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wattributes" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wattributes" WsStrategy& wsStrategy #ifndef EMPER_STATS - ATTR_UNUSED + ATTR_UNUSED #endif - ; - #pragma GCC diagnostic pop - -public: + ; +#pragma GCC diagnostic pop + public: WsScheduler(Runtime& runtime, WsStrategy& wsStrategy); - + void schedule(Fiber& fiber) override; Fiber* nextFiber() override; - }; diff --git a/emper/strategies/ws/WsStrategy.cpp b/emper/strategies/ws/WsStrategy.cpp index 7cba27ce..b9b78d91 100644 --- a/emper/strategies/ws/WsStrategy.cpp +++ b/emper/strategies/ws/WsStrategy.cpp @@ -1,7 +1,7 @@ #include "WsStrategy.hpp" -#include "WsScheduler.hpp" #include "WsDispatcher.hpp" +#include "WsScheduler.hpp" WsStrategy WsStrategy::INSTANCE; diff --git a/emper/strategies/ws/WsStrategy.hpp b/emper/strategies/ws/WsStrategy.hpp index 1a094d34..269e93f6 100644 --- a/emper/strategies/ws/WsStrategy.hpp +++ b/emper/strategies/ws/WsStrategy.hpp @@ -1,12 +1,12 @@ #pragma once -#include "RuntimeStrategy.hpp" -#include "WsStrategyStats.hpp" - -#include <cstdint> #include <atomic> +#include <cstdint> #include <memory> +#include "RuntimeStrategy.hpp" +#include "WsStrategyStats.hpp" + class Scheduler; class Dispatcher; @@ -14,24 +14,18 @@ class WsScheduler; class WsDispatcher; class WsStrategy : public RuntimeStrategy { - -private: - + private: std::atomic<std::uint64_t> scheduledFibers; std::atomic<std::uint64_t> nextFiberFromLocal; std::atomic<std::uint64_t> nextFiberStolen; - WsStrategy() : scheduledFibers(0) - , nextFiberFromLocal(0) - , nextFiberStolen(0) { - } + WsStrategy() : scheduledFibers(0), nextFiberFromLocal(0), nextFiberStolen(0) {} Scheduler& getScheduler(Runtime& runtime); Dispatcher& getDispatcher(Runtime& runtime); - -public: + public: virtual std::shared_ptr<RuntimeStrategyStats> getStats(); static WsStrategy INSTANCE; diff --git a/emper/strategies/ws/WsStrategyStats.cpp b/emper/strategies/ws/WsStrategyStats.cpp index 2379d5bf..d3925dfc 100644 --- a/emper/strategies/ws/WsStrategyStats.cpp +++ b/emper/strategies/ws/WsStrategyStats.cpp @@ -1,30 +1,23 @@ -#include "WsStrategy.hpp" #include "WsStrategyStats.hpp" #include <iostream> +#include "WsStrategy.hpp" + WsStrategyStats::WsStrategyStats(WsStrategy& wsStrategy) - : scheduledFibers(wsStrategy.scheduledFibers) - , nextFiberFromLocal(wsStrategy.nextFiberFromLocal) - , nextFiberStolen(wsStrategy.nextFiberStolen) { -} + : scheduledFibers(wsStrategy.scheduledFibers), + nextFiberFromLocal(wsStrategy.nextFiberFromLocal), + nextFiberStolen(wsStrategy.nextFiberStolen) {} -uint64_t WsStrategyStats::getScheduledFibers() const { - return scheduledFibers; -} +uint64_t WsStrategyStats::getScheduledFibers() const { return scheduledFibers; } -uint64_t WsStrategyStats::getNextFiberFromLocal() const { - return nextFiberFromLocal; -} +uint64_t WsStrategyStats::getNextFiberFromLocal() const { return nextFiberFromLocal; } -uint64_t WsStrategyStats::getNextFiberStolen() const { - return nextFiberStolen; -} +uint64_t WsStrategyStats::getNextFiberStolen() const { return nextFiberStolen; } void WsStrategyStats::print() { std::cout << "WsStrategyStats" - << " scheduledFibers:" << scheduledFibers - << " nextFiberFromLocal:" << nextFiberFromLocal - << " nextFiberStolen:" << nextFiberStolen - << std::endl; + << " scheduledFibers:" << scheduledFibers + << " nextFiberFromLocal:" << nextFiberFromLocal + << " nextFiberStolen:" << nextFiberStolen << std::endl; } diff --git a/emper/strategies/ws/WsStrategyStats.hpp b/emper/strategies/ws/WsStrategyStats.hpp index 9aa66bcb..cb5a14ad 100644 --- a/emper/strategies/ws/WsStrategyStats.hpp +++ b/emper/strategies/ws/WsStrategyStats.hpp @@ -1,20 +1,18 @@ #pragma once -#include "RuntimeStrategyStats.hpp" - #include <cstdint> +#include "RuntimeStrategyStats.hpp" + class WsStrategy; class WsStrategyStats : public RuntimeStrategyStats { - -private: + private: const uint64_t scheduledFibers; const uint64_t nextFiberFromLocal; const uint64_t nextFiberStolen; -public: - + public: WsStrategyStats(WsStrategy& wsStrategy); uint64_t getScheduledFibers() const; diff --git a/eval/Locality.cpp b/eval/Locality.cpp index 2a6e6a16..7d1f7ded 100644 --- a/eval/Locality.cpp +++ b/eval/Locality.cpp @@ -1,22 +1,23 @@ -#include "Fiber.hpp" -#include "Runtime.hpp" -#include "Dispatcher.hpp" -#include "PrivateSemaphore.hpp" -#include "CountingPrivateSemaphore.hpp" -#include "strategies/laws/LawsStrategy.hpp" -#include "lib/DebugUtil.hpp" +#include <unistd.h> #include <algorithm> -#include <random> #include <cstdint> +#include <random> #include <thread> -#include <unistd.h> -#define L1_CACHE_LINE_SIZE 64 // 64 Bytes +#include "CountingPrivateSemaphore.hpp" +#include "Dispatcher.hpp" +#include "Fiber.hpp" +#include "PrivateSemaphore.hpp" +#include "Runtime.hpp" +#include "lib/DebugUtil.hpp" +#include "strategies/laws/LawsStrategy.hpp" -#define L1_DCACHE_SIZE (32*1024) // 32 KiB -#define L2_DCACHE_SIZE (256*1024) // 256 KiB -#define L3_DCACHE_SIZE (4096*1024) // 4 MiB +#define L1_CACHE_LINE_SIZE 64 // 64 Bytes + +#define L1_DCACHE_SIZE (32 * 1024) // 32 KiB +#define L2_DCACHE_SIZE (256 * 1024) // 256 KiB +#define L3_DCACHE_SIZE (4096 * 1024) // 4 MiB //#define FIBER_METADATA @@ -41,17 +42,11 @@ struct State { workeraffinity_t* affinity; uint8_t* data; FiberMetadata* fiberMetadata; - //std::map<unsigned int, std::vector<FiberMetadata>> fiberMetadata; - - State(Runtime& runtime, - unsigned int fiberCount, - unsigned int bytesPerFiber, - unsigned int rounds, - unsigned int seed) : - fiberCount(fiberCount) , - bytesPerFiber(bytesPerFiber) , - rounds(rounds) , - runtime(runtime) { + // std::map<unsigned int, std::vector<FiberMetadata>> fiberMetadata; + + State(Runtime& runtime, unsigned int fiberCount, unsigned int bytesPerFiber, unsigned int rounds, + unsigned int seed) + : fiberCount(fiberCount), bytesPerFiber(bytesPerFiber), rounds(rounds), runtime(runtime) { randomGenerator = std::mt19937(seed); affinity = new workeraffinity_t[fiberCount]; for (unsigned int i = 0; i < fiberCount; ++i) { @@ -66,16 +61,14 @@ struct State { } ~State() { - delete [] affinity; - delete [] data; + delete[] affinity; + delete[] data; #ifdef FIBER_METADATA - delete [] fiberMetadata; + delete[] fiberMetadata; #endif } - uint8_t getNextRandom() { - return UINT8_UNIFORM_DISTRIBUTION(randomGenerator); - } + uint8_t getNextRandom() { return UINT8_UNIFORM_DISTRIBUTION(randomGenerator); } FiberMetadata* getFiberMetadata(unsigned int fiberNum, unsigned int roundNum) { return fiberMetadata + (fiberNum * fiberCount) + roundNum; @@ -95,9 +88,9 @@ struct FiberArgs { static void performRound(State& state, #ifndef FIBER_METADATA - UNUSED_ARG + UNUSED_ARG #endif - unsigned int round) { + unsigned int round) { uint8_t roundData = state.getNextRandom(); CPS cps(state.fiberCount); @@ -114,49 +107,50 @@ static void performRound(State& state, fiberArgs[i].fiberMetadata = state.getFiberMetadata(i, round); #endif - Fiber* fiber = Fiber::from([](void* fiberArgsPtr) { - FiberArgs* fiberArgs = (FiberArgs*) fiberArgsPtr; + Fiber* fiber = Fiber::from( + [](void* fiberArgsPtr) { + FiberArgs* fiberArgs = (FiberArgs*)fiberArgsPtr; #ifdef FIBER_METADATA - FiberMetadata* fiberMetadata = fiberArgs->fiberMetadata; + FiberMetadata* fiberMetadata = fiberArgs->fiberMetadata; - fiberMetadata->start = std::chrono::high_resolution_clock::now(); - fiberMetadata->workerId = Runtime::getWorkerId(); - fiberMetadata->currentAffinity = Dispatcher::getCurrentFiber().getAffinity(); + fiberMetadata->start = std::chrono::high_resolution_clock::now(); + fiberMetadata->workerId = Runtime::getWorkerId(); + fiberMetadata->currentAffinity = Dispatcher::getCurrentFiber().getAffinity(); #endif - uint8_t* fiberData = fiberArgs->fiberData; - unsigned int bytesPerFiber = fiberArgs->state->bytesPerFiber; - for (unsigned int j = (bytesPerFiber - 1); j > (bytesPerFiber - 10); --j) { - for (unsigned int i = 0; i < bytesPerFiber; i++) { - unsigned int next = (i + L1_DCACHE_SIZE + fiberData[j]) % bytesPerFiber; - fiberData[i] -= fiberData[next]; - - fiberData[i] += fiberArgs->roundData; - /* - if (fiberData[i] < 128) { - fiberData[i] += fiberArgs->roundData / 2; - } - if (fiberData[i] > 192) { - fiberData[i] -= (fiberArgs->roundData * 4); - } - - if (i == (bytesPerFiber * 0.75)) { - if (fiberData[i] < 128) { - break; + uint8_t* fiberData = fiberArgs->fiberData; + unsigned int bytesPerFiber = fiberArgs->state->bytesPerFiber; + for (unsigned int j = (bytesPerFiber - 1); j > (bytesPerFiber - 10); --j) { + for (unsigned int i = 0; i < bytesPerFiber; i++) { + unsigned int next = (i + L1_DCACHE_SIZE + fiberData[j]) % bytesPerFiber; + fiberData[i] -= fiberData[next]; + + fiberData[i] += fiberArgs->roundData; + /* + if (fiberData[i] < 128) { + fiberData[i] += fiberArgs->roundData / 2; + } + if (fiberData[i] > 192) { + fiberData[i] -= (fiberArgs->roundData * 4); + } + + if (i == (bytesPerFiber * 0.75)) { + if (fiberData[i] < 128) { + break; + } + } + */ } } - */ - } - } - #ifdef FIBER_METADATA - fiberMetadata->end = std::chrono::high_resolution_clock::now(); + fiberMetadata->end = std::chrono::high_resolution_clock::now(); #endif - fiberArgs->ps->signal(); - }, (void*) (fiberArgs + i), state.affinity + i); + fiberArgs->ps->signal(); + }, + (void*)(fiberArgs + i), state.affinity + i); state.runtime.schedule(*fiber); } @@ -165,7 +159,7 @@ static void performRound(State& state, DBG("Finished round " << round); - delete [] fiberArgs; + delete[] fiberArgs; } /* @@ -189,28 +183,22 @@ static void printState(State& state) { POP_DIAGNOSTIC */ -static void run(Runtime& runtime, - unsigned int fiberCount, - unsigned int bytesPerFiber, - unsigned int rounds, - unsigned int seed) { - +static void run(Runtime& runtime, unsigned int fiberCount, unsigned int bytesPerFiber, + unsigned int rounds, unsigned int seed) { runtime.executeAndWait([&] { - State state(runtime, fiberCount, bytesPerFiber, rounds, seed); + State state(runtime, fiberCount, bytesPerFiber, rounds, seed); - auto start = std::chrono::high_resolution_clock::now(); - for (unsigned int i = 0; i < state.rounds; ++i) { - performRound(state, i); - } - auto end = std::chrono::high_resolution_clock::now(); + auto start = std::chrono::high_resolution_clock::now(); + for (unsigned int i = 0; i < state.rounds; ++i) { + performRound(state, i); + } + auto end = std::chrono::high_resolution_clock::now(); - auto diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start); + auto diff = std::chrono::duration_cast<std::chrono::microseconds>(end - start); - std::cout << "Inner " - << diff.count() << " us" - << std::endl; - //printState(state); - }); + std::cout << "Inner " << diff.count() << " us" << std::endl; + // printState(state); + }); } enum RuntimeVariant { @@ -218,7 +206,7 @@ enum RuntimeVariant { wslh, }; -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { enableStacktraceOnAborts(); RuntimeVariant runtimeVariant = ws; @@ -229,19 +217,19 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { while ((opt = getopt(argc, argv, "m:")) != -1) { std::string optargString; switch (opt) { - case 'm': - optargString = std::string(optarg); - if (optargString == "ws") { - runtimeVariant = ws; - } else if (optargString == "wslh") { - runtimeVariant = wslh; - } else { - std::cerr << "Invalid -m argument " << optargString << std::endl; + case 'm': + optargString = std::string(optarg); + if (optargString == "ws") { + runtimeVariant = ws; + } else if (optargString == "wslh") { + runtimeVariant = wslh; + } else { + std::cerr << "Invalid -m argument " << optargString << std::endl; + abort(); + } + break; + default: abort(); - } - break; - default: - abort(); } } @@ -253,10 +241,12 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { Runtime* runtime; switch (runtimeVariant) { - case ws: - runtime = new Runtime(); break; - case wslh: - runtime = new Runtime(LawsStrategy::INSTANCE); break; + case ws: + runtime = new Runtime(); + break; + case wslh: + runtime = new Runtime(LawsStrategy::INSTANCE); + break; } start = std::chrono::high_resolution_clock::now(); @@ -266,15 +256,15 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { std::string variantName; switch (runtimeVariant) { - case ws: - variantName = "W/o Locality: "; break; - case wslh: - variantName = "W Locality: "; break; + case ws: + variantName = "W/o Locality: "; + break; + case wslh: + variantName = "W Locality: "; + break; } - std::cout << variantName - << diff.count() << " us" - << std::endl; + std::cout << variantName << diff.count() << " us" << std::endl; exit(EXIT_SUCCESS); } diff --git a/eval/SpawnALot.cpp b/eval/SpawnALot.cpp index c9b295a8..9b99d72e 100644 --- a/eval/SpawnALot.cpp +++ b/eval/SpawnALot.cpp @@ -1,24 +1,25 @@ -#include "Runtime.hpp" -#include "PrivateSemaphore.hpp" #include "BinaryPrivateSemaphore.hpp" #include "CountingPrivateSemaphore.hpp" +#include "PrivateSemaphore.hpp" +#include "Runtime.hpp" #include "lib/DebugUtil.hpp" #define CACHE_LINE_SIZE 64 -static void spawnALotThreadsRecursiveTFun(unsigned int depth, unsigned int width, unsigned int current_depth) { - if (current_depth == depth) return; +static void spawnALotThreadsRecursiveTFun(unsigned int depth, unsigned int width, + unsigned int current_depth) { + if (current_depth == depth) return; - std::thread* threads = new std::thread[width]; - const unsigned int new_depth = current_depth + 1; - for (unsigned int i = 0; i < width; ++i) { - threads[i] = std::thread(spawnALotThreadsRecursiveTFun, depth, width, new_depth); - } - for (unsigned int i = 0; i < width; ++i) { - threads[i].join(); - } + std::thread* threads = new std::thread[width]; + const unsigned int new_depth = current_depth + 1; + for (unsigned int i = 0; i < width; ++i) { + threads[i] = std::thread(spawnALotThreadsRecursiveTFun, depth, width, new_depth); + } + for (unsigned int i = 0; i < width; ++i) { + threads[i].join(); + } - delete[] threads; + delete[] threads; } static void spawnALotThreadsRecursive(unsigned int depth, unsigned int width) { @@ -30,9 +31,7 @@ static void spawnALotThreadsNonRecursive(uint64_t count) { uint8_t* flags = new uint8_t[count * CACHE_LINE_SIZE]; std::thread* threads = new std::thread[count]; for (uint64_t i = 0; i < count; ++i) { - threads[i] = std::thread([&flags, i] { - flags[i * CACHE_LINE_SIZE] = 1; - }); + threads[i] = std::thread([&flags, i] { flags[i * CACHE_LINE_SIZE] = 1; }); } for (uint64_t i = 0; i < count; ++i) { @@ -51,31 +50,24 @@ struct SpawnALotFibersData { unsigned int current_depth; SpawnALotFibersData(SpawnALotFibersData* oldData, PS& ps) - : runtime(oldData->runtime) - , depth(oldData->depth) - , width(oldData->width) - , ps(ps) - , current_depth(oldData->current_depth + 1) { - } + : runtime(oldData->runtime), + depth(oldData->depth), + width(oldData->width), + ps(ps), + current_depth(oldData->current_depth + 1) {} SpawnALotFibersData(Runtime& runtime, unsigned int depth, unsigned int width, PS& ps) - : runtime(runtime) - , depth(depth) - , width(width) - , ps(ps) - , current_depth(0) { - } - + : runtime(runtime), depth(depth), width(width), ps(ps), current_depth(0) {} }; static void spawnALotFibersRecursiveFFun(void* dataPtr) { - SpawnALotFibersData* data = (SpawnALotFibersData*) dataPtr; + SpawnALotFibersData* data = (SpawnALotFibersData*)dataPtr; if (data->current_depth < data->depth) { CPS childSem(data->width); SpawnALotFibersData newData(data, childSem); for (unsigned int i = 0; i < data->width; ++i) { - Fiber* fiber = Fiber::from(spawnALotFibersRecursiveFFun, (void*) &newData); + Fiber* fiber = Fiber::from(spawnALotFibersRecursiveFFun, (void*)&newData); data->runtime.schedule(*fiber); } @@ -89,7 +81,7 @@ static void spawnALotFibersRecursive(Runtime& runtime, unsigned int depth, unsig BPS bps; SpawnALotFibersData data(runtime, depth, width, bps); - Fiber* fiber = Fiber::from(spawnALotFibersRecursiveFFun, (void*) &data); + Fiber* fiber = Fiber::from(spawnALotFibersRecursiveFFun, (void*)&data); runtime.schedule(*fiber); bps.wait(); @@ -101,9 +93,9 @@ static void spawnALotFibersNonRecursive(Runtime& runtime, uint64_t count) { for (uint64_t i = 0; i < count; ++i) { Fiber* fiber = Fiber::from([i, &cps, flags] { - flags[i * CACHE_LINE_SIZE] = 1; - cps.signal(); - }); + flags[i * CACHE_LINE_SIZE] = 1; + cps.signal(); + }); runtime.schedule(*fiber); } @@ -112,7 +104,7 @@ static void spawnALotFibersNonRecursive(Runtime& runtime, uint64_t count) { delete[] flags; } -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { enableStacktraceOnAborts(); const uint64_t count = 1024; @@ -125,46 +117,38 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { start = std::chrono::high_resolution_clock::now(); spawnALotThreadsRecursive(depth, width); end = std::chrono::high_resolution_clock::now(); - diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start); - std::cout << "Spawn a lot of threads recursive (depth=" - << depth << ", width=" - << width << ") took " << std::endl - << diff.count() << " ns" - << std::endl; + diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); + std::cout << "Spawn a lot of threads recursive (depth=" << depth << ", width=" << width + << ") took " << std::endl + << diff.count() << " ns" << std::endl; start = std::chrono::high_resolution_clock::now(); spawnALotThreadsNonRecursive(count); end = std::chrono::high_resolution_clock::now(); - diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start); - std::cout << "Spawn a lot of threads non-recursive (count=" - << count << ") took " << std::endl - << diff.count() << " ns" - << " (" << diff.count() / count << " ns/thread)" - << std::endl; + diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); + std::cout << "Spawn a lot of threads non-recursive (count=" << count << ") took " << std::endl + << diff.count() << " ns" + << " (" << diff.count() / count << " ns/thread)" << std::endl; Runtime runtime; runtime.executeAndWait([&] { - start = std::chrono::high_resolution_clock::now(); - spawnALotFibersRecursive(runtime, depth, width); - end = std::chrono::high_resolution_clock::now(); - diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start); - std::cout << "Spawn a lot of fibers recursive (depth=" - << depth << ", width=" - << width << ") took " << std::endl - << diff.count() << " ns" - << std::endl; - - start = std::chrono::high_resolution_clock::now(); - spawnALotFibersNonRecursive(runtime, count); - end = std::chrono::high_resolution_clock::now(); - diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start); - std::cout << "Spawn a lot of fibers non-recursive (count=" - << count << ") took " << std::endl - << diff.count() << " ns" - << " (" << diff.count() / count << " ns/fiber)" - << std::endl; - }); + start = std::chrono::high_resolution_clock::now(); + spawnALotFibersRecursive(runtime, depth, width); + end = std::chrono::high_resolution_clock::now(); + diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); + std::cout << "Spawn a lot of fibers recursive (depth=" << depth << ", width=" << width + << ") took " << std::endl + << diff.count() << " ns" << std::endl; + + start = std::chrono::high_resolution_clock::now(); + spawnALotFibersNonRecursive(runtime, count); + end = std::chrono::high_resolution_clock::now(); + diff = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); + std::cout << "Spawn a lot of fibers non-recursive (count=" << count << ") took " << std::endl + << diff.count() << " ns" + << " (" << diff.count() / count << " ns/fiber)" << std::endl; + }); return EXIT_SUCCESS; } diff --git a/eval/TimeToSpawn.cpp b/eval/TimeToSpawn.cpp index 5e6bb532..9be3ee43 100644 --- a/eval/TimeToSpawn.cpp +++ b/eval/TimeToSpawn.cpp @@ -1,17 +1,14 @@ -#include "Runtime.hpp" -#include "BinaryPrivateSemaphore.hpp" - #include <chrono> -#include <thread> #include <mutex> +#include <thread> -static std::chrono::nanoseconds threadTimeToSpawn() { +#include "BinaryPrivateSemaphore.hpp" +#include "Runtime.hpp" +static std::chrono::nanoseconds threadTimeToSpawn() { std::chrono::time_point<std::chrono::high_resolution_clock> end; auto start = std::chrono::high_resolution_clock::now(); - std::thread t([&end] { - end = std::chrono::high_resolution_clock::now(); - }); + std::thread t([&end] { end = std::chrono::high_resolution_clock::now(); }); t.join(); return std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); @@ -25,20 +22,20 @@ static std::chrono::nanoseconds fiberTimeToSpawn() { testFinished.lock(); Fiber* fiber = Fiber::from([&runtime, &res, &testFinished] { - BPS bps; - std::chrono::time_point<std::chrono::high_resolution_clock> end; - Fiber* fiber = Fiber::from([&end, &bps] { - end = std::chrono::high_resolution_clock::now(); - bps.signal(); - }); + BPS bps; + std::chrono::time_point<std::chrono::high_resolution_clock> end; + Fiber* fiber = Fiber::from([&end, &bps] { + end = std::chrono::high_resolution_clock::now(); + bps.signal(); + }); - auto start = std::chrono::high_resolution_clock::now(); - runtime.schedule(*fiber); + auto start = std::chrono::high_resolution_clock::now(); + runtime.schedule(*fiber); - bps.wait(); - res = std::chrono::duration_cast<std::chrono::nanoseconds>(end -start); - testFinished.unlock(); - }); + bps.wait(); + res = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); + testFinished.unlock(); + }); runtime.schedule(*fiber); testFinished.lock(); @@ -47,18 +44,14 @@ static std::chrono::nanoseconds fiberTimeToSpawn() { return res; } -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { { auto ttts = threadTimeToSpawn(); - std::cout << "Thread time to spawn: " - << ttts.count() << " ns" - << std::endl; + std::cout << "Thread time to spawn: " << ttts.count() << " ns" << std::endl; } { auto ftts = fiberTimeToSpawn(); - std::cout << "Fiber time to spawn: " - << ftts.count() << " ns" - << std::endl; + std::cout << "Fiber time to spawn: " << ftts.count() << " ns" << std::endl; } } diff --git a/tests/CppApiTest.cpp b/tests/CppApiTest.cpp index 71077710..6308da48 100644 --- a/tests/CppApiTest.cpp +++ b/tests/CppApiTest.cpp @@ -1,14 +1,11 @@ -#include "emper.hpp" - #include <atomic> #include "CountingPrivateSemaphore.hpp" +#include "emper.hpp" static std::atomic_uint counter; -static void increaseCounterByOne() { - counter++; -} +static void increaseCounterByOne() { counter++; } static void mainFiber(void) { const unsigned int FIBER_COUNT = 100; @@ -17,7 +14,7 @@ static void mainFiber(void) { for (unsigned int i = 0; i < FIBER_COUNT; ++i) { spawn(&increaseCounterByOne, cps); - } + } cps.wait(); diff --git a/tests/SimpleActorTest.cpp b/tests/SimpleActorTest.cpp index b603356d..d0fd44f4 100644 --- a/tests/SimpleActorTest.cpp +++ b/tests/SimpleActorTest.cpp @@ -1,27 +1,22 @@ +#include <atomic> +#include <mutex> + #include "Actor.hpp" -#include "Runtime.hpp" #include "CountingPrivateSemaphore.hpp" -#include "Dispatcher.hpp" #include "Debug.hpp" +#include "Dispatcher.hpp" +#include "Runtime.hpp" #include "emper.hpp" -#include <atomic> -#include <mutex> - class SumActor : public Actor<uint64_t> { -private: + private: uint64_t sum = 0; - -protected: - virtual void receive(uint64_t t) override { - sum += t; - } - -public: + protected: + virtual void receive(uint64_t t) override { sum += t; } - SumActor(Runtime& runtime) : Actor(runtime) { - } + public: + SumActor(Runtime& runtime) : Actor(runtime) {} uint64_t getSum() { std::atomic_thread_fence(std::memory_order::memory_order_acquire); @@ -30,7 +25,7 @@ public: }; static void mainFiber(void* runtime_ptr) { - Runtime& runtime = * (Runtime*) runtime_ptr; + Runtime& runtime = *(Runtime*)runtime_ptr; const unsigned int FIBER_COUNT = 1000; const uint64_t FIBERS_COUNT_TO = 1000; const uint64_t PER_FIBER_SUM = (FIBERS_COUNT_TO * (FIBERS_COUNT_TO + 1)) / 2; @@ -41,12 +36,14 @@ static void mainFiber(void* runtime_ptr) { CPS cps; for (unsigned int i = 0; i < FIBER_COUNT; ++i) { - spawn([&sumActor] { - WDBG(Dispatcher::getCurrentFiber() << " starts to count to " << FIBERS_COUNT_TO); - for (uint64_t i = 1; i <= FIBERS_COUNT_TO; ++i) { - sumActor.tell(i); - } - }, cps); + spawn( + [&sumActor] { + WDBG(Dispatcher::getCurrentFiber() << " starts to count to " << FIBERS_COUNT_TO); + for (uint64_t i = 1; i <= FIBERS_COUNT_TO; ++i) { + sumActor.tell(i); + } + }, + cps); } // Wait for the producer fibers to finish. @@ -60,17 +57,18 @@ static void mainFiber(void* runtime_ptr) { } if (sumActor.getSum() != EXPECTED_SUM) { - std::cerr << "FAILURE: Actor sum " << sumActor.getSum() << " is not equal to expected sum " << EXPECTED_SUM << std::endl; + std::cerr << "FAILURE: Actor sum " << sumActor.getSum() << " is not equal to expected sum " + << EXPECTED_SUM << std::endl; exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } -int main(UNUSED_ARG int arg, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int arg, UNUSED_ARG char* argv[]) { Runtime runtime; - Fiber* fiber = Fiber::from(mainFiber, (void*) &runtime); + Fiber* fiber = Fiber::from(mainFiber, (void*)&runtime); runtime.schedule(*fiber); runtime.waitUntilFinished(); diff --git a/tests/SimpleFibTest.cpp b/tests/SimpleFibTest.cpp index d31da0d7..cd29790a 100644 --- a/tests/SimpleFibTest.cpp +++ b/tests/SimpleFibTest.cpp @@ -1,15 +1,16 @@ #include <stdio.h> #include <stdlib.h> + #include <iostream> #include <list> #include <string> -#include "Runtime.hpp" -#include "Common.hpp" -#include "PrivateSemaphore.hpp" #include "BinaryPrivateSemaphore.hpp" +#include "Common.hpp" #include "CountingPrivateSemaphore.hpp" #include "Debug.hpp" +#include "PrivateSemaphore.hpp" +#include "Runtime.hpp" typedef struct { int n; @@ -17,10 +18,10 @@ typedef struct { PS* sem; } fibParams; -static void fib(void *voidParams) { +static void fib(void* voidParams) { fibParams* params = static_cast<fibParams*>(voidParams); int n = params->n; - int *result = params->result; + int* result = params->result; PS* sem = params->sem; if (n < 2) { @@ -54,15 +55,15 @@ static void fib(void *voidParams) { sem->signalAndExit(); } - -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { Runtime runtime; - Fiber* fibFiber = Fiber::from([] (UNUSED_ARG void* arg) { + Fiber* fibFiber = Fiber::from( + [](UNUSED_ARG void* arg) { const int fibNum = 13; int result; BPS sem; - fibParams params = { fibNum, &result, &sem }; + fibParams params = {fibNum, &result, &sem}; fib(¶ms); @@ -73,11 +74,12 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { } exit(EXIT_SUCCESS); - }, nullptr); + }, + nullptr); runtime.schedule(*fibFiber); runtime.waitUntilFinished(); - - return EXIT_FAILURE; + + return EXIT_FAILURE; } diff --git a/tests/SimpleLawsTest.cpp b/tests/SimpleLawsTest.cpp index 6b305515..98ad269f 100644 --- a/tests/SimpleLawsTest.cpp +++ b/tests/SimpleLawsTest.cpp @@ -1,10 +1,9 @@ -#include "emper.hpp" +#include <random> #include "Fiber.hpp" +#include "emper.hpp" #include "strategies/laws/LawsStrategy.hpp" -#include <random> - static const unsigned int ROUND_COUNT = 10; static const unsigned int FIBER_LOOPS = 10; static const unsigned int PAYLOAD_COUNT = 4096; @@ -20,7 +19,6 @@ typedef struct ALIGN_TO_CACHE_LINE { workeraffinity_t affinity; } AlignedWorkerAffinity; - static void fiberFun(void* voidFiberData) { FiberData* fiberData = static_cast<FiberData*>(voidFiberData); @@ -42,7 +40,7 @@ static void alphaFun() { Runtime* runtime = Runtime::getRuntime(); const unsigned int FIBER_COUNT = runtime->getWorkerCount() + 3; - AlignedWorkerAffinity *affinities = new AlignedWorkerAffinity[FIBER_COUNT]; + AlignedWorkerAffinity* affinities = new AlignedWorkerAffinity[FIBER_COUNT]; FiberData* fiberData = new FiberData[FIBER_COUNT]; for (unsigned int i = 0; i < FIBER_COUNT; ++i) { @@ -59,9 +57,7 @@ static void alphaFun() { for (unsigned int i = 0; i < FIBER_COUNT; ++i) { FiberData* myFiberData = &fiberData[i]; myFiberData->cps = &cps; - Fiber* fiber = Fiber::from(&fiberFun, - myFiberData, - &affinities[i].affinity); + Fiber* fiber = Fiber::from(&fiberFun, myFiberData, &affinities[i].affinity); runtime->schedule(*fiber); } cps.wait(); @@ -72,16 +68,17 @@ static void alphaFun() { for (unsigned int i = 0; i < FIBER_COUNT; ++i) { FiberData* myFiberData = &fiberData[i]; myFiberData->cps = &cps; - Fiber* fiber = Fiber::from([myFiberData, &finalResult]() { - uint64_t mySum = 0; - for (unsigned int i = 0; i < PAYLOAD_COUNT; ++i) { - mySum += myFiberData->payload[i]; - } - finalResult += mySum; - - myFiberData->cps->signalAndExit(); - }, - &affinities[i].affinity); + Fiber* fiber = Fiber::from( + [myFiberData, &finalResult]() { + uint64_t mySum = 0; + for (unsigned int i = 0; i < PAYLOAD_COUNT; ++i) { + mySum += myFiberData->payload[i]; + } + finalResult += mySum; + + myFiberData->cps->signalAndExit(); + }, + &affinities[i].affinity); runtime->schedule(*fiber); } cps.wait(); @@ -94,7 +91,7 @@ static void alphaFun() { exit(EXIT_SUCCESS); } -int main(UNUSED_ARG int args, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int args, UNUSED_ARG char* argv[]) { RuntimeStrategy& lawsStrategy = LawsStrategy::INSTANCE; Runtime runtime(lawsStrategy); diff --git a/tests/SimplestFibTest.cpp b/tests/SimplestFibTest.cpp index d365f02c..753b26f6 100644 --- a/tests/SimplestFibTest.cpp +++ b/tests/SimplestFibTest.cpp @@ -1,15 +1,15 @@ +#include <cstdlib> #include <iostream> #include <list> #include <string> #include <thread> -#include <cstdlib> -#include "Runtime.hpp" -#include "Common.hpp" -#include "PrivateSemaphore.hpp" #include "BinaryPrivateSemaphore.hpp" +#include "Common.hpp" #include "CountingPrivateSemaphore.hpp" #include "Debug.hpp" +#include "PrivateSemaphore.hpp" +#include "Runtime.hpp" #include "emper.hpp" typedef struct { @@ -18,13 +18,14 @@ typedef struct { PS* sem; } fibParams; -static void fib(void *voidParams) { +static void fib(void* voidParams) { fibParams* params = static_cast<fibParams*>(voidParams); int n = params->n; - int *result = params->result; + int* result = params->result; if (!result) { - std::cerr << "voidParams: " << voidParams << " n: " << params->n << " sem: " << params->sem << std::endl; - abort( ); + std::cerr << "voidParams: " << voidParams << " n: " << params->n << " sem: " << params->sem + << std::endl; + abort(); } PS* sem = params->sem; @@ -65,7 +66,7 @@ static void fibKickoff() { const int fibNum = 2; int result; BPS sem; - fibParams params = { fibNum, &result, &sem }; + fibParams params = {fibNum, &result, &sem}; Fiber* fibFiber = Fiber::from(fib, ¶ms); async(fibFiber); @@ -76,8 +77,8 @@ static void fibKickoff() { exit(EXIT_SUCCESS); } -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { - //const unsigned nthreads = std::thread::hardware_concurrency(); +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { + // const unsigned nthreads = std::thread::hardware_concurrency(); const unsigned nthreads = 2; std::cout << "Number of threads: " << nthreads << std::endl; @@ -91,6 +92,6 @@ int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { runtime.schedule(*fibFiber); runtime.waitUntilFinished(); - + return 0; } diff --git a/tests/c_api_test.c b/tests/c_api_test.c index 77335399..2cfbbd92 100644 --- a/tests/c_api_test.c +++ b/tests/c_api_test.c @@ -1,7 +1,7 @@ #include <stdlib.h> -#include "emper.h" #include "emper-common.h" +#include "emper.h" #define FIBER_COUNT 10 @@ -40,7 +40,7 @@ static void alpha_fun(void) { schedule(check_fiber); } -int main(UNUSED_ARG int argc, UNUSED_ARG char *argv[]) { +int main(UNUSED_ARG int argc, UNUSED_ARG char* argv[]) { init_runtime(); fiber* alpha_fiber = fiber_from0(alpha_fun); diff --git a/tools/check-format b/tools/check-format new file mode 100755 index 00000000..291d1523 --- /dev/null +++ b/tools/check-format @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Pretty fancy method to get reliable the absolute path of a shell +# script, *even if it is sourced*. Credits go to GreenFox on +# stackoverflow: http://stackoverflow.com/a/12197518/194894 +pushd . > /dev/null +SCRIPTDIR="${BASH_SOURCE[0]}"; +while([ -h "${SCRIPTDIR}" ]); do + cd "`dirname "${SCRIPTDIR}"`" + SCRIPTDIR="$(readlink "`basename "${SCRIPTDIR}"`")"; +done +cd "`dirname "${SCRIPTDIR}"`" > /dev/null +SCRIPTDIR="`pwd`"; +popd > /dev/null + +DEBUG=false +while getopts d OPT; do + case $OPT in + d) + set -x + DEBUG=true + ;; + *) + echo "usage: ${0##*/} [-dq} [--] ARGS..." + exit 2 + esac +done +shift $(( OPTIND - 1 )) +OPTIND=1 + +ROOTDIR=$(readlink -f "${SCRIPTDIR}/..") + +MAX_PROCS=$(nproc) + +CHECKED_FILES_FILE=$(mktemp) +if ! $DEBUG; then + trap 'rm "${CHECKED_FILES_FILE}"' EXIT +fi + +cd "${ROOTDIR}" +# Note that the --dry-run and --Werror clang-format arguments require +# clang-format 10 or higher. See https://reviews.llvm.org/D68554 +find . \( -path '*/\.*' -o -path "./build*" \) -prune -o \ + -type f -regextype posix-extended -regex '.*\.(c|h|cpp|hpp)' -print0 |\ + tee "${CHECKED_FILES_FILE}" |\ + xargs --null --max-args=3 --max-procs="${MAX_PROCS}" \ + clang-format --style=file --dry-run -Werror + +FILE_COUNT=$(<"${CHECKED_FILES_FILE}" tr -cd '\0' | wc -c) +echo "Checked ${FILE_COUNT} files for format violations" -- GitLab