1
1
use anyhow:: Result ;
2
+ use async_mutex:: { Mutex as AsyncMutex , MutexGuardArc as AsyncMutexGuard } ;
2
3
use futures_core:: ready;
3
4
use std:: {
4
5
future:: Future ,
5
6
io:: Write ,
6
7
mem:: replace,
7
8
path:: Path ,
8
9
pin:: Pin ,
9
- sync:: { Arc , Mutex } ,
10
+ sync:: Arc ,
10
11
task:: { Context , Poll } ,
11
12
time:: { Duration , Instant } ,
12
13
} ;
@@ -60,7 +61,7 @@ impl Target for NucleoF401re {
60
61
}
61
62
62
63
struct ProbeRsDebugProbe {
63
- session : Arc < Mutex < probe_rs:: Session > > ,
64
+ session : Arc < AsyncMutex < probe_rs:: Session > > ,
64
65
}
65
66
66
67
#[ derive( thiserror:: Error , Debug ) ]
@@ -86,7 +87,7 @@ impl ProbeRsDebugProbe {
86
87
) -> anyhow:: Result < Self > {
87
88
let probe = probe_rs:: Probe :: open ( probe_sel) . map_err ( OpenError :: OpenProbe ) ?;
88
89
89
- let session = Arc :: new ( Mutex :: new (
90
+ let session = Arc :: new ( AsyncMutex :: new (
90
91
probe. attach ( target_sel) . map_err ( OpenError :: Attach ) ?,
91
92
) ) ;
92
93
@@ -100,28 +101,29 @@ impl DebugProbe for ProbeRsDebugProbe {
100
101
exe : & Path ,
101
102
) -> Pin < Box < dyn Future < Output = Result < DynAsyncRead < ' _ > > > + ' _ > > {
102
103
let exe = exe. to_owned ( ) ;
103
- let session = Arc :: clone ( & self . session ) ;
104
104
105
105
Box :: pin ( async move {
106
+ let mut session = self . session . lock_arc ( ) . await ;
107
+
106
108
// Flash the executable
107
109
log:: debug!( "Flashing '{0}'" , exe. display( ) ) ;
108
110
109
- let session2 = Arc :: clone ( & session) ;
110
111
let exe2 = exe. clone ( ) ;
111
- spawn_blocking ( move || {
112
- let mut session_lock = session2. lock ( ) . unwrap ( ) ;
112
+ let mut session = spawn_blocking ( move || {
113
113
probe_rs:: flashing:: download_file (
114
- & mut * session_lock ,
114
+ & mut * session ,
115
115
& exe2,
116
116
probe_rs:: flashing:: Format :: Elf ,
117
- )
117
+ ) ?;
118
+ Ok ( session)
118
119
} )
119
120
. await
120
121
. unwrap ( )
121
122
. map_err ( RunError :: Flash ) ?;
122
123
123
124
// Reset the core
124
- ( session. lock ( ) . unwrap ( ) . core ( 0 ) )
125
+ session
126
+ . core ( 0 )
125
127
. map_err ( RunError :: Reset ) ?
126
128
. reset ( )
127
129
. map_err ( RunError :: Reset ) ?;
@@ -152,7 +154,7 @@ pub struct RttOptions {
152
154
}
153
155
154
156
pub async fn attach_rtt (
155
- session : Arc < Mutex < probe_rs:: Session > > ,
157
+ mut session : AsyncMutexGuard < probe_rs:: Session > ,
156
158
exe : & Path ,
157
159
options : RttOptions ,
158
160
) -> Result < DynAsyncRead < ' static > , AttachRttError > {
@@ -185,32 +187,32 @@ pub async fn attach_rtt(
185
187
// Attach to RTT
186
188
let start = Instant :: now ( ) ;
187
189
let rtt = loop {
188
- let session = session. clone ( ) ;
189
190
let halt_on_access = options. halt_on_access ;
190
191
let rtt_scan_region = rtt_scan_region. clone ( ) ;
191
192
192
- let result = spawn_blocking ( move || {
193
- let mut session = session. lock ( ) . unwrap ( ) ;
193
+ let ( result, session2) = spawn_blocking ( move || {
194
194
let memory_map = session. target ( ) . memory_map . clone ( ) ;
195
- let mut core = session. core ( 0 ) . map_err ( AttachRttError :: HaltCore ) ?;
196
- let halt_guard;
197
- let core = if halt_on_access {
198
- halt_guard = CoreHaltGuard :: new ( & mut core) . map_err ( AttachRttError :: HaltCore ) ?;
199
- & mut * halt_guard. core
200
- } else {
201
- & mut core
202
- } ;
195
+ let result = {
196
+ let mut core = session. core ( 0 ) . map_err ( AttachRttError :: HaltCore ) ?;
197
+ let halt_guard;
198
+ let core = if halt_on_access {
199
+ halt_guard = CoreHaltGuard :: new ( & mut core) . map_err ( AttachRttError :: HaltCore ) ?;
200
+ & mut * halt_guard. core
201
+ } else {
202
+ & mut core
203
+ } ;
203
204
204
- let result = match probe_rs_rtt:: Rtt :: attach_region ( core, & memory_map, & rtt_scan_region)
205
- {
206
- Ok ( rtt ) => Some ( rtt ) ,
207
- Err ( probe_rs_rtt :: Error :: ControlBlockNotFound ) => None ,
208
- Err ( e ) => return Err ( AttachRttError :: AttachRtt ( e ) ) ,
205
+ match probe_rs_rtt:: Rtt :: attach_region ( core, & memory_map, & rtt_scan_region) {
206
+ Ok ( rtt ) => Some ( rtt ) ,
207
+ Err ( probe_rs_rtt :: Error :: ControlBlockNotFound ) => None ,
208
+ Err ( e ) => return Err ( AttachRttError :: AttachRtt ( e ) ) ,
209
+ }
209
210
} ;
210
- Ok ( result)
211
+ Ok ( ( result, session ) )
211
212
} )
212
213
. await
213
214
. unwrap ( ) ?;
215
+ session = session2;
214
216
215
217
if let Some ( rtt) = result {
216
218
break rtt;
@@ -271,7 +273,6 @@ impl Drop for CoreHaltGuard<'_, '_> {
271
273
}
272
274
273
275
struct ReadRtt {
274
- session : Arc < Mutex < probe_rs:: Session > > ,
275
276
options : RttOptions ,
276
277
st : ReadRttSt ,
277
278
}
@@ -281,19 +282,28 @@ enum ReadRttSt {
281
282
/// `<ReadRtt as AsyncRead>`.
282
283
Idle {
283
284
buf : ReadRttBuf ,
285
+ session : AsyncMutexGuard < probe_rs:: Session > ,
284
286
rtt : Box < probe_rs_rtt:: Rtt > ,
285
287
pos : usize ,
286
288
len : usize ,
287
289
} ,
288
290
289
291
/// `ReadRtt` is currently fetching new data from RTT channels.
290
292
Read {
291
- join_handle : JoinHandle < tokio:: io:: Result < ( ReadRttBuf , usize , Box < probe_rs_rtt:: Rtt > ) > > ,
293
+ join_handle : JoinHandle <
294
+ tokio:: io:: Result < (
295
+ ReadRttBuf ,
296
+ AsyncMutexGuard < probe_rs:: Session > ,
297
+ usize ,
298
+ Box < probe_rs_rtt:: Rtt > ,
299
+ ) > ,
300
+ > ,
292
301
} ,
293
302
294
303
/// `ReadRtt` is waiting for some time before trying reading again.
295
304
PollDelay {
296
305
buf : ReadRttBuf ,
306
+ session : AsyncMutexGuard < probe_rs:: Session > ,
297
307
rtt : Box < probe_rs_rtt:: Rtt > ,
298
308
delay : Pin < Box < Sleep > > ,
299
309
} ,
@@ -305,15 +315,15 @@ type ReadRttBuf = Box<[u8; 1024]>;
305
315
306
316
impl ReadRtt {
307
317
fn new (
308
- session : Arc < Mutex < probe_rs:: Session > > ,
318
+ session : AsyncMutexGuard < probe_rs:: Session > ,
309
319
rtt : probe_rs_rtt:: Rtt ,
310
320
options : RttOptions ,
311
321
) -> Self {
312
322
Self {
313
- session,
314
323
options,
315
324
st : ReadRttSt :: Idle {
316
325
buf : Box :: new ( [ 0u8 ; 1024 ] ) ,
326
+ session,
317
327
rtt : Box :: new ( rtt) ,
318
328
pos : 0 ,
319
329
len : 0 ,
@@ -346,22 +356,28 @@ impl AsyncBufRead for ReadRtt {
346
356
ReadRttSt :: Idle { pos, len, .. } => {
347
357
if * pos == * len {
348
358
// Buffer is empty; start reading RTT channels
349
- let ( mut buf, mut rtt) = match replace ( & mut this. st , ReadRttSt :: Invalid ) {
350
- ReadRttSt :: Idle { buf, rtt, .. } => ( buf, rtt) ,
351
- _ => unreachable ! ( ) ,
352
- } ;
359
+ let ( mut buf, mut rtt, mut session) =
360
+ match replace ( & mut this. st , ReadRttSt :: Invalid ) {
361
+ ReadRttSt :: Idle {
362
+ buf, rtt, session, ..
363
+ } => ( buf, rtt, session) ,
364
+ _ => unreachable ! ( ) ,
365
+ } ;
353
366
354
367
let halt_on_access = this. options . halt_on_access ;
355
- let session = this. session . clone ( ) ;
356
368
357
369
// Reading RTT is a blocking operation, so do it in a
358
370
// separate thread
359
371
let join_handle = spawn_blocking ( move || {
360
- let num_read_bytes =
361
- Self :: read_inner ( session, & mut rtt, & mut * buf, halt_on_access) ?;
372
+ let num_read_bytes = Self :: read_inner (
373
+ & mut session,
374
+ & mut rtt,
375
+ & mut * buf,
376
+ halt_on_access,
377
+ ) ?;
362
378
363
379
// Send the buffer back to the `ReadRtt`
364
- Ok ( ( buf, num_read_bytes, rtt) )
380
+ Ok ( ( buf, session , num_read_bytes, rtt) )
365
381
} ) ;
366
382
367
383
this. st = ReadRttSt :: Read { join_handle } ;
@@ -379,7 +395,7 @@ impl AsyncBufRead for ReadRtt {
379
395
}
380
396
381
397
ReadRttSt :: Read { join_handle } => {
382
- let ( buf, num_read_bytes, rtt) =
398
+ let ( buf, session , num_read_bytes, rtt) =
383
399
match ready ! ( Pin :: new( join_handle) . poll( cx) ) . unwrap ( ) {
384
400
Ok ( x) => x,
385
401
Err ( e) => return Poll :: Ready ( Err ( e) ) ,
@@ -389,12 +405,14 @@ impl AsyncBufRead for ReadRtt {
389
405
// If no bytes were read, wait for a while and try again
390
406
ReadRttSt :: PollDelay {
391
407
buf,
408
+ session,
392
409
rtt,
393
410
delay : Box :: pin ( sleep ( POLL_INTERVAL ) ) ,
394
411
}
395
412
} else {
396
413
ReadRttSt :: Idle {
397
414
buf,
415
+ session,
398
416
rtt,
399
417
pos : 0 ,
400
418
len : num_read_bytes,
@@ -405,13 +423,16 @@ impl AsyncBufRead for ReadRtt {
405
423
ReadRttSt :: PollDelay { delay, .. } => {
406
424
ready ! ( delay. as_mut( ) . poll( cx) ) ;
407
425
408
- let ( buf, rtt) = match replace ( & mut this. st , ReadRttSt :: Invalid ) {
409
- ReadRttSt :: PollDelay { buf, rtt, .. } => ( buf, rtt) ,
426
+ let ( buf, rtt, session) = match replace ( & mut this. st , ReadRttSt :: Invalid ) {
427
+ ReadRttSt :: PollDelay {
428
+ buf, rtt, session, ..
429
+ } => ( buf, rtt, session) ,
410
430
_ => unreachable ! ( ) ,
411
431
} ;
412
432
413
433
this. st = ReadRttSt :: Idle {
414
434
buf,
435
+ session,
415
436
rtt,
416
437
pos : 0 ,
417
438
len : 0 ,
@@ -436,15 +457,11 @@ impl AsyncBufRead for ReadRtt {
436
457
437
458
impl ReadRtt {
438
459
fn read_inner (
439
- session : Arc < Mutex < probe_rs:: Session > > ,
460
+ session : & mut probe_rs:: Session ,
440
461
rtt : & mut probe_rs_rtt:: Rtt ,
441
462
buf : & mut [ u8 ] ,
442
463
halt_on_access : bool ,
443
464
) -> tokio:: io:: Result < usize > {
444
- // FIXME: Hold the lock in `ReadRtt`; it's pointless to be able to have
445
- // two instances of `ReadRtt` pointing to the same `Session` and
446
- // performing interleaved reads
447
- let mut session = session. lock ( ) . unwrap ( ) ;
448
465
let mut core = session
449
466
. core ( 0 )
450
467
. map_err ( |e| tokio:: io:: Error :: new ( tokio:: io:: ErrorKind :: Other , e) ) ?;
0 commit comments