diff --git a/src/ioprio.cpp b/src/ioprio.cpp index 0e3abe13..3ed1ba1a 100644 --- a/src/ioprio.cpp +++ b/src/ioprio.cpp @@ -32,8 +32,12 @@ enum IOPRIO_WHO_PROCESS = 1 }; +namespace ioprio +{ + std::atomic _enabled{false}; +} + thread_local int ioprio::SetFrom::thread_prio = -1; -bool _enabled = false; int ioprio::get(const int who_) @@ -69,22 +73,14 @@ ioprio::set(const int who_, void ioprio::enable(const bool enable_) { - _enabled = enable_; + _enabled.store(enable_,std::memory_order_relaxed); } -bool -ioprio::enabled() -{ - return _enabled; -} - -ioprio::SetFrom::SetFrom(const pid_t pid_) +void +ioprio::SetFrom::_slow_apply(const pid_t pid_) { int client_prio; - if(!_enabled) - return; - client_prio = ioprio::get(pid_); if(client_prio < 0) return; diff --git a/src/ioprio.hpp b/src/ioprio.hpp index acdc455d..1f272a4f 100644 --- a/src/ioprio.hpp +++ b/src/ioprio.hpp @@ -18,13 +18,27 @@ #pragma once +#include + #include namespace ioprio { + // Exposed so the disabled-path check in SetFrom can inline into + // every fuse_read/fuse_write as an atomic load + branch, with no + // function overhead. + extern std::atomic _enabled; + + [[gnu::always_inline]] + inline + bool + enabled() + { + return _enabled.load(std::memory_order_relaxed); + } + void enable(const bool); - bool enabled(); int get(const int who); int set(const int who, const int ioprio); @@ -33,6 +47,15 @@ namespace ioprio { static thread_local int thread_prio; - SetFrom(const pid_t pid); + [[gnu::always_inline]] + inline + SetFrom(const pid_t pid_) + { + if(ioprio::enabled()) + _slow_apply(pid_); + } + + private: + void _slow_apply(const pid_t); }; };