Loading CMakeLists.txt +16 −3 Original line number Diff line number Diff line Loading @@ -77,12 +77,25 @@ target_link_libraries(sled PUBLIC rpc_core fmt marl) if(SLED_BUILD_BENCHMARK) find_package(benchmark REQUIRED) add_executable(sled_benchmark benchmark/strings/base64_benchmark.cc) add_executable(sled_benchmark "src/system/fiber/fiber_bench.cc") target_link_libraries(sled_benchmark PRIVATE sled benchmark::benchmark benchmark::benchmark_main) endif(SLED_BUILD_BENCHMARK) if(SLED_BUILD_TESTS) find_package(gtest REQUIRED) add_executable(sled_tests "") include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) FetchContent_MakeAvailable(googletest) add_executable(sled_tests src/filesystem/path_test.cc src/strings/base64_test.cc src/cleanup_test.cc src/status_or_test.cc src/system/fiber/fiber_test.cc ) target_link_libraries(sled_tests PRIVATE sled GTest::gtest GTest::gtest_main) add_test(NAME sled_tests COMMAND sled_tests) endif(SLED_BUILD_TESTS) benchmark/strings/base64_benchmark.ccdeleted 100644 → 0 +0 −59 Original line number Diff line number Diff line #include <benchmark/benchmark.h> #include <sled/random.h> #include <sled/strings/base64.h> #include <sstream> struct strings {}; static std::string AllocRandomString(sled::Random &random, int len) { std::stringstream ss; for (int i = len; i > 0; i--) { ss << random.Rand<char>(); } return ss.str(); } void BenchmarkBase64Encode(benchmark::State &state) { state.PauseTiming(); sled::Random random(2393); std::vector<std::string> test_data; for (int i = 0; i < state.range(0); i++) { test_data.emplace_back(AllocRandomString(random, state.range(1))); } state.ResumeTiming(); for (int i = 0; i < state.range(2); i++) { for (const auto &str : test_data) { auto base64 = sled::Base64::Encode(str); } } } std::string uint2str(unsigned int num) { std::ostringstream oss; oss << num; return oss.str(); } void test(benchmark::State &state) { for (int i = 0; i < 1000000; i++) (void) uint2str(i); state.end(); } BENCHMARK(test); /* BENCHMARK(BenchmarkBase64Encode) ->ArgsProduct({ // generate the num of strings benchmark::CreateRange(10, 1000, 10), // generate the length of each string benchmark::CreateRange(10, 1000, 10), benchmark::CreateRange(10, 1000, 10), }); */ include/sled/synchronization/mutex.h +93 −42 Original line number Diff line number Diff line Loading @@ -5,12 +5,14 @@ **/ #pragma once #include "marl/conditionvariable.h" #ifndef SLED_SYNCHRONIZATION_MUTEX_H #define SLED_SYNCHRONIZATION_MUTEX_H #include "sled/units/time_delta.h" #include <chrono> #include <condition_variable> #include <marl/mutex.h> #include <mutex> #include <type_traits> Loading @@ -31,24 +33,26 @@ struct HasLockAndUnlock { }; }// namespace internal class Mutex final { public: Mutex() = default; Mutex(const Mutex &) = delete; Mutex &operator=(const Mutex &) = delete; inline void Lock() { impl_.lock(); }; inline bool TryLock() { return impl_.try_lock(); } inline void AssertHeld() {} inline void Unlock() { impl_.unlock(); } using Mutex = marl::mutex; private: std::mutex impl_; friend class ConditionVariable; }; // class Mutex final { // public: // Mutex() = default; // Mutex(const Mutex &) = delete; // Mutex &operator=(const Mutex &) = delete; // // inline void Lock() { impl_.lock(); }; // // inline bool TryLock() { return impl_.try_lock(); } // // inline void AssertHeld() {} // // inline void Unlock() { impl_.unlock(); } // // private: // std::mutex impl_; // friend class ConditionVariable; // }; class RecursiveMutex final { public: Loading Loading @@ -85,8 +89,22 @@ private: friend class ConditionVariable; }; using MutexLock = LockGuard<Mutex>; using MutexGuard = LockGuard<Mutex>; class MutexGuard final { public: MutexGuard(Mutex *mutex) : lock_(*mutex) {} MutexGuard(const MutexGuard &) = delete; MutexGuard &operator=(const MutexGuard &) = delete; private: friend class ConditionVariable; marl::lock lock_; }; using MutexLock = MutexGuard; // using MutexGuard = marl::lock; // using MutexLock = LockGuard<Mutex>; // using MutexGuard = LockGuard<Mutex>; using RecursiveMutexLock = LockGuard<RecursiveMutex>; // class MutexLock final { Loading Loading @@ -121,44 +139,77 @@ using RecursiveMutexLock = LockGuard<RecursiveMutex>; class ConditionVariable final { public: static constexpr TimeDelta kForever = TimeDelta::PlusInfinity(); ConditionVariable() = default; ConditionVariable(const ConditionVariable &) = delete; ConditionVariable &operator=(const ConditionVariable &) = delete; // inline ConditionVariable(); inline void NotifyOne() { cv_.notify_one(); } inline void NotifyAll() { cv_.notify_all(); } template<typename Predicate> inline bool Wait(LockGuard<Mutex> &guard, Predicate pred) inline void Wait(MutexLock &lock, Predicate &&pred) { std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); cv_.wait(lock, pred); return true; cv_.wait(lock, std::forward<Predicate>(pred)); } template<typename Predicate> inline bool WaitFor(LockGuard<Mutex> &guard, TimeDelta timeout, Predicate pred) inline bool WaitFor(MutexLock &lock, TimeDelta timeout, Predicate &&pred) { std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); if (timeout == kForever) { cv_.wait(lock, pred); if (timeout == TimeDelta::PlusInfinity()) { cv_.wait(lock.lock_, std::forward<Predicate>(pred)); return true; } else { return cv_.wait_for(lock, std::chrono::milliseconds(timeout.ms()), pred); return cv_.wait_for(lock.lock_, std::chrono::milliseconds(timeout.ms()), std::forward<Predicate>(pred)); } } // template<typename Predicate> // bool WaitUntil(Mutex *mutex, TimeDelta timeout, Predicate pred) // {} inline void NotifyOne() { cv_.notify_one(); } inline void NotifyAll() { cv_.notify_all(); } private: std::condition_variable cv_; marl::ConditionVariable cv_; }; // class ConditionVariable final { // public: // static constexpr TimeDelta kForever = TimeDelta::PlusInfinity(); // ConditionVariable() = default; // ConditionVariable(const ConditionVariable &) = delete; // ConditionVariable &operator=(const ConditionVariable &) = delete; // // template<typename Predicate> // inline bool Wait(LockGuard<Mutex> &guard, Predicate pred) // { // std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); // cv_.wait(lock, pred); // return true; // } // // template<typename Predicate> // inline bool // WaitFor(LockGuard<Mutex> &guard, TimeDelta timeout, Predicate pred) // { // std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); // if (timeout == kForever) { // cv_.wait(lock, pred); // return true; // } else { // return cv_.wait_for(lock, std::chrono::milliseconds(timeout.ms()), // pred); // } // } // // // template<typename Predicate> // // bool WaitUntil(Mutex *mutex, TimeDelta timeout, Predicate pred) // // {} // // inline void NotifyOne() { cv_.notify_one(); } // // inline void NotifyAll() { cv_.notify_all(); } // // private: // std::condition_variable cv_; // }; }// namespace sled #endif// SLED_SYNCHRONIZATION_MUTEX_H include/sled/system/fiber/fiber_wait_group.hdeleted 100644 → 0 +0 −10 Original line number Diff line number Diff line #pragma once #ifndef SLED_SYSTEM_FIBER_FIBER_WAIT_GROUP_H #define SLED_SYSTEM_FIBER_FIBER_WAIT_GROUP_H #include <marl/waitgroup.h> namespace sled { using FiberWaitGroup = marl::WaitGroup; } #endif// SLED_SYSTEM_FIBER_FIBER_WAIT_GROUP_H include/sled/system/fiber/fiber_scheduler.h→include/sled/system/fiber/scheduler.h +4 −4 Original line number Diff line number Diff line #pragma once #ifndef SLED_SYSTEM_FIBER_FIBER_SCHEDULER_H #define SLED_SYSTEM_FIBER_FIBER_SCHEDULER_H #ifndef SLED_SYSTEM_FIBER_SCHEDULER_H #define SLED_SYSTEM_FIBER_SCHEDULER_H #include <marl/defer.h> #include <marl/scheduler.h> #include <marl/task.h> namespace sled { using FiberScheduler = marl::Scheduler; using Scheduler = marl::Scheduler; // schedule() schedules the task T to be asynchronously called using the // currently bound scheduler. Loading Loading @@ -42,4 +42,4 @@ Schedule(Function &&f) } }// namespace sled #endif// SLED_SYSTEM_FIBER_FIBER_SCHEDULER_H #endif// SLED_SYSTEM_FIBER_SCHEDULER_H Loading
CMakeLists.txt +16 −3 Original line number Diff line number Diff line Loading @@ -77,12 +77,25 @@ target_link_libraries(sled PUBLIC rpc_core fmt marl) if(SLED_BUILD_BENCHMARK) find_package(benchmark REQUIRED) add_executable(sled_benchmark benchmark/strings/base64_benchmark.cc) add_executable(sled_benchmark "src/system/fiber/fiber_bench.cc") target_link_libraries(sled_benchmark PRIVATE sled benchmark::benchmark benchmark::benchmark_main) endif(SLED_BUILD_BENCHMARK) if(SLED_BUILD_TESTS) find_package(gtest REQUIRED) add_executable(sled_tests "") include(FetchContent) FetchContent_Declare( googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip ) FetchContent_MakeAvailable(googletest) add_executable(sled_tests src/filesystem/path_test.cc src/strings/base64_test.cc src/cleanup_test.cc src/status_or_test.cc src/system/fiber/fiber_test.cc ) target_link_libraries(sled_tests PRIVATE sled GTest::gtest GTest::gtest_main) add_test(NAME sled_tests COMMAND sled_tests) endif(SLED_BUILD_TESTS)
benchmark/strings/base64_benchmark.ccdeleted 100644 → 0 +0 −59 Original line number Diff line number Diff line #include <benchmark/benchmark.h> #include <sled/random.h> #include <sled/strings/base64.h> #include <sstream> struct strings {}; static std::string AllocRandomString(sled::Random &random, int len) { std::stringstream ss; for (int i = len; i > 0; i--) { ss << random.Rand<char>(); } return ss.str(); } void BenchmarkBase64Encode(benchmark::State &state) { state.PauseTiming(); sled::Random random(2393); std::vector<std::string> test_data; for (int i = 0; i < state.range(0); i++) { test_data.emplace_back(AllocRandomString(random, state.range(1))); } state.ResumeTiming(); for (int i = 0; i < state.range(2); i++) { for (const auto &str : test_data) { auto base64 = sled::Base64::Encode(str); } } } std::string uint2str(unsigned int num) { std::ostringstream oss; oss << num; return oss.str(); } void test(benchmark::State &state) { for (int i = 0; i < 1000000; i++) (void) uint2str(i); state.end(); } BENCHMARK(test); /* BENCHMARK(BenchmarkBase64Encode) ->ArgsProduct({ // generate the num of strings benchmark::CreateRange(10, 1000, 10), // generate the length of each string benchmark::CreateRange(10, 1000, 10), benchmark::CreateRange(10, 1000, 10), }); */
include/sled/synchronization/mutex.h +93 −42 Original line number Diff line number Diff line Loading @@ -5,12 +5,14 @@ **/ #pragma once #include "marl/conditionvariable.h" #ifndef SLED_SYNCHRONIZATION_MUTEX_H #define SLED_SYNCHRONIZATION_MUTEX_H #include "sled/units/time_delta.h" #include <chrono> #include <condition_variable> #include <marl/mutex.h> #include <mutex> #include <type_traits> Loading @@ -31,24 +33,26 @@ struct HasLockAndUnlock { }; }// namespace internal class Mutex final { public: Mutex() = default; Mutex(const Mutex &) = delete; Mutex &operator=(const Mutex &) = delete; inline void Lock() { impl_.lock(); }; inline bool TryLock() { return impl_.try_lock(); } inline void AssertHeld() {} inline void Unlock() { impl_.unlock(); } using Mutex = marl::mutex; private: std::mutex impl_; friend class ConditionVariable; }; // class Mutex final { // public: // Mutex() = default; // Mutex(const Mutex &) = delete; // Mutex &operator=(const Mutex &) = delete; // // inline void Lock() { impl_.lock(); }; // // inline bool TryLock() { return impl_.try_lock(); } // // inline void AssertHeld() {} // // inline void Unlock() { impl_.unlock(); } // // private: // std::mutex impl_; // friend class ConditionVariable; // }; class RecursiveMutex final { public: Loading Loading @@ -85,8 +89,22 @@ private: friend class ConditionVariable; }; using MutexLock = LockGuard<Mutex>; using MutexGuard = LockGuard<Mutex>; class MutexGuard final { public: MutexGuard(Mutex *mutex) : lock_(*mutex) {} MutexGuard(const MutexGuard &) = delete; MutexGuard &operator=(const MutexGuard &) = delete; private: friend class ConditionVariable; marl::lock lock_; }; using MutexLock = MutexGuard; // using MutexGuard = marl::lock; // using MutexLock = LockGuard<Mutex>; // using MutexGuard = LockGuard<Mutex>; using RecursiveMutexLock = LockGuard<RecursiveMutex>; // class MutexLock final { Loading Loading @@ -121,44 +139,77 @@ using RecursiveMutexLock = LockGuard<RecursiveMutex>; class ConditionVariable final { public: static constexpr TimeDelta kForever = TimeDelta::PlusInfinity(); ConditionVariable() = default; ConditionVariable(const ConditionVariable &) = delete; ConditionVariable &operator=(const ConditionVariable &) = delete; // inline ConditionVariable(); inline void NotifyOne() { cv_.notify_one(); } inline void NotifyAll() { cv_.notify_all(); } template<typename Predicate> inline bool Wait(LockGuard<Mutex> &guard, Predicate pred) inline void Wait(MutexLock &lock, Predicate &&pred) { std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); cv_.wait(lock, pred); return true; cv_.wait(lock, std::forward<Predicate>(pred)); } template<typename Predicate> inline bool WaitFor(LockGuard<Mutex> &guard, TimeDelta timeout, Predicate pred) inline bool WaitFor(MutexLock &lock, TimeDelta timeout, Predicate &&pred) { std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); if (timeout == kForever) { cv_.wait(lock, pred); if (timeout == TimeDelta::PlusInfinity()) { cv_.wait(lock.lock_, std::forward<Predicate>(pred)); return true; } else { return cv_.wait_for(lock, std::chrono::milliseconds(timeout.ms()), pred); return cv_.wait_for(lock.lock_, std::chrono::milliseconds(timeout.ms()), std::forward<Predicate>(pred)); } } // template<typename Predicate> // bool WaitUntil(Mutex *mutex, TimeDelta timeout, Predicate pred) // {} inline void NotifyOne() { cv_.notify_one(); } inline void NotifyAll() { cv_.notify_all(); } private: std::condition_variable cv_; marl::ConditionVariable cv_; }; // class ConditionVariable final { // public: // static constexpr TimeDelta kForever = TimeDelta::PlusInfinity(); // ConditionVariable() = default; // ConditionVariable(const ConditionVariable &) = delete; // ConditionVariable &operator=(const ConditionVariable &) = delete; // // template<typename Predicate> // inline bool Wait(LockGuard<Mutex> &guard, Predicate pred) // { // std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); // cv_.wait(lock, pred); // return true; // } // // template<typename Predicate> // inline bool // WaitFor(LockGuard<Mutex> &guard, TimeDelta timeout, Predicate pred) // { // std::unique_lock<std::mutex> lock(guard.mutex_->impl_, std::adopt_lock); // if (timeout == kForever) { // cv_.wait(lock, pred); // return true; // } else { // return cv_.wait_for(lock, std::chrono::milliseconds(timeout.ms()), // pred); // } // } // // // template<typename Predicate> // // bool WaitUntil(Mutex *mutex, TimeDelta timeout, Predicate pred) // // {} // // inline void NotifyOne() { cv_.notify_one(); } // // inline void NotifyAll() { cv_.notify_all(); } // // private: // std::condition_variable cv_; // }; }// namespace sled #endif// SLED_SYNCHRONIZATION_MUTEX_H
include/sled/system/fiber/fiber_wait_group.hdeleted 100644 → 0 +0 −10 Original line number Diff line number Diff line #pragma once #ifndef SLED_SYSTEM_FIBER_FIBER_WAIT_GROUP_H #define SLED_SYSTEM_FIBER_FIBER_WAIT_GROUP_H #include <marl/waitgroup.h> namespace sled { using FiberWaitGroup = marl::WaitGroup; } #endif// SLED_SYSTEM_FIBER_FIBER_WAIT_GROUP_H
include/sled/system/fiber/fiber_scheduler.h→include/sled/system/fiber/scheduler.h +4 −4 Original line number Diff line number Diff line #pragma once #ifndef SLED_SYSTEM_FIBER_FIBER_SCHEDULER_H #define SLED_SYSTEM_FIBER_FIBER_SCHEDULER_H #ifndef SLED_SYSTEM_FIBER_SCHEDULER_H #define SLED_SYSTEM_FIBER_SCHEDULER_H #include <marl/defer.h> #include <marl/scheduler.h> #include <marl/task.h> namespace sled { using FiberScheduler = marl::Scheduler; using Scheduler = marl::Scheduler; // schedule() schedules the task T to be asynchronously called using the // currently bound scheduler. Loading Loading @@ -42,4 +42,4 @@ Schedule(Function &&f) } }// namespace sled #endif// SLED_SYSTEM_FIBER_FIBER_SCHEDULER_H #endif// SLED_SYSTEM_FIBER_SCHEDULER_H