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/gcc6-concepts.hh>
28 
30 
31 namespace seastar {
32 
33 constexpr unsigned max_scheduling_groups() { return 16; }
34 
35 template <typename... T>
36 class future;
37 
38 class reactor;
39 
40 class scheduling_group;
41 class scheduling_group_key;
42 
43 namespace internal {
44 
45 // Returns an index between 0 and max_scheduling_groups()
46 unsigned scheduling_group_index(scheduling_group sg);
47 scheduling_group scheduling_group_from_index(unsigned index);
48 
49 unsigned long scheduling_group_key_id(scheduling_group_key);
50 
51 }
52 
53 
64 future<scheduling_group> create_scheduling_group(sstring name, float shares);
65 
75 future<> destroy_scheduling_group(scheduling_group sg);
76 
87 future<> rename_scheduling_group(scheduling_group sg, sstring new_name);
88 
89 
108  scheduling_group_key_config(typeid(void)) {}
118  scheduling_group_key_config(const std::type_info& type_info) :
119  type_index(type_info) {}
123  size_t alignment;
125  std::type_index type_index;
127  std::function<void (void*)> constructor;
130  std::function<void (void*)> destructor;
131 
132 };
133 
134 
142 public:
144  scheduling_group_key(const scheduling_group_key&) = default;
145 private:
146  scheduling_group_key(unsigned long id) :
147  _id(id) {}
148  unsigned long _id;
149  unsigned long id() const {
150  return _id;
151  }
152  friend class reactor;
154  template<typename T>
156  template<typename T>
158 
159  friend unsigned long internal::scheduling_group_key_id(scheduling_group_key key) {
160  return key.id();
161  }
162 };
163 
164 namespace internal {
183 template<typename ConstructorType, typename Tuple, size_t...Idx>
184 void apply_constructor(void* pre_alocated_mem, Tuple args, std::index_sequence<Idx...> idx_seq) {
185  new (pre_alocated_mem) ConstructorType(std::get<Idx>(args)...);
186 }
187 }
188 
199 template <typename T, typename... ConstructorArgs>
200 scheduling_group_key_config
201 make_scheduling_group_key_config(ConstructorArgs... args) {
202  scheduling_group_key_config sgkc(typeid(T));
203  sgkc.allocation_size = sizeof(T);
204  sgkc.alignment = alignof(T);
205  sgkc.constructor = [args = std::make_tuple(args...)] (void* p) {
206  internal::apply_constructor<T>(p, args, std::make_index_sequence<sizeof...(ConstructorArgs)>());
207  };
208  sgkc.destructor = [] (void* p) {
209  static_cast<T*>(p)->~T();
210  };
211  return sgkc;
212 }
213 
221 future<scheduling_group_key> scheduling_group_key_create(scheduling_group_key_config cfg);
222 
230 template<typename T>
231 T& scheduling_group_get_specific(scheduling_group sg, scheduling_group_key key);
232 
233 
239  unsigned _id;
240 private:
241  explicit scheduling_group(unsigned id) : _id(id) {}
242 public:
244  constexpr scheduling_group() noexcept : _id(0) {} // must be constexpr for current_scheduling_group_holder
245  bool active() const;
246  const sstring& name() const;
247  bool operator==(scheduling_group x) const { return _id == x._id; }
248  bool operator!=(scheduling_group x) const { return _id != x._id; }
249  bool is_main() const { return _id == 0; }
250  template<typename T>
258  return scheduling_group_get_specific<T>(*this, key);
259  }
272  void set_shares(float shares);
273  friend future<scheduling_group> create_scheduling_group(sstring name, float shares);
275  friend future<> rename_scheduling_group(scheduling_group sg, sstring new_name);
276  friend class reactor;
277  friend unsigned internal::scheduling_group_index(scheduling_group sg);
278  friend scheduling_group internal::scheduling_group_from_index(unsigned index);
279 
280  template<typename SpecificValType, typename Mapper, typename Reducer, typename Initial>
281  GCC6_CONCEPT( requires requires(SpecificValType specific_val, Mapper mapper, Reducer reducer, Initial initial) {
282  {reducer(initial, mapper(specific_val))} -> Initial;
283  })
284  friend future<typename function_traits<Reducer>::return_type>
285  map_reduce_scheduling_group_specific(Mapper mapper, Reducer reducer, Initial initial_val, scheduling_group_key key);
286 
287  template<typename SpecificValType, typename Reducer, typename Initial>
288  GCC6_CONCEPT( requires requires(SpecificValType specific_val, Reducer reducer, Initial initial) {
289  {reducer(initial, specific_val)} -> Initial;
290  })
291  friend future<typename function_traits<Reducer>::return_type>
292  reduce_scheduling_group_specific(Reducer reducer, Initial initial_val, scheduling_group_key key);
293 
294 
295 };
296 
298 namespace internal {
299 
300 inline
301 unsigned
302 scheduling_group_index(scheduling_group sg) {
303  return sg._id;
304 }
305 
306 inline
307 scheduling_group
308 scheduling_group_from_index(unsigned index) {
309  return scheduling_group(index);
310 }
311 
312 inline
313 scheduling_group*
314 current_scheduling_group_ptr() {
315  // Slow unless constructor is constexpr
316  static thread_local scheduling_group sg;
317  return &sg;
318 }
319 
320 }
322 
324 inline
325 scheduling_group
327  return *internal::current_scheduling_group_ptr();
328 }
329 
330 inline
331 scheduling_group
332 default_scheduling_group() {
333  return scheduling_group();
334 }
335 
336 inline
337 bool
338 scheduling_group::active() const {
339  return *this == current_scheduling_group();
340 }
341 
342 }
343 
344 namespace std {
345 
346 template <>
347 struct hash<seastar::scheduling_group> {
348  size_t operator()(seastar::scheduling_group sg) const {
349  return seastar::internal::scheduling_group_index(sg);
350  }
351 };
352 
353 }
A representation of a possibly not-yet-computed value.
Definition: future.hh:79
scheduling_group_key(const scheduling_group_key &)=default
The only user allowed operation on a key is copying.
scheduling_group current_scheduling_group()
Returns the current scheduling group.
Definition: scheduling.hh:326
size_t allocation_size
The allocation size for the value (usually: sizeof(T))
Definition: scheduling.hh:121
std::function< void(void *)> destructor
Definition: scheduling.hh:130
future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg)
STL namespace.
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:119
Definition: reactor.hh:181
friend future rename_scheduling_group(scheduling_group sg, sstring new_name)
friend future< scheduling_group_key > scheduling_group_key_create(scheduling_group_key_config cfg)
T & scheduling_group_get_specific(scheduling_group sg, scheduling_group_key key)
Definition: scheduling_specific.hh:70
Identifies function calls that are accounted as a group.
Definition: scheduling.hh:238
future destroy_scheduling_group(scheduling_group sg)
std::type_index type_index
Holds the type information for debug mode runtime validation.
Definition: scheduling.hh:125
scheduling_group_key_config()
Definition: scheduling.hh:107
friend T & scheduling_group_get_specific(scheduling_group sg, scheduling_group_key key)
Definition: scheduling_specific.hh:70
future< scheduling_group > create_scheduling_group(sstring name, float shares)
constexpr scheduling_group() noexcept
Creates a scheduling_group object denoting the default group.
Definition: scheduling.hh:244
size_t alignment
The required alignment of the value (usually: alignof(T))
Definition: scheduling.hh:123
friend future< scheduling_group > create_scheduling_group(sstring name, float shares)
future rename_scheduling_group(scheduling_group sg, sstring new_name)
scheduling_group_key_config(const std::type_info &type_info)
Definition: scheduling.hh:118
Definition: scheduling.hh:103
void set_shares(float shares)
scheduling_group_key_config make_scheduling_group_key_config(ConstructorArgs... args)
Definition: scheduling.hh:201
friend future destroy_scheduling_group(scheduling_group sg)
T & get_specific(scheduling_group_key key)
Definition: scheduling.hh:257
Seastar API namespace.
Definition: abort_on_ebadf.hh:24
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:153
Definition: scheduling.hh:141
std::function< void(void *)> constructor
A function that will be called for each newly allocated value.
Definition: scheduling.hh:127