Seastar
High performance C++ framework for concurrent servers
scheduling.hh
Go to the documentation of this file.
1/*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18/*
19 * Copyright (C) 2016 Scylla DB Ltd
20 */
21
22#pragma once
23
24#ifndef SEASTAR_MODULE
25#include <chrono>
26#include <concepts>
27#include <functional>
28#include <typeindex>
29#endif
30#include <seastar/core/sstring.hh>
31#include <seastar/core/function_traits.hh>
32#include <seastar/util/modules.hh>
33
35
36namespace seastar {
37
38SEASTAR_MODULE_EXPORT_BEGIN
39constexpr unsigned max_scheduling_groups() { return SEASTAR_SCHEDULING_GROUPS_COUNT; }
40
41template <typename T = void>
42class future;
43
44class reactor;
45
46class scheduling_group;
47class scheduling_group_key;
48
49using sched_clock = std::chrono::steady_clock;
50SEASTAR_MODULE_EXPORT_END
51
52namespace internal {
53
54// Returns an index between 0 and max_scheduling_groups()
55unsigned scheduling_group_index(scheduling_group sg) noexcept;
56scheduling_group scheduling_group_from_index(unsigned index) noexcept;
57
58unsigned long scheduling_group_key_id(scheduling_group_key) noexcept;
59
60template<typename T>
61T* scheduling_group_get_specific_ptr(scheduling_group sg, scheduling_group_key key) noexcept;
62
63}
64
65SEASTAR_MODULE_EXPORT_BEGIN
66
77future<scheduling_group> create_scheduling_group(sstring name, float shares) noexcept;
78
92future<scheduling_group> create_scheduling_group(sstring name, sstring shortname, float shares) noexcept;
93
104
115future<> rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept;
127future<> rename_scheduling_group(scheduling_group sg, sstring new_name, sstring new_shortname) noexcept;
128
129
148 scheduling_group_key_config(typeid(void)) {}
158 scheduling_group_key_config(const std::type_info& type_info) :
159 type_index(type_info) {}
163 size_t alignment;
165 std::type_index type_index;
167 std::function<void (void*)> constructor;
169 std::function<void (void*)> rename;
172 std::function<void (void*)> destructor;
173
174};
175
176
184public:
186 scheduling_group_key(const scheduling_group_key&) noexcept = default;
187 scheduling_group_key(scheduling_group_key&&) noexcept = default;
188private:
189 scheduling_group_key(unsigned long id) noexcept :
190 _id(id) {}
191 unsigned long _id;
192 unsigned long id() const noexcept {
193 return _id;
194 }
196 template<typename T>
197 friend T* internal::scheduling_group_get_specific_ptr(scheduling_group sg, scheduling_group_key key) noexcept;
198 template<typename T>
200
201 friend unsigned long internal::scheduling_group_key_id(scheduling_group_key key) noexcept;
202};
203
204SEASTAR_MODULE_EXPORT_END
205namespace internal {
206
207inline unsigned long scheduling_group_key_id(scheduling_group_key key) noexcept {
208 return key.id();
209}
210
229template<typename ConstructorType, typename Tuple, size_t...Idx>
230void apply_constructor(void* pre_alocated_mem, Tuple args, std::index_sequence<Idx...>) {
231 new (pre_alocated_mem) ConstructorType(std::get<Idx>(args)...);
232}
233}
234SEASTAR_MODULE_EXPORT_BEGIN
235
249template <typename T, typename... ConstructorArgs>
250scheduling_group_key_config
251make_scheduling_group_key_config(ConstructorArgs... args) {
252 scheduling_group_key_config sgkc(typeid(T));
253 sgkc.allocation_size = sizeof(T);
254 sgkc.alignment = alignof(T);
255 sgkc.constructor = [args = std::make_tuple(args...)] (void* p) {
256 internal::apply_constructor<T>(p, args, std::make_index_sequence<sizeof...(ConstructorArgs)>());
257 };
258 sgkc.destructor = [] (void* p) {
259 static_cast<T*>(p)->~T();
260 };
261 if constexpr (requires(T key) { key.rename(); }) {
262 sgkc.rename = [] (void* p) {
263 static_cast<T*>(p)->rename();
264 };
265 }
266 return sgkc;
267}
268
277
285template<typename T>
287
288
294 unsigned _id;
295private:
296 explicit scheduling_group(unsigned id) noexcept : _id(id) {}
297public:
299 constexpr scheduling_group() noexcept : _id(0) {} // must be constexpr for current_scheduling_group_holder
300 bool active() const noexcept;
301 const sstring& name() const noexcept;
302 const sstring& short_name() const noexcept;
303 bool operator==(scheduling_group x) const noexcept { return _id == x._id; }
304 bool operator!=(scheduling_group x) const noexcept { return _id != x._id; }
305 bool is_main() const noexcept { return _id == 0; }
306 bool is_at_exit() const noexcept { return _id == 1; }
307 template<typename T>
315 return *internal::scheduling_group_get_specific_ptr<T>(*this, key);
316 }
329 void set_shares(float shares) noexcept;
330
335 float get_shares() const noexcept;
336
344 future<> update_io_bandwidth(uint64_t bandwidth) const;
345
346 friend future<scheduling_group> create_scheduling_group(sstring name, sstring shortname, float shares) noexcept;
348 friend future<> rename_scheduling_group(scheduling_group sg, sstring new_name, sstring new_shortname) noexcept;
349 friend class reactor;
350 friend unsigned internal::scheduling_group_index(scheduling_group sg) noexcept;
351 friend scheduling_group internal::scheduling_group_from_index(unsigned index) noexcept;
352
353 template<typename SpecificValType, typename Mapper, typename Reducer, typename Initial>
354 requires requires(SpecificValType specific_val, Mapper mapper, Reducer reducer, Initial initial) {
355 {reducer(initial, mapper(specific_val))} -> std::convertible_to<Initial>;
356 }
358 map_reduce_scheduling_group_specific(Mapper mapper, Reducer reducer, Initial initial_val, scheduling_group_key key);
359
360 template<typename SpecificValType, typename Reducer, typename Initial>
361 requires requires(SpecificValType specific_val, Reducer reducer, Initial initial) {
362 {reducer(initial, specific_val)} -> std::convertible_to<Initial>;
363 }
364 friend future<typename function_traits<Reducer>::return_type>
365 reduce_scheduling_group_specific(Reducer reducer, Initial initial_val, scheduling_group_key key);
366
367
368};
369
371SEASTAR_MODULE_EXPORT_END
372namespace internal {
373
374inline
375unsigned
376scheduling_group_index(scheduling_group sg) noexcept {
377 return sg._id;
378}
379
380inline
381scheduling_group
382scheduling_group_from_index(unsigned index) noexcept {
383 return scheduling_group(index);
384}
385
386#ifdef SEASTAR_BUILD_SHARED_LIBS
387scheduling_group*
388current_scheduling_group_ptr() noexcept;
389#else
390inline
391scheduling_group*
392current_scheduling_group_ptr() noexcept {
393 // Slow unless constructor is constexpr
394 static thread_local scheduling_group sg;
395 return &sg;
396}
397#endif
398}
400
401SEASTAR_MODULE_EXPORT_BEGIN
403inline
404scheduling_group
406 return *internal::current_scheduling_group_ptr();
407}
408
409inline
410scheduling_group
411default_scheduling_group() noexcept {
412 return scheduling_group();
413}
414
415SEASTAR_MODULE_EXPORT_END
416
417inline
418bool
419scheduling_group::active() const noexcept {
420 return *this == current_scheduling_group();
421}
422
423}
424
425namespace std {
426
427SEASTAR_MODULE_EXPORT
428template <>
429struct hash<seastar::scheduling_group> {
430 size_t operator()(seastar::scheduling_group sg) const noexcept {
431 return seastar::internal::scheduling_group_index(sg);
432 }
433};
434
435}
A representation of a possibly not-yet-computed value.
Definition: future.hh:1219
Definition: reactor.hh:147
Definition: scheduling.hh:183
friend future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg) noexcept
friend T & scheduling_group_get_specific(scheduling_group_key key) noexcept
Definition: scheduling_specific.hh:170
scheduling_group_key(const scheduling_group_key &) noexcept=default
The only user allowed operation on a key is copying.
Identifies function calls that are accounted as a group.
Definition: scheduling.hh:293
float get_shares() const noexcept
constexpr scheduling_group() noexcept
Creates a scheduling_group object denoting the default group.
Definition: scheduling.hh:299
friend future rename_scheduling_group(scheduling_group sg, sstring new_name, sstring new_shortname) noexcept
friend future destroy_scheduling_group(scheduling_group sg) noexcept
future update_io_bandwidth(uint64_t bandwidth) const
Updates the current IO bandwidth for a given scheduling group.
friend future< scheduling_group > create_scheduling_group(sstring name, sstring shortname, float shares) noexcept
void set_shares(float shares) noexcept
friend future< typename function_traits< Reducer >::return_type > reduce_scheduling_group_specific(Reducer reducer, Initial initial_val, scheduling_group_key key)
Definition: scheduling_specific.hh:234
friend future< typename function_traits< Reducer >::return_type > map_reduce_scheduling_group_specific(Mapper mapper, Reducer reducer, Initial initial_val, scheduling_group_key key)
Definition: scheduling_specific.hh:200
T & get_specific(scheduling_group_key key) noexcept
Definition: scheduling.hh:314
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
scheduling_group current_scheduling_group() noexcept
Returns the current scheduling group.
Definition: scheduling.hh:405
T & scheduling_group_get_specific(scheduling_group sg, scheduling_group_key key)
Definition: scheduling_specific.hh:154
future destroy_scheduling_group(scheduling_group sg) noexcept
future rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept
future< scheduling_group > create_scheduling_group(sstring name, float shares) noexcept
scheduling_group_key_config make_scheduling_group_key_config(ConstructorArgs... args)
Definition: scheduling.hh:251
future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg) noexcept
STL namespace.
Definition: scheduling.hh:143
size_t allocation_size
The allocation size for the value (usually: sizeof(T))
Definition: scheduling.hh:161
std::function< void(void *)> constructor
A function that will be called for each newly allocated value.
Definition: scheduling.hh:167
std::function< void(void *)> rename
A function that will be called for each value after the scheduling group is renamed.
Definition: scheduling.hh:169
std::type_index type_index
Holds the type information for debug mode runtime validation.
Definition: scheduling.hh:165
scheduling_group_key_config()
Definition: scheduling.hh:147
size_t alignment
The required alignment of the value (usually: alignof(T))
Definition: scheduling.hh:163
scheduling_group_key_config(const std::type_info &type_info)
Definition: scheduling.hh:158
std::function< void(void *)> destructor
Definition: scheduling.hh:172