1
1
extern crate alloc;
2
2
use crate :: context:: Context as ExecutorContext ;
3
3
use crate :: executor:: Executor ;
4
+ use crate :: switch;
4
5
use crate :: waker_page:: { WakerPage , WakerPageRef , WAKER_PAGE_SIZE } ;
5
6
use alloc:: sync:: Arc ;
6
7
use alloc:: vec;
7
8
use alloc:: vec:: Vec ;
8
9
use core:: cell:: RefCell ;
9
- use core:: ops:: DerefMut ;
10
10
use lazy_static:: * ;
11
+ use riscv:: register:: sstatus;
11
12
use log:: warn;
12
13
use spin:: Mutex ;
13
14
use unicycle:: pin_slab:: PinSlab ;
@@ -136,8 +137,10 @@ pub struct ExecutorRuntime<F: Future<Output = ()> + Unpin> {
136
137
strong_executor : Arc < Pin < Box < Executor < F > > > > ,
137
138
138
139
// 该executor在执行完一次后就会被drop
139
- weak_executor_vec : Vec < Arc < Pin < Box < Executor < F > > > > > ,
140
+ weak_executor_vec : Vec < Option < Arc < Pin < Box < Executor < F > > > > > > ,
140
141
142
+ // 当前正在执行的executor
143
+ current_executor : Option < Arc < Pin < Box < Executor < F > > > > > ,
141
144
// runtime context
142
145
context : ExecutorContext ,
143
146
}
@@ -150,6 +153,7 @@ impl<F: Future<Output = ()> + Unpin> ExecutorRuntime<F> {
150
153
priority_inner : priority_inner,
151
154
strong_executor : Arc :: new ( Executor :: new ( priority_inner_cloned) ) ,
152
155
weak_executor_vec : vec ! [ ] ,
156
+ current_executor : None ,
153
157
context : ExecutorContext :: default ( ) ,
154
158
} ;
155
159
e
@@ -165,11 +169,14 @@ impl<F: Future<Output = ()> + Unpin> ExecutorRuntime<F> {
165
169
}
166
170
167
171
fn add_weak_executor ( & mut self , weak_executor : Arc < Pin < Box < Executor < F > > > > ) {
168
- self . weak_executor_vec . push ( weak_executor) ;
172
+ self . weak_executor_vec . push ( Some ( weak_executor) ) ;
169
173
}
170
174
171
175
fn downgrade_strong_executor ( & mut self ) {
172
- let old = self . strong_executor . clone ( ) ;
176
+ let mut old = self . strong_executor . clone ( ) ;
177
+ unsafe {
178
+ Arc :: get_mut_unchecked ( & mut old) . mark_weak ( ) ;
179
+ }
173
180
self . add_weak_executor ( old) ;
174
181
self . strong_executor = Arc :: new ( Executor :: new ( self . priority_inner . clone ( ) ) ) ;
175
182
}
@@ -181,24 +188,9 @@ impl<F: Future<Output = ()> + Unpin> Drop for ExecutorRuntime<F> {
181
188
}
182
189
}
183
190
184
- // 运行executor.run()
185
- #[ no_mangle]
186
- pub ( crate ) fn run_executor ( executor_addr : usize ) {
187
- log:: warn!( "executor addr {:x}" , executor_addr) ;
188
- unsafe {
189
- let mut p = Box :: from_raw ( executor_addr as * mut Executor < Task > ) ;
190
- p. run ( ) ;
191
- }
192
- }
193
-
194
191
unsafe impl Send for ExecutorRuntime < Task > { }
195
192
unsafe impl Sync for ExecutorRuntime < Task > { }
196
193
197
- // lazy_static! {
198
- // pub static ref GLOBAL_RUNTIME: Mutex<RefCell<ExecutorRuntime<Task>>> =
199
- // Mutex::new(RefCell::new(ExecutorRuntime::new()));
200
- // }
201
-
202
194
lazy_static ! {
203
195
pub static ref GLOBAL_RUNTIME : Mutex <ExecutorRuntime <Task >> =
204
196
Mutex :: new( ExecutorRuntime :: new( ) ) ;
@@ -209,24 +201,63 @@ pub fn spawn(future: impl Future<Output = ()> + Send + 'static) {
209
201
return priority_spawn ( future, DEFAULT_PRIORITY ) ;
210
202
}
211
203
204
+ //
212
205
pub fn run ( ) {
213
206
log:: warn!( "GLOBAL_RUNTIME.run()" ) ;
214
207
loop {
215
- let runtime = GLOBAL_RUNTIME . lock ( ) ;
208
+ let mut runtime = GLOBAL_RUNTIME . lock ( ) ;
216
209
let cx_ref = & runtime. context ;
217
- let old_ctx = cx_ref as * const ExecutorContext as usize ;
218
- let new_ctx = & ( runtime. strong_executor . context ) as * const ExecutorContext as usize ;
210
+ let runtime_cx = cx_ref as * const ExecutorContext as usize ;
211
+ let executor_cx = & ( runtime. strong_executor . context ) as * const ExecutorContext as usize ;
219
212
// 释放保护global_runtime的锁
213
+ runtime. current_executor = Some ( runtime. strong_executor . clone ( ) ) ;
220
214
drop ( runtime) ;
221
215
unsafe {
222
- crate :: switch ( old_ctx, new_ctx) ;
216
+ log:: warn!( "run strong executor" ) ;
217
+ crate :: switch ( runtime_cx, executor_cx) ;
223
218
// 该函数返回说明当前strong_executor执行的future超时了,
224
219
// 需要重新创建一个executor执行后续的future, 并且将
225
220
// 新的executor作为strong_executor,旧的executor添
226
221
// 加到weak_exector中。
227
222
}
223
+ log:: warn!( "switch return" ) ;
228
224
let mut runtime = GLOBAL_RUNTIME . lock ( ) ;
229
- runtime. downgrade_strong_executor ( ) ;
225
+ // 只有strong_executor主动yield时, 才会执行运行weak_executor;
226
+
227
+ if runtime. strong_executor . is_running_future ( ) {
228
+ runtime. downgrade_strong_executor ( ) ;
229
+ log:: warn!( "continued" ) ;
230
+ continue ;
231
+ }
232
+
233
+ // 遍历全部的weak_executor
234
+ let weak_executor_num = runtime. weak_executor_vec . len ( ) ;
235
+ log:: warn!( "run weak executor size={}" , weak_executor_num) ;
236
+ for i in 0 ..weak_executor_num {
237
+ if runtime. weak_executor_vec [ i] . is_none ( ) {
238
+ continue ;
239
+ }
240
+ let weak_executor = runtime. weak_executor_vec [ i] . as_ref ( ) . unwrap ( ) ;
241
+ if weak_executor. killed ( ) {
242
+ // TODO: 回收资源
243
+ continue ;
244
+ }
245
+ let executor_ctx = & weak_executor. context as * const ExecutorContext as usize ;
246
+
247
+ runtime. current_executor = Some ( weak_executor. clone ( ) ) ;
248
+ drop ( runtime) ;
249
+ unsafe {
250
+ sstatus:: set_sie ( ) ;
251
+ log:: warn!( "switch weak executor" ) ;
252
+ switch ( runtime_cx, executor_ctx) ;
253
+ log:: warn!( "switch weak executor return" ) ;
254
+ sstatus:: clear_sie ( ) ;
255
+ }
256
+ log:: warn!( "global locking" ) ;
257
+ runtime = GLOBAL_RUNTIME . lock ( ) ;
258
+ log:: warn!( "global locking finish" ) ;
259
+ }
260
+ log:: warn!( "run weak executor finish" ) ;
230
261
}
231
262
}
232
263
@@ -246,19 +277,48 @@ pub fn priority_spawn(future: impl Future<Output = ()> + Send + 'static, priorit
246
277
// 切换到runtime的context
247
278
pub fn handle_timeout ( ) {
248
279
let runtime = GLOBAL_RUNTIME . lock ( ) ;
249
- if !runtime. strong_executor . is_running_future ( ) {
280
+ if !runtime. current_executor . as_ref ( ) . unwrap ( ) . is_running_future ( ) {
250
281
return ;
251
282
}
252
283
let cx_ref = & runtime. context ;
253
- let old_ctx = & ( runtime. strong_executor . context ) as * const ExecutorContext as usize ;
254
- let new_ctx = cx_ref as * const ExecutorContext as usize ;
284
+ let executor_cx = & ( runtime. strong_executor . context ) as * const ExecutorContext as usize ;
285
+ let runtime_cx = cx_ref as * const ExecutorContext as usize ;
255
286
drop ( runtime) ;
256
- log:: warn!( "switch to executor runtime" ) ;
257
- unsafe { crate :: switch ( old_ctx , new_ctx ) } ;
287
+ log:: warn!( "switching to executor runtime" ) ;
288
+ unsafe { crate :: switch ( executor_cx , runtime_cx ) } ;
258
289
}
259
290
260
291
pub fn test_borrow ( ) {
261
292
let runtime = GLOBAL_RUNTIME . lock ( ) ;
262
293
let inner = runtime. priority_inner . get_mut_inner ( DEFAULT_PRIORITY ) ;
263
- log:: warn!( "borrow successfully {:?}" , inner. deref( ) as * const _ as usize ) ;
294
+ log:: warn!(
295
+ "borrow successfully {:?}" ,
296
+ inner. deref( ) as * const _ as usize
297
+ ) ;
298
+ }
299
+
300
+ // 运行executor.run()
301
+ #[ no_mangle]
302
+ pub ( crate ) fn run_executor ( executor_addr : usize ) {
303
+ log:: warn!( "executor addr {:x}" , executor_addr) ;
304
+ unsafe {
305
+ let mut p = Box :: from_raw ( executor_addr as * mut Executor < Task > ) ;
306
+ p. run ( ) ;
307
+ }
308
+ let runtime = GLOBAL_RUNTIME . lock ( ) ;
309
+ let cx_ref = & runtime. context ;
310
+ let executor_cx = & ( runtime. strong_executor . context ) as * const ExecutorContext as usize ;
311
+ let runtime_cx = cx_ref as * const ExecutorContext as usize ;
312
+ drop ( runtime) ;
313
+ unsafe { crate :: switch ( executor_cx, runtime_cx) }
314
+ unreachable ! ( ) ;
315
+ }
316
+
317
+ pub ( crate ) fn yeild ( ) {
318
+ let runtime = GLOBAL_RUNTIME . lock ( ) ;
319
+ let cx_ref = & runtime. context ;
320
+ let executor_cx = & ( runtime. strong_executor . context ) as * const ExecutorContext as usize ;
321
+ let runtime_cx = cx_ref as * const ExecutorContext as usize ;
322
+ drop ( runtime) ;
323
+ unsafe { crate :: switch ( executor_cx, runtime_cx) }
264
324
}
0 commit comments