From 66ba3d98e4c363e943912a867831e018f61ecac4 Mon Sep 17 00:00:00 2001 From: Ludovic 'Archivist' Lagouardette Date: Wed, 27 Oct 2021 11:52:38 +0200 Subject: [PATCH] Updating bottleneck with a semaphore --- extra_tests/001_test/Makefile | 10 +++--- extra_tests/001_test/main.cpp | 2 +- extra_tests/001_test/syscall.hpp | 2 +- include/gp/ipc/bottleneck.hpp | 54 ++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/extra_tests/001_test/Makefile b/extra_tests/001_test/Makefile index ac4f9ee..8df4f5b 100644 --- a/extra_tests/001_test/Makefile +++ b/extra_tests/001_test/Makefile @@ -1,17 +1,17 @@ CXX= clang++ -CXXFLAGS= --std=c++20 -target x86_64-none-linux-elf -Os -ffreestanding -nostdlib -pedantic \ - -Wno-unknown-attributes -fno-omit-frame-pointer -MD -fno-use-cxa-atexit -fno-rtti -I../../include -I. +CXXFLAGS= --std=c++20 -target x86_64-none-linux-elf -O2 -ffreestanding -nostdlib -pedantic \ + -Wno-unknown-attributes -fno-omit-frame-pointer -MD -fno-use-cxa-atexit -fno-rtti -I. -I../../include # -fsanitize=address -fsanitize-blacklist=blacklist.txt all: tests tests: bin/tests - ./bin/tests + ./bin/tests potato bin/tests: main.cpp @mkdir -p $(@D) - $(CXX) $(CXXFLAGS) main.cpp -o $@ + $(CXX) $(CXXFLAGS) main.cpp -nostartfiles -s -static -o $@ clean: ./bin - @rm -rf $< \ No newline at end of file + @rm -rf $< diff --git a/extra_tests/001_test/main.cpp b/extra_tests/001_test/main.cpp index 8c09aac..d0a8a06 100644 --- a/extra_tests/001_test/main.cpp +++ b/extra_tests/001_test/main.cpp @@ -1,4 +1,4 @@ -#include +#include #include "syscall.hpp" gp::buffer hello = "Hello world\n"; diff --git a/extra_tests/001_test/syscall.hpp b/extra_tests/001_test/syscall.hpp index 62ed2a1..abe3f7a 100644 --- a/extra_tests/001_test/syscall.hpp +++ b/extra_tests/001_test/syscall.hpp @@ -133,7 +133,7 @@ inline int write(int fd, char* buffer, size_t sz) { return _write((int64_t)fd, (int64_t)buffer, (int64_t)sz); } -inline void* mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) { +inline void* mmap(void *addr, size_t length, int prot, int flags, int fd, int64_t offset) { return (void*)_mmap((int64_t)addr, (int64_t)length, (int64_t)prot, (int64_t)flags, (int64_t)fd, (int64_t)offset); } diff --git a/include/gp/ipc/bottleneck.hpp b/include/gp/ipc/bottleneck.hpp index e57f2ce..d4e3764 100644 --- a/include/gp/ipc/bottleneck.hpp +++ b/include/gp/ipc/bottleneck.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "gp_config.hpp" @@ -55,4 +56,57 @@ namespace gp { return flag.compare_exchange_strong(t,f,std::memory_order::release); } }; + + /** + * @brief A fast semaphore exclusion handler WITHOUT deadlock detection + */ + template + class fast_semaphore { + std::atomic flag; + public: + fast_semaphore() = default; + fast_semaphore(fast_semaphore&) = delete; + fast_semaphore(fast_semaphore&&) = delete; + + enum class tristate { + success, + timing, + error + }; + + void lock_super() { + auto value = flag.fetch_add(maximum_increment, std::memory_order::relaxed); + while(value > maximum_increment) { value = flag.load(std::memory_order::release); } + } + + + template + void lock() { + while(not try_lock()); + } + + template + [[nodiscard]] bool try_lock() { + T expect = flag.load(std::memory_order::relaxed); + T target = expect + increment; + if(target > maximum_increment) return false; + return flag.compare_exchange_strong(expect,target,std::memory_order::acquire); + } + + template + void unlock() { + tristate v; + do{ v = try_unlock(); } + while(v == tristate::timing); + gp_config::assertion(v == tristate::success, "Over unlocking may have happened"); + } + + template + [[nodiscard]] tristate try_unlock() { + T expect = flag.load(std::memory_order::relaxed); + T target = expect - increment; + if(target < 0) return tristate::error; + return flag.compare_exchange_strong(expect,target,std::memory_order::release) ? tristate::success : tristate::timing; + } + }; } \ No newline at end of file