1 // Copyright 2022 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_SRC_CORE_LIB_GPRPP_PER_CPU_H 16 #define GRPC_SRC_CORE_LIB_GPRPP_PER_CPU_H 17 18 #include <grpc/support/port_platform.h> 19 20 #include <algorithm> 21 #include <cstddef> 22 #include <limits> 23 #include <memory> 24 25 #include "src/core/lib/iomgr/exec_ctx.h" 26 27 namespace grpc_core { 28 29 class PerCpuOptions { 30 public: 31 // Set the number of cpus that colocate on the same shard SetCpusPerShard(size_t cpus_per_shard)32 PerCpuOptions SetCpusPerShard(size_t cpus_per_shard) { 33 cpus_per_shard_ = std::max<size_t>(1, cpus_per_shard); 34 return *this; 35 } 36 37 // Set the maximum number of allowable shards SetMaxShards(size_t max_shards)38 PerCpuOptions SetMaxShards(size_t max_shards) { 39 max_shards_ = std::max<size_t>(1, max_shards); 40 return *this; 41 } 42 cpus_per_shard()43 size_t cpus_per_shard() const { return cpus_per_shard_; } max_shards()44 size_t max_shards() const { return max_shards_; } 45 46 size_t Shards(); 47 size_t ShardsForCpuCount(size_t cpu_count); 48 49 private: 50 size_t cpus_per_shard_ = 1; 51 size_t max_shards_ = std::numeric_limits<size_t>::max(); 52 }; 53 54 template <typename T> 55 class PerCpu { 56 public: 57 // Options are not defaulted to try and force consideration of what the 58 // options specify. PerCpu(PerCpuOptions options)59 explicit PerCpu(PerCpuOptions options) : cpus_(options.Shards()) {} 60 this_cpu()61 T& this_cpu() { return data_[ExecCtx::Get()->starting_cpu() % cpus_]; } 62 begin()63 T* begin() { return data_.get(); } end()64 T* end() { return data_.get() + cpus_; } begin()65 const T* begin() const { return data_.get(); } end()66 const T* end() const { return data_.get() + cpus_; } 67 68 private: 69 const size_t cpus_; 70 std::unique_ptr<T[]> data_{new T[cpus_]}; 71 }; 72 73 } // namespace grpc_core 74 75 #endif // GRPC_SRC_CORE_LIB_GPRPP_PER_CPU_H 76