@@ -2406,7 +2406,7 @@ func mspinning() {
2406
2406
// Must not have write barriers because this may be called without a P.
2407
2407
//
2408
2408
//go:nowritebarrierrec
2409
- func startm (pp * p , spinning bool ) {
2409
+ func startm (pp * p , spinning bool , lockheld bool ) {
2410
2410
// Disable preemption.
2411
2411
//
2412
2412
// Every owned P must have an owner that will eventually stop it in the
@@ -2424,9 +2424,12 @@ func startm(pp *p, spinning bool) {
2424
2424
// startm. Callers passing a nil P may be preemptible, so we must
2425
2425
// disable preemption before acquiring a P from pidleget below.
2426
2426
mp := acquirem ()
2427
- pushEventTrace ("startm acquiring sched lock" )
2428
- lock (& sched .lock )
2429
- pushEventTrace ("startm acquired sched lock" )
2427
+
2428
+ if ! lockheld {
2429
+ pushEventTrace ("startm acquiring sched lock" )
2430
+ lock (& sched .lock )
2431
+ pushEventTrace ("startm acquired sched lock" )
2432
+ }
2430
2433
if pp == nil {
2431
2434
if spinning {
2432
2435
// TODO(prattmic): All remaining calls to this function
@@ -2436,9 +2439,11 @@ func startm(pp *p, spinning bool) {
2436
2439
}
2437
2440
pp , _ = pidleget (0 )
2438
2441
if pp == nil {
2439
- pushEventTrace ("mcommoninit releasing sched lock (1)" )
2440
- unlock (& sched .lock )
2441
- pushEventTrace ("mcommoninit released sched lock (1)" )
2442
+ if ! lockheld {
2443
+ pushEventTrace ("mcommoninit releasing sched lock (1)" )
2444
+ unlock (& sched .lock )
2445
+ pushEventTrace ("mcommoninit released sched lock (1)" )
2446
+ }
2442
2447
releasem (mp )
2443
2448
return
2444
2449
}
@@ -2458,9 +2463,11 @@ func startm(pp *p, spinning bool) {
2458
2463
// new M will eventually run the scheduler to execute any
2459
2464
// queued G's.
2460
2465
id := mReserveID ()
2461
- pushEventTrace ("mcommoninit releasing sched lock (2)" )
2462
- unlock (& sched .lock )
2463
- pushEventTrace ("mcommoninit released sched lock (2)" )
2466
+ if ! lockheld {
2467
+ pushEventTrace ("mcommoninit releasing sched lock (2)" )
2468
+ unlock (& sched .lock )
2469
+ pushEventTrace ("mcommoninit released sched lock (2)" )
2470
+ }
2464
2471
2465
2472
var fn func ()
2466
2473
if spinning {
@@ -2473,9 +2480,11 @@ func startm(pp *p, spinning bool) {
2473
2480
releasem (mp )
2474
2481
return
2475
2482
}
2476
- pushEventTrace ("mcommoninit releasing sched lock (3)" )
2477
- unlock (& sched .lock )
2478
- pushEventTrace ("mcommoninit released sched lock (3)" )
2483
+ if ! lockheld {
2484
+ pushEventTrace ("mcommoninit releasing sched lock (3)" )
2485
+ unlock (& sched .lock )
2486
+ pushEventTrace ("mcommoninit released sched lock (3)" )
2487
+ }
2479
2488
if nmp .spinning {
2480
2489
throw ("startm: m is spinning" )
2481
2490
}
@@ -2504,24 +2513,24 @@ func handoffp(pp *p) {
2504
2513
2505
2514
// if it has local work, start it straight away
2506
2515
if ! runqempty (pp ) || sched .runqsize != 0 {
2507
- startm (pp , false )
2516
+ startm (pp , false , false )
2508
2517
return
2509
2518
}
2510
2519
// if there's trace work to do, start it straight away
2511
2520
if (trace .enabled || trace .shutdown ) && traceReaderAvailable () != nil {
2512
- startm (pp , false )
2521
+ startm (pp , false , false )
2513
2522
return
2514
2523
}
2515
2524
// if it has GC work, start it straight away
2516
2525
if gcBlackenEnabled != 0 && gcMarkWorkAvailable (pp ) {
2517
- startm (pp , false )
2526
+ startm (pp , false , false )
2518
2527
return
2519
2528
}
2520
2529
// no local work, check that there are no spinning/idle M's,
2521
2530
// otherwise our help is not required
2522
2531
if sched .nmspinning .Load ()+ sched .npidle .Load () == 0 && sched .nmspinning .CompareAndSwap (0 , 1 ) { // TODO: fast atomic
2523
2532
sched .needspinning .Store (0 )
2524
- startm (pp , true )
2533
+ startm (pp , true , false )
2525
2534
return
2526
2535
}
2527
2536
pushEventTrace ("handoffp acquiring sched lock" )
@@ -2549,7 +2558,7 @@ func handoffp(pp *p) {
2549
2558
pushEventTrace ("mcommoninit releasing sched lock (2)" )
2550
2559
unlock (& sched .lock )
2551
2560
pushEventTrace ("mcommoninit released sched lock (2)" )
2552
- startm (pp , false )
2561
+ startm (pp , false , false )
2553
2562
return
2554
2563
}
2555
2564
// If this is the last running P and nobody is polling network,
@@ -2558,7 +2567,7 @@ func handoffp(pp *p) {
2558
2567
pushEventTrace ("mcommoninit releasing sched lock (3)" )
2559
2568
unlock (& sched .lock )
2560
2569
pushEventTrace ("mcommoninit released sched lock (3)" )
2561
- startm (pp , false )
2570
+ startm (pp , false , false )
2562
2571
return
2563
2572
}
2564
2573
@@ -2615,7 +2624,7 @@ func wakep() {
2615
2624
unlock (& sched .lock )
2616
2625
pushEventTrace ("wakep released sched lock (2)" )
2617
2626
2618
- startm (pp , true )
2627
+ startm (pp , true , false )
2619
2628
2620
2629
releasem (mp )
2621
2630
}
@@ -2957,6 +2966,7 @@ top:
2957
2966
throw ("findrunnable: wrong p" )
2958
2967
}
2959
2968
now = pidleput (pp , now )
2969
+ sched .crashPending .Store (true )
2960
2970
pushEventTrace ("findRunnable releasing sched lock (6)" )
2961
2971
unlock (& sched .lock )
2962
2972
pushEventTrace ("findRunnable released sched lock (6)" )
@@ -3076,13 +3086,16 @@ top:
3076
3086
stopm ()
3077
3087
goto top
3078
3088
}
3089
+
3079
3090
pushEventTrace ("findRunnable acquiring sched lock (4)" )
3080
3091
lock (& sched .lock )
3081
3092
pushEventTrace ("findRunnable acquired sched lock (4)" )
3082
3093
pp , _ := pidleget (now )
3083
3094
pushEventTrace ("findRunnable releasing sched lock (7)" )
3084
3095
unlock (& sched .lock )
3085
3096
pushEventTrace ("findRunnable released sched lock (7)" )
3097
+ sched .crashPending .Store (false )
3098
+
3086
3099
if pp == nil {
3087
3100
injectglist (& list )
3088
3101
} else {
@@ -3416,10 +3429,17 @@ func injectglist(glist *gList) {
3416
3429
break
3417
3430
}
3418
3431
3432
+ if sched .crashPending .Load () {
3433
+ pushEventTrace ("[checkdead] should have crashed" )
3434
+ sched .crashPending .Store (false )
3435
+ }
3436
+
3437
+ startm (pp , false , true )
3438
+
3419
3439
pushEventTrace ("injectglist releasing sched lock (2)" )
3420
3440
unlock (& sched .lock )
3421
3441
pushEventTrace ("injectglist released sched lock (2)" )
3422
- startm ( pp , false )
3442
+
3423
3443
releasem (mp )
3424
3444
}
3425
3445
}
@@ -5647,7 +5667,7 @@ func sysmon() {
5647
5667
// See issue 42515 and
5648
5668
// https://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=50094.
5649
5669
if next := timeSleepUntil (); next < now {
5650
- startm (nil , false )
5670
+ startm (nil , false , false )
5651
5671
}
5652
5672
}
5653
5673
if scavenger .sysmonWake .Load () != 0 {
@@ -5932,7 +5952,7 @@ func schedEnableUser(enable bool) {
5932
5952
unlock (& sched .lock )
5933
5953
pushEventTrace ("schedEnableUser released sched lock (2)" )
5934
5954
for ; n != 0 && sched .npidle .Load () != 0 ; n -- {
5935
- startm (nil , false )
5955
+ startm (nil , false , false )
5936
5956
}
5937
5957
} else {
5938
5958
pushEventTrace ("schedEnableUser releasing sched lock (3)" )
0 commit comments