Loading 3party/asyncplusplus/include/async++/scheduler_fwd.h +49 −42 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ template<typename T, typename = decltype(std::declval<T>().schedule(std::declval two &is_scheduler_helper(int); template<typename T> one &is_scheduler_helper(...); template<typename T> struct is_scheduler : public std::integral_constant<bool, sizeof(is_scheduler_helper<T>(0)) - 1> {}; Loading @@ -48,6 +49,7 @@ class thread_scheduler_impl { public: LIBASYNC_EXPORT static void schedule(task_run_handle t); }; class inline_scheduler_impl { public: static void schedule(task_run_handle t); Loading @@ -63,7 +65,9 @@ void schedule_task(Sched& sched, task_ptr t); // Wait for the given task to finish. This will call the wait handler currently // active for this thread, which causes the thread to sleep by default. #ifndef LIBASYNC_CUSTOM_WAIT_FOR_TASK LIBASYNC_EXPORT void wait_for_task(task_base *wait_task); #endif // Forward-declaration for data used by threadpool_scheduler struct threadpool_data; Loading @@ -71,7 +75,8 @@ struct threadpool_data; }// namespace detail // Run a task in the current thread as soon as it is scheduled inline detail::inline_scheduler_impl& inline_scheduler() inline detail::inline_scheduler_impl & inline_scheduler() { static detail::inline_scheduler_impl instance; return instance; Loading @@ -80,7 +85,8 @@ inline detail::inline_scheduler_impl& inline_scheduler() // Run a task in a separate thread. Note that this scheduler does not wait for // threads to finish at process exit. You must ensure that all threads finish // before ending the process. inline detail::thread_scheduler_impl& thread_scheduler() inline detail::thread_scheduler_impl & thread_scheduler() { static detail::thread_scheduler_impl instance; return instance; Loading @@ -96,8 +102,10 @@ LIBASYNC_EXPORT threadpool_scheduler& default_threadpool_scheduler(); // LIBASYNC_CUSTOM_DEFAULT_SCHEDULER before including async++.h. Keep in mind // that in that case async::default_scheduler should be declared before // including async++.h. #ifndef LIBASYNC_CUSTOM_DEFAULT_SCHEDULER inline threadpool_scheduler& default_scheduler() inline threadpool_scheduler & default_scheduler() { return default_threadpool_scheduler(); } Loading Loading @@ -137,9 +145,8 @@ public: // Create a thread pool with the given number of threads. Call `prerun` // function before execution loop and `postrun` after. LIBASYNC_EXPORT threadpool_scheduler(std::size_t num_threads, std::function<void()>&& prerun_, std::function<void()>&& postrun_); LIBASYNC_EXPORT threadpool_scheduler(std::size_t num_threads, std::function<void()> &&prerun_, std::function<void()> &&postrun_); // Destroy the thread pool, tasks that haven't been started are dropped LIBASYNC_EXPORT ~threadpool_scheduler(); Loading CMakeLists.txt +3 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,9 @@ if(SLED_BUILD_TESTS) src/system/thread_pool_test.cc src/rx_test.cc src/uri_test.cc) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(sled_tests PRIVATE -Wthread-safety) endif() target_link_libraries(sled_tests PRIVATE sled GTest::gtest GTest::gtest_main) add_test(NAME sled_tests COMMAND sled_tests) endif(SLED_BUILD_TESTS) Loading include/sled/async/async.h +10 −0 Original line number Diff line number Diff line Loading @@ -3,18 +3,28 @@ namespace sled { class FiberScheduler; } namespace async { sled::FiberScheduler &default_scheduler(); class task_base; namespace detail { void wait_for_task(task_base *wait_task); } }// namespace async #define LIBASYNC_CUSTON_EVENT #define LIBASYNC_CUSTOM_DEFAULT_SCHEDULER #include <async++.h> namespace sled { void SleepWaitHandler(async::task_wait_handle t); class FiberScheduler { public: FiberScheduler(); void schedule(async::task_run_handle t); }; Loading include/sled/synchronization/mutex.h +32 −34 Original line number Diff line number Diff line Loading @@ -33,28 +33,29 @@ struct HasLockAndUnlock { }; }// namespace internal using Mutex = marl::mutex; // using Mutex = marl::mutex; // 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 SLED_LOCKABLE Mutex final { public: Mutex() = default; Mutex(const Mutex &) = delete; Mutex &operator=(const Mutex &) = delete; class RecursiveMutex final { inline void Lock() SLED_EXCLUSIVE_LOCK_FUNCTION(impl_) { impl_.lock(); }; inline bool TryLock() SLED_EXCLUSIVE_TRYLOCK_FUNCTION(true) { return impl_.try_lock(); } inline void AssertHeld() SLED_ASSERT_EXCLUSIVE_LOCK(impl_) {} inline void Unlock() SLED_UNLOCK_FUNCTION(impl_) { impl_.unlock(); } private: marl::mutex impl_; friend class ConditionVariable; friend class MutexLock; }; class SLED_LOCKABLE RecursiveMutex final { public: RecursiveMutex() = default; RecursiveMutex(const RecursiveMutex &) = delete; Loading @@ -72,17 +73,14 @@ private: std::recursive_mutex impl_; }; class RecursiveMutexLock final { class SLED_SCOPED_CAPABILITY RecursiveMutexLock final { public: RecursiveMutexLock(const RecursiveMutexLock &) = delete; RecursiveMutexLock &operator=(const RecursiveMutexLock &) = delete; explicit RecursiveMutexLock(RecursiveMutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : mutex_(mutex) { mutex->Lock(); } explicit RecursiveMutexLock(RecursiveMutex *mutex) SLED_ACQUIRE_SHARED(mutex) : mutex_(mutex) { mutex->Lock(); } ~RecursiveMutexLock() SLED_UNLOCK_FUNCTION() { mutex_->Unlock(); } ~RecursiveMutexLock() SLED_RELEASE_SHARED(mutex_) { mutex_->Unlock(); } private: RecursiveMutex *mutex_; Loading @@ -101,11 +99,11 @@ private: // friend class ConditionVariable; // }; // class MutexLock final { class SLED_SCOPED_CAPABILITY MutexLock final { public: MutexLock(Mutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : lock_(*mutex) {} MutexLock(Mutex *mutex) SLED_ACQUIRE(mutex) : lock_(mutex->impl_) {} ~MutexLock() SLED_UNLOCK_FUNCTION() = default; ~MutexLock() SLED_RELEASE() = default; MutexLock(const MutexLock &) = delete; MutexLock &operator=(const MutexLock &) = delete; Loading src/async/async.cc +21 −10 Original line number Diff line number Diff line Loading @@ -5,15 +5,6 @@ // clang-format off #include <async++.h> // clang-format on namespace async { sled::FiberScheduler & default_scheduler() { static sled::FiberScheduler scheduler; return scheduler; } }// namespace async namespace sled { Loading @@ -25,13 +16,33 @@ SleepWaitHandler(async::task_wait_handle t) event.Wait(sled::Event::kForever); } FiberScheduler::FiberScheduler() { } void FiberScheduler::schedule(async::task_run_handle t) { static ThreadPool thread_pool; auto move_on_copy = sled::MakeMoveOnCopy(t); // thread_pool.PostTask([move_on_copy] { move_on_copy.value.run_with_wait_handler(SleepWaitHandler); }); thread_pool.submit([move_on_copy] { move_on_copy.value.run_with_wait_handler(SleepWaitHandler); }); // thread_pool.submit([move_on_copy] { move_on_copy.value.run(); }); } }// namespace sled // clang-format on namespace async { sled::FiberScheduler & default_scheduler() { static sled::FiberScheduler scheduler; return scheduler; } void detail::wait_for_task(task_base *wait_task) { sled::SleepWaitHandler(task_wait_handle(wait_task)); } }// namespace async Loading
3party/asyncplusplus/include/async++/scheduler_fwd.h +49 −42 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ template<typename T, typename = decltype(std::declval<T>().schedule(std::declval two &is_scheduler_helper(int); template<typename T> one &is_scheduler_helper(...); template<typename T> struct is_scheduler : public std::integral_constant<bool, sizeof(is_scheduler_helper<T>(0)) - 1> {}; Loading @@ -48,6 +49,7 @@ class thread_scheduler_impl { public: LIBASYNC_EXPORT static void schedule(task_run_handle t); }; class inline_scheduler_impl { public: static void schedule(task_run_handle t); Loading @@ -63,7 +65,9 @@ void schedule_task(Sched& sched, task_ptr t); // Wait for the given task to finish. This will call the wait handler currently // active for this thread, which causes the thread to sleep by default. #ifndef LIBASYNC_CUSTOM_WAIT_FOR_TASK LIBASYNC_EXPORT void wait_for_task(task_base *wait_task); #endif // Forward-declaration for data used by threadpool_scheduler struct threadpool_data; Loading @@ -71,7 +75,8 @@ struct threadpool_data; }// namespace detail // Run a task in the current thread as soon as it is scheduled inline detail::inline_scheduler_impl& inline_scheduler() inline detail::inline_scheduler_impl & inline_scheduler() { static detail::inline_scheduler_impl instance; return instance; Loading @@ -80,7 +85,8 @@ inline detail::inline_scheduler_impl& inline_scheduler() // Run a task in a separate thread. Note that this scheduler does not wait for // threads to finish at process exit. You must ensure that all threads finish // before ending the process. inline detail::thread_scheduler_impl& thread_scheduler() inline detail::thread_scheduler_impl & thread_scheduler() { static detail::thread_scheduler_impl instance; return instance; Loading @@ -96,8 +102,10 @@ LIBASYNC_EXPORT threadpool_scheduler& default_threadpool_scheduler(); // LIBASYNC_CUSTOM_DEFAULT_SCHEDULER before including async++.h. Keep in mind // that in that case async::default_scheduler should be declared before // including async++.h. #ifndef LIBASYNC_CUSTOM_DEFAULT_SCHEDULER inline threadpool_scheduler& default_scheduler() inline threadpool_scheduler & default_scheduler() { return default_threadpool_scheduler(); } Loading Loading @@ -137,9 +145,8 @@ public: // Create a thread pool with the given number of threads. Call `prerun` // function before execution loop and `postrun` after. LIBASYNC_EXPORT threadpool_scheduler(std::size_t num_threads, std::function<void()>&& prerun_, std::function<void()>&& postrun_); LIBASYNC_EXPORT threadpool_scheduler(std::size_t num_threads, std::function<void()> &&prerun_, std::function<void()> &&postrun_); // Destroy the thread pool, tasks that haven't been started are dropped LIBASYNC_EXPORT ~threadpool_scheduler(); Loading
CMakeLists.txt +3 −0 Original line number Diff line number Diff line Loading @@ -141,6 +141,9 @@ if(SLED_BUILD_TESTS) src/system/thread_pool_test.cc src/rx_test.cc src/uri_test.cc) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") target_compile_options(sled_tests PRIVATE -Wthread-safety) endif() target_link_libraries(sled_tests PRIVATE sled GTest::gtest GTest::gtest_main) add_test(NAME sled_tests COMMAND sled_tests) endif(SLED_BUILD_TESTS) Loading
include/sled/async/async.h +10 −0 Original line number Diff line number Diff line Loading @@ -3,18 +3,28 @@ namespace sled { class FiberScheduler; } namespace async { sled::FiberScheduler &default_scheduler(); class task_base; namespace detail { void wait_for_task(task_base *wait_task); } }// namespace async #define LIBASYNC_CUSTON_EVENT #define LIBASYNC_CUSTOM_DEFAULT_SCHEDULER #include <async++.h> namespace sled { void SleepWaitHandler(async::task_wait_handle t); class FiberScheduler { public: FiberScheduler(); void schedule(async::task_run_handle t); }; Loading
include/sled/synchronization/mutex.h +32 −34 Original line number Diff line number Diff line Loading @@ -33,28 +33,29 @@ struct HasLockAndUnlock { }; }// namespace internal using Mutex = marl::mutex; // using Mutex = marl::mutex; // 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 SLED_LOCKABLE Mutex final { public: Mutex() = default; Mutex(const Mutex &) = delete; Mutex &operator=(const Mutex &) = delete; class RecursiveMutex final { inline void Lock() SLED_EXCLUSIVE_LOCK_FUNCTION(impl_) { impl_.lock(); }; inline bool TryLock() SLED_EXCLUSIVE_TRYLOCK_FUNCTION(true) { return impl_.try_lock(); } inline void AssertHeld() SLED_ASSERT_EXCLUSIVE_LOCK(impl_) {} inline void Unlock() SLED_UNLOCK_FUNCTION(impl_) { impl_.unlock(); } private: marl::mutex impl_; friend class ConditionVariable; friend class MutexLock; }; class SLED_LOCKABLE RecursiveMutex final { public: RecursiveMutex() = default; RecursiveMutex(const RecursiveMutex &) = delete; Loading @@ -72,17 +73,14 @@ private: std::recursive_mutex impl_; }; class RecursiveMutexLock final { class SLED_SCOPED_CAPABILITY RecursiveMutexLock final { public: RecursiveMutexLock(const RecursiveMutexLock &) = delete; RecursiveMutexLock &operator=(const RecursiveMutexLock &) = delete; explicit RecursiveMutexLock(RecursiveMutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : mutex_(mutex) { mutex->Lock(); } explicit RecursiveMutexLock(RecursiveMutex *mutex) SLED_ACQUIRE_SHARED(mutex) : mutex_(mutex) { mutex->Lock(); } ~RecursiveMutexLock() SLED_UNLOCK_FUNCTION() { mutex_->Unlock(); } ~RecursiveMutexLock() SLED_RELEASE_SHARED(mutex_) { mutex_->Unlock(); } private: RecursiveMutex *mutex_; Loading @@ -101,11 +99,11 @@ private: // friend class ConditionVariable; // }; // class MutexLock final { class SLED_SCOPED_CAPABILITY MutexLock final { public: MutexLock(Mutex *mutex) SLED_EXCLUSIVE_LOCK_FUNCTION(mutex) : lock_(*mutex) {} MutexLock(Mutex *mutex) SLED_ACQUIRE(mutex) : lock_(mutex->impl_) {} ~MutexLock() SLED_UNLOCK_FUNCTION() = default; ~MutexLock() SLED_RELEASE() = default; MutexLock(const MutexLock &) = delete; MutexLock &operator=(const MutexLock &) = delete; Loading
src/async/async.cc +21 −10 Original line number Diff line number Diff line Loading @@ -5,15 +5,6 @@ // clang-format off #include <async++.h> // clang-format on namespace async { sled::FiberScheduler & default_scheduler() { static sled::FiberScheduler scheduler; return scheduler; } }// namespace async namespace sled { Loading @@ -25,13 +16,33 @@ SleepWaitHandler(async::task_wait_handle t) event.Wait(sled::Event::kForever); } FiberScheduler::FiberScheduler() { } void FiberScheduler::schedule(async::task_run_handle t) { static ThreadPool thread_pool; auto move_on_copy = sled::MakeMoveOnCopy(t); // thread_pool.PostTask([move_on_copy] { move_on_copy.value.run_with_wait_handler(SleepWaitHandler); }); thread_pool.submit([move_on_copy] { move_on_copy.value.run_with_wait_handler(SleepWaitHandler); }); // thread_pool.submit([move_on_copy] { move_on_copy.value.run(); }); } }// namespace sled // clang-format on namespace async { sled::FiberScheduler & default_scheduler() { static sled::FiberScheduler scheduler; return scheduler; } void detail::wait_for_task(task_base *wait_task) { sled::SleepWaitHandler(task_wait_handle(wait_task)); } }// namespace async