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