1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 cfg_not_ffrt! { 15 use std::time::Duration; 16 use crate::builder::CallbackHook; 17 use crate::builder::ScheduleAlgo; 18 const BLOCKING_PERMANENT_THREAD_NUM: u8 = 0; 19 } 20 21 cfg_ffrt! { 22 use std::collections::HashMap; 23 use ylong_ffrt::Qos; 24 } 25 26 #[cfg(feature = "ffrt")] 27 pub(crate) struct CommonBuilder { 28 /// Name prefix of worker threads 29 pub(crate) worker_name: Option<String>, 30 /// Thread stack size for each qos 31 pub(crate) stack_size_by_qos: HashMap<Qos, usize>, 32 } 33 34 #[cfg(not(feature = "ffrt"))] 35 pub(crate) struct CommonBuilder { 36 /// Name prefix of worker threads 37 pub(crate) worker_name: Option<String>, 38 39 /// Core affinity, default set to true 40 pub(crate) is_affinity: bool, 41 42 /// How long the blocking thread will be kept alive after becoming idle 43 pub(crate) keep_alive_time: Option<Duration>, 44 45 /// Maximum thread number for blocking thread pool 46 pub(crate) max_blocking_pool_size: Option<u8>, 47 48 /// Schedule policy, default set to FIFO 49 pub(crate) schedule_algo: ScheduleAlgo, 50 51 /// Maximum number of permanent threads 52 pub(crate) blocking_permanent_thread_num: u8, 53 54 /// Worker thread stack size 55 pub(crate) stack_size: Option<usize>, 56 57 /// A callback function to be called after starting a worker thread 58 pub(crate) after_start: Option<CallbackHook>, 59 60 /// A callback function to be called before stopping a worker thread 61 pub(crate) before_stop: Option<CallbackHook>, 62 } 63 64 #[cfg(feature = "ffrt")] 65 impl CommonBuilder { new() -> Self66 pub(crate) fn new() -> Self { 67 CommonBuilder { 68 worker_name: None, 69 stack_size_by_qos: HashMap::new(), 70 } 71 } 72 } 73 74 #[cfg(not(feature = "ffrt"))] 75 impl CommonBuilder { new() -> Self76 pub(crate) fn new() -> Self { 77 CommonBuilder { 78 worker_name: None, 79 is_affinity: false, 80 blocking_permanent_thread_num: BLOCKING_PERMANENT_THREAD_NUM, 81 max_blocking_pool_size: None, 82 schedule_algo: ScheduleAlgo::FifoBound, 83 stack_size: None, 84 after_start: None, 85 before_stop: None, 86 keep_alive_time: None, 87 } 88 } 89 } 90 91 #[cfg(not(feature = "ffrt"))] 92 macro_rules! impl_common { 93 ($self:ident) => { 94 use std::sync::Arc; 95 use std::time::Duration; 96 97 use crate::builder::ScheduleAlgo; 98 99 impl $self { 100 /// Sets the name prefix for all worker threads. 101 pub fn worker_name(mut self, name: String) -> Self { 102 self.common.worker_name = Some(name); 103 self 104 } 105 106 /// Sets the core affinity of the worker threads 107 pub fn is_affinity(mut self, is_affinity: bool) -> Self { 108 self.common.is_affinity = is_affinity; 109 self 110 } 111 112 /// Sets the schedule policy. 113 pub fn schedule_algo(mut self, schedule_algo: ScheduleAlgo) -> Self { 114 self.common.schedule_algo = schedule_algo; 115 self 116 } 117 118 /// Sets the callback function to be called when a worker thread starts. 119 pub fn after_start<F>(mut self, f: F) -> Self 120 where 121 F: Fn() + Send + Sync + 'static, 122 { 123 self.common.after_start = Some(Arc::new(f)); 124 self 125 } 126 127 /// Sets the callback function to be called when a worker thread stops. 128 pub fn before_stop<F>(mut self, f: F) -> Self 129 where 130 F: Fn() + Send + Sync + 'static, 131 { 132 self.common.before_stop = Some(Arc::new(f)); 133 self 134 } 135 136 /// Sets the maximum number of permanent threads in blocking thread pool 137 pub fn blocking_permanent_thread_num( 138 mut self, 139 blocking_permanent_thread_num: u8, 140 ) -> Self { 141 self.common.blocking_permanent_thread_num = blocking_permanent_thread_num; 142 self 143 } 144 145 /// Sets the number of threads that the runtime could spawn additionally 146 /// besides the core thread pool. 147 /// 148 /// The boundary is 1-64. 149 pub fn max_blocking_pool_size(mut self, max_blocking_pool_size: u8) -> Self { 150 if max_blocking_pool_size < 1 { 151 self.common.max_blocking_pool_size = Some(1); 152 } else if max_blocking_pool_size > 64 { 153 self.common.max_blocking_pool_size = Some(64); 154 } else { 155 self.common.max_blocking_pool_size = Some(max_blocking_pool_size); 156 } 157 self 158 } 159 160 /// Sets how long will the thread be kept alive inside the blocking pool 161 /// after it becomes idle. 162 pub fn keep_alive_time(mut self, keep_alive_time: Duration) -> Self { 163 self.common.keep_alive_time = Some(keep_alive_time); 164 self 165 } 166 167 /// Sets the stack size for every worker thread that gets spawned by the 168 /// runtime. The minimum stack size is 1. 169 pub fn worker_stack_size(mut self, stack_size: usize) -> Self { 170 if stack_size < 1 { 171 self.common.stack_size = Some(1); 172 } else { 173 self.common.stack_size = Some(stack_size); 174 } 175 self 176 } 177 } 178 }; 179 } 180 181 #[cfg(not(feature = "ffrt"))] 182 pub(crate) use impl_common; 183