63bool OpenFile(
const std::string &entity, std::string &open_error_message);
66void Apply(
int reqsize,
int reqops,
int uid);
70bool IsThrottling() {
return (m_ops_per_second > 0) || (m_bytes_per_second > 0);}
77void SetThrottles(
float reqbyterate,
float reqoprate,
int concurrency,
float interval_length)
78 {m_interval_length_seconds = interval_length; m_bytes_per_second = reqbyterate;
79 m_ops_per_second = reqoprate; m_concurrency_limit = concurrency;}
81void SetLoadShed(std::string &hostname,
unsigned port,
unsigned frequency)
82 {m_loadshed_host = hostname; m_loadshed_port = port; m_loadshed_frequency = frequency;}
84void SetMaxOpen(
unsigned long max_open) {m_max_open = max_open;}
86void SetMaxConns(
unsigned long max_conns) {m_max_conns = max_conns;}
88void SetMaxWait(
unsigned long max_wait) {m_max_wait_time = std::chrono::seconds(max_wait);}
111void PrepLoadShed(
const char *opaque, std::string &lsOpaque);
115void PerformLoadShed(
const std::string &opaque, std::string &host,
unsigned &port);
126void StopIOTimer(std::chrono::steady_clock::duration & event_duration, uint16_t uid);
133uint16_t GetUid(
const std::string &);
137void RecomputeInternal();
140void * RecomputeBootstrap(
void *pp);
143void ComputeWaiterOrder();
150void UserIOAccounting();
154void GetShares(
int &shares,
int &request);
156void StealShares(
int uid,
int &reqsize,
int &reqops);
162static unsigned GetTimerListHash();
173float m_interval_length_seconds;
174float m_bytes_per_second;
175float m_ops_per_second;
176int m_concurrency_limit;
180static constexpr int m_max_users = 1024;
181std::vector<int> m_primary_bytes_shares;
182std::vector<int> m_secondary_bytes_shares;
183std::vector<int> m_primary_ops_shares;
184std::vector<int> m_secondary_ops_shares;
185int m_last_round_allocation;
188struct alignas(64) Waiter
190 std::condition_variable m_cv;
192 unsigned m_waiting{0};
197 XrdSys::RAtomic<float> m_concurrency{0};
201 XrdSys::RAtomic<std::chrono::steady_clock::duration::rep> m_io_time{0};
210 void NotifyOne(std::unique_lock<std::mutex> lock)
215std::array<Waiter, m_max_users> m_waiter_info;
228std::array<XrdSys::RAtomic<int16_t>, m_max_users> m_wake_order_0;
229std::array<XrdSys::RAtomic<int16_t>, m_max_users> m_wake_order_1;
230XrdSys::RAtomic<char> m_wake_order_active;
231std::atomic<size_t> m_waiter_offset{0};
232std::chrono::steady_clock::time_point m_last_waiter_recompute_time;
233XrdSys::RAtomic<unsigned> m_waiting_users{0};
235std::atomic<uint32_t> m_io_active;
236XrdSys::RAtomic<std::chrono::steady_clock::duration::rep> m_io_active_time;
237XrdSys::RAtomic<uint64_t> m_io_total{0};
239int m_stable_io_active{0};
240uint64_t m_stable_io_total{0};
242std::chrono::steady_clock::duration m_stable_io_wait;
245std::string m_loadshed_host;
246unsigned m_loadshed_port;
247unsigned m_loadshed_frequency;
252XrdSys::RAtomic<int> m_loadshed_limit_hit;
255unsigned long m_max_open{0};
256unsigned long m_max_conns{0};
257std::unordered_map<std::string, unsigned long> m_file_counters;
258std::unordered_map<std::string, unsigned long> m_conn_counters;
259std::unordered_map<std::string, std::unique_ptr<std::unordered_map<pid_t, unsigned long>>> m_active_conns;
260std::mutex m_file_mutex;
264 unsigned long max_conn{0};
265 bool is_wildcard{
false};
267std::unordered_map<std::string, UserLimit> m_user_limits;
268std::shared_mutex m_user_limits_mutex;
269std::string m_user_config_file;
280#if defined(__linux__)
281static constexpr size_t m_timer_list_size = 32;
283static constexpr size_t m_timer_list_size = 1;
285std::array<TimerList, m_timer_list_size> m_timer_list;
290std::chrono::steady_clock::duration m_max_wait_time{std::chrono::seconds(30)};
293XrdXrootdGStream* m_gstream{
nullptr};
295static const char *TraceID;
316 m_start_time(std::chrono::steady_clock::time_point::min())
323 m_start_time(std::chrono::steady_clock::now())
328 auto &timerList = m_manager->m_timer_list[m_timer_list_entry];
329 std::lock_guard<std::mutex> lock(timerList.m_mutex);
330 if (timerList.m_first ==
nullptr) {
331 timerList.m_first =
this;
333 m_prev = timerList.m_last;
334 m_prev->m_next =
this;
336 timerList.m_last =
this;
339std::chrono::steady_clock::duration
Reset() {
340 auto now = std::chrono::steady_clock::now();
341 auto last_start = m_start_time.exchange(now);
342 return now - last_start;
349 if (!m_manager)
return;
351 auto event_duration =
Reset();
352 auto &timerList = m_manager->m_timer_list[m_timer_list_entry];
354 std::unique_lock<std::mutex> lock(timerList.m_mutex);
356 m_prev->m_next = m_next;
358 m_next->m_prev = m_prev;
360 timerList.m_last = m_prev;
363 timerList.m_first = m_next;
365 m_next->m_prev =
nullptr;
367 timerList.m_last =
nullptr;
371 m_manager->StopIOTimer(event_duration, m_owner);
374 const uint16_t m_owner{0};
375 const uint16_t m_timer_list_entry{0};
379 XrdSys::RAtomic<std::chrono::steady_clock::time_point> m_start_time;