MCPcopy Index your code
hub / github.com/RustPython/RustPython / park_detached_threads

Method park_detached_threads

crates/vm/src/vm/mod.rs:257–318  ·  view source on GitHub ↗

Try to CAS detached threads directly to SUSPENDED and check whether stop countdown reached zero after parking detached threads.

(&self, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

255 /// Try to CAS detached threads directly to SUSPENDED and check whether
256 /// stop countdown reached zero after parking detached threads.
257 fn park_detached_threads(&self, vm: &VirtualMachine) -> bool {
258 use thread::{THREAD_ATTACHED, THREAD_DETACHED, THREAD_SUSPENDED};
259 let requester = self.requester.load(Ordering::Relaxed);
260 let registry = vm.state.thread_frames.lock();
261 let mut attached_seen = 0u64;
262 let mut forced_parks = 0u64;
263 for (&id, slot) in registry.iter() {
264 if id == requester {
265 continue;
266 }
267 let state = slot.state.load(Ordering::Relaxed);
268 if state == THREAD_DETACHED {
269 // CAS DETACHED → SUSPENDED (park without thread cooperation)
270 match slot.state.compare_exchange(
271 THREAD_DETACHED,
272 THREAD_SUSPENDED,
273 Ordering::AcqRel,
274 Ordering::Relaxed,
275 ) {
276 Ok(_) => {
277 slot.stop_requested.store(false, Ordering::Release);
278 forced_parks = forced_parks.saturating_add(1);
279 }
280 Err(THREAD_ATTACHED) => {
281 // Set per-thread stop bit (_PY_EVAL_PLEASE_STOP_BIT).
282 slot.stop_requested.store(true, Ordering::Release);
283 // Raced with a thread re-attaching; it will self-suspend.
284 attached_seen = attached_seen.saturating_add(1);
285 }
286 Err(THREAD_DETACHED) => {
287 // Extremely unlikely race; next poll will handle it.
288 }
289 Err(THREAD_SUSPENDED) => {
290 slot.stop_requested.store(false, Ordering::Release);
291 // Another path parked it first.
292 }
293 Err(other) => {
294 debug_assert!(
295 false,
296 "unexpected thread state in park_detached_threads: {other}"
297 );
298 }
299 }
300 } else if state == THREAD_ATTACHED {
301 // Set per-thread stop bit (_PY_EVAL_PLEASE_STOP_BIT).
302 slot.stop_requested.store(true, Ordering::Release);
303 // Thread is in bytecode — it will see `requested` and self-suspend
304 attached_seen = attached_seen.saturating_add(1);
305 }
306 // THREAD_SUSPENDED → already parked
307 }
308 if attached_seen != 0 {
309 self.stats_attached_seen
310 .fetch_add(attached_seen, Ordering::Relaxed);
311 }
312 if forced_parks != 0 {
313 self.decrement_thread_countdown(forced_parks);
314 self.stats_forced_parks

Callers 1

stop_the_worldMethod · 0.80

Calls 5

loadMethod · 0.45
lockMethod · 0.45
iterMethod · 0.45
storeMethod · 0.45

Tested by

no test coverage detected