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 use std::time::Duration; 15 16 use crate::builder::CallbackHook; 17 use crate::executor::blocking_pool::BLOCKING_MAX_THEAD_NUM; 18 cfg_not_ffrt!( 19 use crate::builder::ScheduleAlgo; 20 ); 21 22 const BLOCKING_PERMANENT_THREAD_NUM: u8 = 0; 23 24 pub(crate) struct CommonBuilder { 25 /// Name prefix of worker threads 26 pub(crate) worker_name: Option<String>, 27 28 /// Core affinity, default set to true 29 #[cfg(not(feature = "ffrt"))] 30 pub(crate) is_affinity: bool, 31 32 /// How long the blocking thread will be kept alive after becoming idle 33 pub(crate) keep_alive_time: Option<Duration>, 34 35 /// Maximum thread number for blocking thread pool 36 pub(crate) max_blocking_pool_size: Option<u8>, 37 38 /// Schedule policy, default set to FIFO 39 #[cfg(not(feature = "ffrt"))] 40 pub(crate) schedule_algo: ScheduleAlgo, 41 42 /// Maximum number of permanent threads 43 pub(crate) blocking_permanent_thread_num: u8, 44 45 /// Worker thread stack size 46 pub(crate) stack_size: Option<usize>, 47 48 /// A callback function to be called after starting a worker thread 49 pub(crate) after_start: Option<CallbackHook>, 50 51 /// A callback function to be called before stopping a worker thread 52 pub(crate) before_stop: Option<CallbackHook>, 53 } 54 55 impl CommonBuilder { new() -> Self56 pub(crate) fn new() -> Self { 57 CommonBuilder { 58 worker_name: None, 59 #[cfg(not(feature = "ffrt"))] 60 is_affinity: true, 61 blocking_permanent_thread_num: BLOCKING_PERMANENT_THREAD_NUM, 62 max_blocking_pool_size: Some(BLOCKING_MAX_THEAD_NUM), 63 #[cfg(not(feature = "ffrt"))] 64 schedule_algo: ScheduleAlgo::FifoBound, 65 stack_size: None, 66 after_start: None, 67 before_stop: None, 68 keep_alive_time: None, 69 } 70 } 71 } 72 73 macro_rules! impl_common { 74 ($self:ident) => { 75 use std::time::Duration; 76 cfg_not_ffrt!( 77 use crate::builder::ScheduleAlgo; 78 use std::sync::Arc; 79 ); 80 81 #[cfg(not(feature = "ffrt"))] 82 impl $self { 83 /// Sets the core affinity of the worker threads 84 pub fn is_affinity(mut self, is_affinity: bool) -> Self { 85 self.common.is_affinity = is_affinity; 86 self 87 } 88 89 /// Sets the schedule policy. 90 pub fn schedule_algo(mut self, schedule_algo: ScheduleAlgo) -> Self { 91 self.common.schedule_algo = schedule_algo; 92 self 93 } 94 95 /// Sets the callback function to be called when a worker thread starts. 96 pub fn after_start<F>(mut self, f: F) -> Self 97 where 98 F: Fn() + Send + Sync + 'static, 99 { 100 self.common.after_start = Some(Arc::new(f)); 101 self 102 } 103 104 /// Sets the callback function to be called when a worker thread stops. 105 pub fn before_stop<F>(mut self, f: F) -> Self 106 where 107 F: Fn() + Send + Sync + 'static, 108 { 109 self.common.before_stop = Some(Arc::new(f)); 110 self 111 } 112 } 113 114 impl $self { 115 /// Sets the name prefix for all worker threads. 116 pub fn worker_name(mut self, name: String) -> Self { 117 self.common.worker_name = Some(name); 118 self 119 } 120 121 /// Sets the maximum number of permanent threads in blocking thread pool 122 pub fn blocking_permanent_thread_num( 123 mut self, 124 blocking_permanent_thread_num: u8, 125 ) -> Self { 126 if blocking_permanent_thread_num > self.common.max_blocking_pool_size.unwrap() { 127 self.common.blocking_permanent_thread_num = 128 self.common.max_blocking_pool_size.unwrap(); 129 } else { 130 self.common.blocking_permanent_thread_num = blocking_permanent_thread_num; 131 } 132 self 133 } 134 135 /// Sets the number of threads that the runtime could spawn additionally 136 /// besides the core thread pool. 137 /// 138 /// The boundary is 1-64. 139 pub fn max_blocking_pool_size(mut self, max_blocking_pool_size: u8) -> Self { 140 if max_blocking_pool_size < 1 { 141 self.common.max_blocking_pool_size = Some(1); 142 } else if max_blocking_pool_size > 64 { 143 self.common.max_blocking_pool_size = Some(64); 144 } else { 145 self.common.max_blocking_pool_size = Some(max_blocking_pool_size); 146 } 147 self 148 } 149 150 /// Sets the stack size for every worker thread that gets spawned by the 151 /// runtime. The minimum stack size is 1. 152 pub fn worker_stack_size(mut self, stack_size: usize) -> Self { 153 if stack_size < 1 { 154 self.common.stack_size = Some(1); 155 } else { 156 self.common.stack_size = Some(stack_size); 157 } 158 self 159 } 160 161 /// Sets how long will the thread be kept alive inside the blocking pool 162 /// after it becomes idle. 163 pub fn keep_alive_time(mut self, keep_alive_time: Duration) -> Self { 164 self.common.keep_alive_time = Some(keep_alive_time); 165 self 166 } 167 } 168 }; 169 } 170 171 pub(crate) use impl_common; 172