JL_DLLEXPORT int8_t (jl_gc_safe_enter)(void) { return jl_gc_safe_enter(); }
JL_DLLEXPORT int8_t (jl_gc_safe_enter)(void) { jl_ptls_t ptls = jl_get_ptls_states(); return jl_gc_safe_enter(ptls); }
JL_DLLEXPORT jl_task_t *jl_task_get_next(jl_value_t *getsticky) { jl_ptls_t ptls = jl_get_ptls_states(); // spin briefly before blocking when the workqueue is empty size_t spin_count = 0; jl_task_t *task; while (1) { jl_gc_safepoint(); task = get_next_task(getsticky); if (task) return task; if (!_threadedregion) { spin_count = 0; if (ptls->tid == 0) { if (jl_run_once(jl_global_event_loop()) == 0) { task = get_next_task(getsticky); if (task) return task; #ifdef _OS_WINDOWS_ Sleep(INFINITE); #else pause(); #endif } } else { int sleepnow = 0; uv_mutex_lock(&sleep_lock); if (!_threadedregion) { sleepnow = 1; } else { uv_mutex_unlock(&sleep_lock); } if (sleepnow) { int8_t gc_state = jl_gc_safe_enter(ptls); uv_cond_wait(&sleep_alarm, &sleep_lock); uv_mutex_unlock(&sleep_lock); jl_gc_safe_leave(ptls, gc_state); } } } else { if (++spin_count > 1000 && jl_atomic_load(&jl_uv_n_waiters) == 0 && jl_mutex_trylock(&jl_uv_mutex)) { task = get_next_task(getsticky); if (task) { JL_UV_UNLOCK(); return task; } uv_loop_t *loop = jl_global_event_loop(); loop->stop_flag = 0; uv_run(loop, UV_RUN_ONCE); JL_UV_UNLOCK(); } else { jl_cpu_pause(); } } } }