@@ -267,12 +267,12 @@ void jl_safepoint_wait_thread_resume(void)
267
267
uv_cond_broadcast (& safepoint_cond_begin );
268
268
uv_mutex_unlock (& safepoint_lock );
269
269
uv_mutex_lock (& ct -> ptls -> sleep_lock );
270
+ while (jl_atomic_load_relaxed (& ct -> ptls -> suspend_count ))
271
+ uv_cond_wait (& ct -> ptls -> wake_signal , & ct -> ptls -> sleep_lock );
270
272
}
271
- while (jl_atomic_load_relaxed (& ct -> ptls -> suspend_count ))
272
- uv_cond_wait (& ct -> ptls -> wake_signal , & ct -> ptls -> sleep_lock );
273
- // must while still holding the mutex_unlock, so we know other threads in
274
- // jl_safepoint_suspend_thread will observe this thread in the correct GC
275
- // state, and not still stuck in JL_GC_STATE_WAITING
273
+ // must exit gc while still holding the mutex_unlock, so we know other
274
+ // threads in jl_safepoint_suspend_thread will observe this thread in the
275
+ // correct GC state, and not still stuck in JL_GC_STATE_WAITING
276
276
jl_atomic_store_release (& ct -> ptls -> gc_state , state );
277
277
uv_mutex_unlock (& ct -> ptls -> sleep_lock );
278
278
}
@@ -290,12 +290,20 @@ int jl_safepoint_suspend_thread(int tid, int waitstate)
290
290
if (0 > tid || tid >= jl_atomic_load_acquire (& jl_n_threads ))
291
291
return 0 ;
292
292
jl_ptls_t ptls2 = jl_atomic_load_relaxed (& jl_all_tls_states )[tid ];
293
+ jl_task_t * ct2 = ptls2 ? jl_atomic_load_relaxed (& ptls2 -> current_task ) : NULL ;
294
+ if (ct2 == NULL ) {
295
+ // this thread is not alive yet or already dead
296
+ return 0 ;
297
+ }
298
+ uv_mutex_lock (& safepoint_lock );
293
299
uv_mutex_lock (& ptls2 -> sleep_lock );
294
300
int16_t suspend_count = jl_atomic_load_relaxed (& ptls2 -> suspend_count ) + 1 ;
295
301
jl_atomic_store_relaxed (& ptls2 -> suspend_count , suspend_count );
296
302
if (suspend_count == 1 ) { // first to suspend
297
303
jl_safepoint_enable (3 );
298
304
jl_atomic_store_relaxed (& ptls2 -> safepoint , (size_t * )(jl_safepoint_pages + jl_page_size * 3 + sizeof (void * )));
305
+ if (jl_atomic_load (& _threadedregion ) != 0 || tid == jl_atomic_load_relaxed (& io_loop_tid ))
306
+ jl_wake_libuv (); // our integration with libuv right now doesn't handle except by waking it
299
307
}
300
308
uv_mutex_unlock (& ptls2 -> sleep_lock );
301
309
if (waitstate ) {
@@ -305,17 +313,20 @@ int jl_safepoint_suspend_thread(int tid, int waitstate)
305
313
// not, so assume it is running GC and wait for GC to finish first.
306
314
// It will be unable to reenter helping with GC because we have
307
315
// changed its safepoint page.
316
+ uv_mutex_unlock (& safepoint_lock );
308
317
jl_set_gc_and_wait ();
318
+ uv_mutex_lock (& safepoint_lock );
309
319
}
310
320
while (jl_atomic_load_acquire (& ptls2 -> suspend_count ) != 0 ) {
311
321
int8_t state2 = jl_atomic_load_acquire (& ptls2 -> gc_state );
312
322
if (waitstate <= 2 && state2 != JL_GC_STATE_UNSAFE )
313
323
break ;
314
324
if (waitstate == 3 && state2 == JL_GC_STATE_WAITING )
315
325
break ;
316
- jl_cpu_pause (); // yield (wait for safepoint_cond_begin, for example)?
326
+ uv_cond_wait ( & safepoint_cond_begin , & safepoint_lock );
317
327
}
318
328
}
329
+ uv_mutex_unlock (& safepoint_lock );
319
330
return suspend_count ;
320
331
}
321
332
@@ -326,6 +337,11 @@ int jl_safepoint_resume_thread(int tid) JL_NOTSAFEPOINT
326
337
if (0 > tid || tid >= jl_atomic_load_acquire (& jl_n_threads ))
327
338
return 0 ;
328
339
jl_ptls_t ptls2 = jl_atomic_load_relaxed (& jl_all_tls_states )[tid ];
340
+ jl_task_t * ct2 = ptls2 ? jl_atomic_load_relaxed (& ptls2 -> current_task ) : NULL ;
341
+ if (ct2 == NULL ) {
342
+ // this thread is not alive yet or already dead
343
+ return 0 ;
344
+ }
329
345
uv_mutex_lock (& safepoint_lock );
330
346
uv_mutex_lock (& ptls2 -> sleep_lock );
331
347
int16_t suspend_count = jl_atomic_load_relaxed (& ptls2 -> suspend_count );
@@ -338,6 +354,7 @@ int jl_safepoint_resume_thread(int tid) JL_NOTSAFEPOINT
338
354
#ifdef _OS_DARWIN_
339
355
jl_safepoint_resume_thread_mach (ptls2 , tid );
340
356
#endif
357
+ uv_cond_broadcast (& safepoint_cond_begin );
341
358
}
342
359
if (suspend_count != 0 ) {
343
360
jl_atomic_store_relaxed (& ptls2 -> suspend_count , suspend_count - 1 );
0 commit comments