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 <functional>
27 #include <typeindex>
28 #endif
29 #include <seastar/core/sstring.hh>
30 #include <seastar/core/function_traits.hh>
31 #include <seastar/util/concepts.hh>
32 #include <seastar/util/modules.hh>
33 
35 
36 namespace seastar {
37 
38 SEASTAR_MODULE_EXPORT_BEGIN
39 constexpr unsigned max_scheduling_groups() { return SEASTAR_SCHEDULING_GROUPS_COUNT; }
40 
41 template <typename T = void>
42 class future;
43 
44 class reactor;
45 
46 class scheduling_group;
47 class scheduling_group_key;
48 
49 using sched_clock = std::chrono::steady_clock;
50 SEASTAR_MODULE_EXPORT_END
51 
52 namespace internal {
53 
54 // Returns an index between 0 and max_scheduling_groups()
55 unsigned scheduling_group_index(scheduling_group sg) noexcept;
56 scheduling_group scheduling_group_from_index(unsigned index) noexcept;
57 
58 unsigned long scheduling_group_key_id(scheduling_group_key) noexcept;
59 
60 template<typename T>
61 T* scheduling_group_get_specific_ptr(scheduling_group sg, scheduling_group_key key) noexcept;
62 
63 }
64 
65 SEASTAR_MODULE_EXPORT_BEGIN
66 
77 future<scheduling_group> create_scheduling_group(sstring name, float shares) noexcept;
78 
92 future<scheduling_group> create_scheduling_group(sstring name, sstring shortname, float shares) noexcept;
93 
104 
115 future<> rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept;
127 future<> 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 
184 public:
186  scheduling_group_key(const scheduling_group_key&) noexcept = default;
187  scheduling_group_key(scheduling_group_key&&) noexcept = default;
188 private:
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  }
195  friend class reactor;
197  template<typename T>
198  friend T* internal::scheduling_group_get_specific_ptr(scheduling_group sg, scheduling_group_key key) noexcept;
199  template<typename T>
200  friend T& scheduling_group_get_specific(scheduling_group_key key) noexcept;
201 
202  friend unsigned long internal::scheduling_group_key_id(scheduling_group_key key) noexcept;
203 };
204 
205 SEASTAR_MODULE_EXPORT_END
206 namespace internal {
207 
208 inline unsigned long scheduling_group_key_id(scheduling_group_key key) noexcept {
209  return key.id();
210 }
211 
230 template<typename ConstructorType, typename Tuple, size_t...Idx>
231 void apply_constructor(void* pre_alocated_mem, Tuple args, std::index_sequence<Idx...>) {
232  new (pre_alocated_mem) ConstructorType(std::get<Idx>(args)...);
233 }
234 }
235 SEASTAR_MODULE_EXPORT_BEGIN
236 
247 template <typename T, typename... ConstructorArgs>
248 scheduling_group_key_config
249 make_scheduling_group_key_config(ConstructorArgs... args) {
250  scheduling_group_key_config sgkc(typeid(T));
251  sgkc.allocation_size = sizeof(T);
252  sgkc.alignment = alignof(T);
253  sgkc.constructor = [args = std::make_tuple(args...)] (void* p) {
254  internal::apply_constructor<T>(p, args, std::make_index_sequence<sizeof...(ConstructorArgs)>());
255  };
256  sgkc.destructor = [] (void* p) {
257  static_cast<T*>(p)->~T();
258  };
259  return sgkc;
260 }
261 
270 
278 template<typename T>
280 
281 
287  unsigned _id;
288 private:
289  explicit scheduling_group(unsigned id) noexcept : _id(id) {}
290 public:
292  constexpr scheduling_group() noexcept : _id(0) {} // must be constexpr for current_scheduling_group_holder
293  bool active() const noexcept;
294  const sstring& name() const noexcept;
295  const sstring& short_name() const noexcept;
296  bool operator==(scheduling_group x) const noexcept { return _id == x._id; }
297  bool operator!=(scheduling_group x) const noexcept { return _id != x._id; }
298  bool is_main() const noexcept { return _id == 0; }
299  bool is_at_exit() const noexcept { return _id == 1; }
300  template<typename T>
308  return *internal::scheduling_group_get_specific_ptr<T>(*this, key);
309  }
322  void set_shares(float shares) noexcept;
323 
328  float get_shares() const noexcept;
329 
330 #if SEASTAR_API_LEVEL >= 7
338  future<> update_io_bandwidth(uint64_t bandwidth) const;
339 #endif
340 
341  friend future<scheduling_group> create_scheduling_group(sstring name, sstring shortname, float shares) noexcept;
343  friend future<> rename_scheduling_group(scheduling_group sg, sstring new_name, sstring new_shortname) noexcept;
344  friend class reactor;
345  friend unsigned internal::scheduling_group_index(scheduling_group sg) noexcept;
346  friend scheduling_group internal::scheduling_group_from_index(unsigned index) noexcept;
347 
348  template<typename SpecificValType, typename Mapper, typename Reducer, typename Initial>
349  SEASTAR_CONCEPT( requires requires(SpecificValType specific_val, Mapper mapper, Reducer reducer, Initial initial) {
350  {reducer(initial, mapper(specific_val))} -> std::convertible_to<Initial>;
351  })
352  friend future<typename function_traits<Reducer>::return_type>
353  map_reduce_scheduling_group_specific(Mapper mapper, Reducer reducer, Initial initial_val, scheduling_group_key key);
354 
355  template<typename SpecificValType, typename Reducer, typename Initial>
356  SEASTAR_CONCEPT( requires requires(SpecificValType specific_val, Reducer reducer, Initial initial) {
357  {reducer(initial, specific_val)} -> std::convertible_to<Initial>;
358  })
359  friend future<typename function_traits<Reducer>::return_type>
360  reduce_scheduling_group_specific(Reducer reducer, Initial initial_val, scheduling_group_key key);
361 
362 
363 };
364 
366 SEASTAR_MODULE_EXPORT_END
367 namespace internal {
368 
369 inline
370 unsigned
371 scheduling_group_index(scheduling_group sg) noexcept {
372  return sg._id;
373 }
374 
375 inline
376 scheduling_group
377 scheduling_group_from_index(unsigned index) noexcept {
378  return scheduling_group(index);
379 }
380 
381 #ifdef SEASTAR_BUILD_SHARED_LIBS
382 scheduling_group*
383 current_scheduling_group_ptr() noexcept;
384 #else
385 inline
386 scheduling_group*
387 current_scheduling_group_ptr() noexcept {
388  // Slow unless constructor is constexpr
389  static thread_local scheduling_group sg;
390  return &sg;
391 }
392 #endif
393 }
395 
396 SEASTAR_MODULE_EXPORT_BEGIN
398 inline
399 scheduling_group
401  return *internal::current_scheduling_group_ptr();
402 }
403 
404 inline
405 scheduling_group
406 default_scheduling_group() noexcept {
407  return scheduling_group();
408 }
409 
410 SEASTAR_MODULE_EXPORT_END
411 
412 inline
413 bool
414 scheduling_group::active() const noexcept {
415  return *this == current_scheduling_group();
416 }
417 
418 }
419 
420 namespace std {
421 
422 SEASTAR_MODULE_EXPORT
423 template <>
424 struct hash<seastar::scheduling_group> {
425  size_t operator()(seastar::scheduling_group sg) const noexcept {
426  return seastar::internal::scheduling_group_index(sg);
427  }
428 };
429 
430 }
A representation of a possibly not-yet-computed value.
Definition: future.hh:1238
Definition: reactor.hh:168
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:120
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:286
float get_shares() const noexcept
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:150
constexpr scheduling_group() noexcept
Creates a scheduling_group object denoting the default group.
Definition: scheduling.hh:292
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:184
friend future rename_scheduling_group(scheduling_group sg, sstring new_name, sstring new_shortname) noexcept
friend future< scheduling_group > create_scheduling_group(sstring name, sstring shortname, float shares) noexcept
T & get_specific(scheduling_group_key key) noexcept
Definition: scheduling.hh:307
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.
void set_shares(float shares) noexcept
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
future< scheduling_group > create_scheduling_group(sstring name, float shares) noexcept
scheduling_group current_scheduling_group() noexcept
Returns the current scheduling group.
Definition: scheduling.hh:400
T & scheduling_group_get_specific(scheduling_group sg, scheduling_group_key key)
Definition: scheduling_specific.hh:104
future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg) noexcept
future destroy_scheduling_group(scheduling_group sg) noexcept
future rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept
scheduling_group_key_config make_scheduling_group_key_config(ConstructorArgs... args)
Definition: scheduling.hh:249
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