1
1
use std:: {
2
2
collections:: { BTreeMap , VecDeque } ,
3
3
fmt:: Debug ,
4
- num:: NonZeroUsize ,
5
4
sync:: atomic:: { AtomicU32 , Ordering } ,
6
5
} ;
7
6
@@ -22,21 +21,20 @@ use crate::tasks::{
22
21
#[ derive( Debug , Clone ) ]
23
22
pub ( crate ) struct Scheduler {
24
23
scheduler_thread_id : u32 ,
25
- capacity : NonZeroUsize ,
26
24
channel : UnboundedSender < SchedulerMessage > ,
27
25
}
28
26
29
27
impl Scheduler {
30
28
/// Spin up a scheduler on the current thread and get a channel that can be
31
29
/// used to communicate with it.
32
- pub ( crate ) fn spawn ( capacity : NonZeroUsize ) -> Scheduler {
30
+ pub ( crate ) fn spawn ( ) -> Scheduler {
33
31
let ( sender, mut receiver) = mpsc:: unbounded_channel ( ) ;
34
32
35
33
let thread_id = wasmer:: current_thread_id ( ) ;
36
34
// Safety: we just got the thread ID.
37
- let sender = unsafe { Scheduler :: new ( sender, thread_id, capacity ) } ;
35
+ let sender = unsafe { Scheduler :: new ( sender, thread_id) } ;
38
36
39
- let mut scheduler = SchedulerState :: new ( capacity , sender. clone ( ) ) ;
37
+ let mut scheduler = SchedulerState :: new ( sender. clone ( ) ) ;
40
38
41
39
tracing:: debug!( thread_id, "Spinning up the scheduler" ) ;
42
40
wasm_bindgen_futures:: spawn_local (
@@ -67,16 +65,11 @@ impl Scheduler {
67
65
///
68
66
/// The `scheduler_thread_id` must match the [`wasmer::current_thread_id()`]
69
67
/// otherwise these `!Send` values will be sent between threads.
70
- unsafe fn new (
71
- channel : UnboundedSender < SchedulerMessage > ,
72
- scheduler_thread_id : u32 ,
73
- capacity : NonZeroUsize ,
74
- ) -> Self {
68
+ unsafe fn new ( channel : UnboundedSender < SchedulerMessage > , scheduler_thread_id : u32 ) -> Self {
75
69
debug_assert_eq ! ( scheduler_thread_id, wasmer:: current_thread_id( ) ) ;
76
70
Scheduler {
77
71
channel,
78
72
scheduler_thread_id,
79
- capacity,
80
73
}
81
74
}
82
75
@@ -102,10 +95,6 @@ impl Scheduler {
102
95
Ok ( ( ) )
103
96
}
104
97
}
105
-
106
- pub ( crate ) fn capacity ( & self ) -> NonZeroUsize {
107
- self . capacity
108
- }
109
98
}
110
99
111
100
// Safety: The only way our !Send messages will be sent to the scheduler is if
@@ -117,8 +106,6 @@ unsafe impl Sync for Scheduler {}
117
106
/// The state for the actor in charge of the threadpool.
118
107
#[ derive( Debug ) ]
119
108
struct SchedulerState {
120
- /// The maximum number of workers we will start.
121
- capacity : NonZeroUsize ,
122
109
/// Workers that are able to receive work.
123
110
idle : VecDeque < WorkerHandle > ,
124
111
/// Workers that are currently blocked on synchronous operations and can't
@@ -130,9 +117,8 @@ struct SchedulerState {
130
117
}
131
118
132
119
impl SchedulerState {
133
- fn new ( capacity : NonZeroUsize , mailbox : Scheduler ) -> Self {
120
+ fn new ( mailbox : Scheduler ) -> Self {
134
121
SchedulerState {
135
- capacity,
136
122
idle : VecDeque :: new ( ) ,
137
123
busy : VecDeque :: new ( ) ,
138
124
mailbox,
@@ -213,14 +199,14 @@ impl SchedulerState {
213
199
/// Send a task to one of the worker threads, preferring workers that aren't
214
200
/// running synchronous work.
215
201
fn post_message ( & mut self , msg : PostMessagePayload ) -> Result < ( ) , Error > {
216
- let ( worker, already_blocked ) = self . next_available_worker ( ) ?;
202
+ let worker = self . next_available_worker ( ) ?;
217
203
218
204
let would_block = msg. would_block ( ) ;
219
205
worker
220
206
. send ( msg)
221
207
. with_context ( || format ! ( "Unable to send a message to worker {}" , worker. id( ) ) ) ?;
222
208
223
- if would_block || already_blocked {
209
+ if would_block {
224
210
self . busy . push_back ( worker) ;
225
211
} else {
226
212
self . idle . push_back ( worker) ;
@@ -229,43 +215,25 @@ impl SchedulerState {
229
215
Ok ( ( ) )
230
216
}
231
217
232
- fn next_available_worker ( & mut self ) -> Result < ( WorkerHandle , bool ) , Error > {
218
+ fn next_available_worker ( & mut self ) -> Result < WorkerHandle , Error > {
233
219
// First, try to send the message to an idle worker
234
220
if let Some ( worker) = self . idle . pop_front ( ) {
235
221
tracing:: trace!(
236
222
worker. id = worker. id( ) ,
237
223
"Sending the message to an idle worker"
238
224
) ;
239
- return Ok ( ( worker, false ) ) ;
225
+ return Ok ( worker) ;
240
226
}
241
227
242
- if self . busy . len ( ) + self . idle . len ( ) < self . capacity . get ( ) {
243
- // Rather than sending the task to one of the blocking workers,
244
- // let's spawn a new worker
245
-
246
- let worker = self . start_worker ( ) ?;
247
- tracing:: trace!(
248
- worker. id = worker. id( ) ,
249
- "Sending the message to a new worker"
250
- ) ;
251
- return Ok ( ( worker, false ) ) ;
252
- }
253
-
254
- // Oh well, looks like there aren't any more idle workers and we can't
255
- // spin up any new workers, so we'll need to add load to a worker that
256
- // is already blocking.
257
- //
258
- // Note: This shouldn't panic because if there were no idle workers and
259
- // we didn't start a new worker, there should always be at least one
260
- // busy worker because our capacity is non-zero.
261
- let worker = self . busy . pop_front ( ) . unwrap ( ) ;
228
+ // Rather than sending the task to one of the blocking workers,
229
+ // let's spawn a new worker
262
230
231
+ let worker = self . start_worker ( ) ?;
263
232
tracing:: trace!(
264
233
worker. id = worker. id( ) ,
265
- "Sending the message to a busy worker"
234
+ "Sending the message to a new worker"
266
235
) ;
267
-
268
- Ok ( ( worker, true ) )
236
+ Ok ( worker)
269
237
}
270
238
271
239
fn start_worker ( & mut self ) -> Result < WorkerHandle , Error > {
@@ -309,8 +277,8 @@ mod tests {
309
277
async fn spawn_an_async_function ( ) {
310
278
let ( sender, receiver) = oneshot:: channel ( ) ;
311
279
let ( tx, _) = mpsc:: unbounded_channel ( ) ;
312
- let tx = unsafe { Scheduler :: new ( tx, wasmer:: current_thread_id ( ) , NonZeroUsize :: MAX ) } ;
313
- let mut scheduler = SchedulerState :: new ( NonZeroUsize :: MAX , tx) ;
280
+ let tx = unsafe { Scheduler :: new ( tx, wasmer:: current_thread_id ( ) ) } ;
281
+ let mut scheduler = SchedulerState :: new ( tx) ;
314
282
let message = SchedulerMessage :: SpawnAsync ( Box :: new ( move || {
315
283
Box :: pin ( async move {
316
284
let _ = sender. send ( 42 ) ;
0 commit comments