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 #include <typeindex>
25 #include <seastar/core/sstring.hh>
26 #include <seastar/core/function_traits.hh>
27 #include <seastar/util/concepts.hh>
28 
30 
31 namespace seastar {
32 
33 constexpr unsigned max_scheduling_groups() { return 16; }
34 
35 #if SEASTAR_API_LEVEL < 6
36 #define SEASTAR_ELLIPSIS ...
37 template <typename SEASTAR_ELLIPSIS T>
38 #else
39 #define SEASTAR_ELLIPSIS
40 template <typename T = void>
41 #endif
42 class future;
43 
44 class reactor;
45 
46 class scheduling_group;
47 class scheduling_group_key;
48 
49 namespace internal {
50 
51 // Returns an index between 0 and max_scheduling_groups()
52 unsigned scheduling_group_index(scheduling_group sg) noexcept;
53 scheduling_group scheduling_group_from_index(unsigned index) noexcept;
54 
55 unsigned long scheduling_group_key_id(scheduling_group_key) noexcept;
56 
57 template<typename T>
58 T* scheduling_group_get_specific_ptr(scheduling_group sg, scheduling_group_key key) noexcept;
59 
60 }
61 
62 
73 future<scheduling_group> create_scheduling_group(sstring name, float shares) noexcept;
74 
85 
96 future<> rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept;
97 
98 
117  scheduling_group_key_config(typeid(void)) {}
127  scheduling_group_key_config(const std::type_info& type_info) :
128  type_index(type_info) {}
132  size_t alignment;
134  std::type_index type_index;
136  std::function<void (void*)> constructor;
139  std::function<void (void*)> destructor;
140 
141 };
142 
143 
151 public:
153  scheduling_group_key(const scheduling_group_key&) noexcept = default;
154  scheduling_group_key(scheduling_group_key&&) noexcept = default;
155 private:
156  scheduling_group_key(unsigned long id) noexcept :
157  _id(id) {}
158  unsigned long _id;
159  unsigned long id() const noexcept {
160  return _id;
161  }
162  friend class reactor;
164  template<typename T>
165  friend T* internal::scheduling_group_get_specific_ptr(scheduling_group sg, scheduling_group_key key) noexcept;
166  template<typename T>
167  friend T& scheduling_group_get_specific(scheduling_group_key key) noexcept;
168 
169  friend unsigned long internal::scheduling_group_key_id(scheduling_group_key key) noexcept;
170 };
171 
172 namespace internal {
173 
174 inline unsigned long scheduling_group_key_id(scheduling_group_key key) noexcept {
175  return key.id();
176 }
177 
196 template<typename ConstructorType, typename Tuple, size_t...Idx>
197 void apply_constructor(void* pre_alocated_mem, Tuple args, std::index_sequence<Idx...> idx_seq) {
198  new (pre_alocated_mem) ConstructorType(std::get<Idx>(args)...);
199 }
200 }
201 
212 template <typename T, typename... ConstructorArgs>
213 scheduling_group_key_config
214 make_scheduling_group_key_config(ConstructorArgs... args) {
215  scheduling_group_key_config sgkc(typeid(T));
216  sgkc.allocation_size = sizeof(T);
217  sgkc.alignment = alignof(T);
218  sgkc.constructor = [args = std::make_tuple(args...)] (void* p) {
219  internal::apply_constructor<T>(p, args, std::make_index_sequence<sizeof...(ConstructorArgs)>());
220  };
221  sgkc.destructor = [] (void* p) {
222  static_cast<T*>(p)->~T();
223  };
224  return sgkc;
225 }
226 
235 
243 template<typename T>
245 
246 
252  unsigned _id;
253 private:
254  explicit scheduling_group(unsigned id) noexcept : _id(id) {}
255 public:
257  constexpr scheduling_group() noexcept : _id(0) {} // must be constexpr for current_scheduling_group_holder
258  bool active() const noexcept;
259  const sstring& name() const noexcept;
260  bool operator==(scheduling_group x) const noexcept { return _id == x._id; }
261  bool operator!=(scheduling_group x) const noexcept { return _id != x._id; }
262  bool is_main() const noexcept { return _id == 0; }
263  template<typename T>
271  return *internal::scheduling_group_get_specific_ptr<T>(*this, key);
272  }
285  void set_shares(float shares) noexcept;
286  friend future<scheduling_group> create_scheduling_group(sstring name, float shares) noexcept;
288  friend future<> rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept;
289  friend class reactor;
290  friend unsigned internal::scheduling_group_index(scheduling_group sg) noexcept;
291  friend scheduling_group internal::scheduling_group_from_index(unsigned index) noexcept;
292 
293  template<typename SpecificValType, typename Mapper, typename Reducer, typename Initial>
294  SEASTAR_CONCEPT( requires requires(SpecificValType specific_val, Mapper mapper, Reducer reducer, Initial initial) {
295  {reducer(initial, mapper(specific_val))} -> std::convertible_to<Initial>;
296  })
297  friend future<typename function_traits<Reducer>::return_type>
298  map_reduce_scheduling_group_specific(Mapper mapper, Reducer reducer, Initial initial_val, scheduling_group_key key);
299 
300  template<typename SpecificValType, typename Reducer, typename Initial>
301  SEASTAR_CONCEPT( requires requires(SpecificValType specific_val, Reducer reducer, Initial initial) {
302  {reducer(initial, specific_val)} -> std::convertible_to<Initial>;
303  })
304  friend future<typename function_traits<Reducer>::return_type>
305  reduce_scheduling_group_specific(Reducer reducer, Initial initial_val, scheduling_group_key key);
306 
307 
308 };
309 
311 namespace internal {
312 
313 inline
314 unsigned
315 scheduling_group_index(scheduling_group sg) noexcept {
316  return sg._id;
317 }
318 
319 inline
320 scheduling_group
321 scheduling_group_from_index(unsigned index) noexcept {
322  return scheduling_group(index);
323 }
324 
325 inline
326 scheduling_group*
327 current_scheduling_group_ptr() noexcept {
328  // Slow unless constructor is constexpr
329  static thread_local scheduling_group sg;
330  return &sg;
331 }
332 
333 }
335 
337 inline
338 scheduling_group
340  return *internal::current_scheduling_group_ptr();
341 }
342 
343 inline
344 scheduling_group
345 default_scheduling_group() noexcept {
346  return scheduling_group();
347 }
348 
349 inline
350 bool
351 scheduling_group::active() const noexcept {
352  return *this == current_scheduling_group();
353 }
354 
355 }
356 
357 namespace std {
358 
359 template <>
360 struct hash<seastar::scheduling_group> {
361  size_t operator()(seastar::scheduling_group sg) const noexcept {
362  return seastar::internal::scheduling_group_index(sg);
363  }
364 };
365 
366 }
seastar::scheduling_group::reduce_scheduling_group_specific
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:174
seastar
Seastar API namespace.
Definition: abort_on_ebadf.hh:24
seastar::scheduling_group::rename_scheduling_group
friend future rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept
seastar::reactor
Definition: reactor.hh:187
seastar::scheduling_group_key
Definition: scheduling.hh:150
seastar::scheduling_group_key_config
Definition: scheduling.hh:112
seastar::scheduling_group::map_reduce_scheduling_group_specific
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:140
seastar::scheduling_group_key_config::allocation_size
size_t allocation_size
The allocation size for the value (usually: sizeof(T))
Definition: scheduling.hh:130
seastar::rename_scheduling_group
future rename_scheduling_group(scheduling_group sg, sstring new_name) noexcept
seastar::scheduling_group_key_config::scheduling_group_key_config
scheduling_group_key_config(const std::type_info &type_info)
Definition: scheduling.hh:127
seastar::create_scheduling_group
future< scheduling_group > create_scheduling_group(sstring name, float shares) noexcept
seastar::scheduling_group_key_config::destructor
std::function< void(void *)> destructor
Definition: scheduling.hh:139
seastar::scheduling_group_key::scheduling_group_get_specific
friend T & scheduling_group_get_specific(scheduling_group_key key) noexcept
Definition: scheduling_specific.hh:110
seastar::scheduling_group_key_create
future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg) noexcept
seastar::scheduling_group::get_specific
T & get_specific(scheduling_group_key key) noexcept
Definition: scheduling.hh:270
seastar::destroy_scheduling_group
future destroy_scheduling_group(scheduling_group sg) noexcept
seastar::current_scheduling_group
scheduling_group current_scheduling_group() noexcept
Returns the current scheduling group.
Definition: scheduling.hh:339
seastar::scheduling_group_key_config::alignment
size_t alignment
The required alignment of the value (usually: alignof(T))
Definition: scheduling.hh:132
seastar::scheduling_group::create_scheduling_group
friend future< scheduling_group > create_scheduling_group(sstring name, float shares) noexcept
seastar::scheduling_group_get_specific
T & scheduling_group_get_specific(scheduling_group sg, scheduling_group_key key)
Definition: scheduling_specific.hh:94
seastar::scheduling_group_key_config::scheduling_group_key_config
scheduling_group_key_config()
Definition: scheduling.hh:116
seastar::scheduling_group_key_config::constructor
std::function< void(void *)> constructor
A function that will be called for each newly allocated value.
Definition: scheduling.hh:136
seastar::future
A representation of a possibly not-yet-computed value.
Definition: future.hh:1337
seastar::scheduling_group_key::scheduling_group_key_create
friend future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg) noexcept
seastar::scheduling_group_key::scheduling_group_key
scheduling_group_key(const scheduling_group_key &) noexcept=default
The only user allowed operation on a key is copying.
seastar::scheduling_group::scheduling_group
constexpr scheduling_group() noexcept
Creates a scheduling_group object denoting the default group.
Definition: scheduling.hh:257
seastar::scheduling_group::destroy_scheduling_group
friend future destroy_scheduling_group(scheduling_group sg) noexcept
seastar::make_scheduling_group_key_config
scheduling_group_key_config make_scheduling_group_key_config(ConstructorArgs... args)
Definition: scheduling.hh:214
seastar::scheduling_group::set_shares
void set_shares(float shares) noexcept
seastar::scheduling_group_key_config::type_index
std::type_index type_index
Holds the type information for debug mode runtime validation.
Definition: scheduling.hh:134
seastar::scheduling_group
Identifies function calls that are accounted as a group.
Definition: scheduling.hh:251