• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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