Skip to content

Commit

Permalink
threads: further optimize scheduler wake-ups
Browse files Browse the repository at this point in the history
And add some debugging aids, controlled by changing the
`JULIA_DEBUG_SLEEPWAKE()` macro in `julia_threads.h`

Eliminates the `sleep_check_state` global,
equal to `any(ptls->sleep_check_state == true)`
  • Loading branch information
vtjnash authored and birm committed Feb 22, 2020
1 parent 7fe33c6 commit bb56288
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 150 deletions.
2 changes: 1 addition & 1 deletion base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ function wait()
W = Workqueues[Threads.threadid()]
reftask = poptaskref(W)
result = try_yieldto(ensure_rescheduled, reftask)
Sys.isjsvm() || process_events()
process_events()
# return when we come out of the queue
return result
end
Expand Down
2 changes: 1 addition & 1 deletion src/jl_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ JL_DLLEXPORT int jl_process_events(void)
uv_loop_t *loop = jl_io_loop;
if (loop && (_threadedregion || ptls->tid == 0)) {
jl_gc_safepoint_(ptls);
if (jl_mutex_trylock(&jl_uv_mutex)) {
if (jl_atomic_load(&jl_uv_n_waiters) == 0 && jl_mutex_trylock(&jl_uv_mutex)) {
loop->stop_flag = 0;
int r = uv_run(loop, UV_RUN_NOWAIT);
JL_UV_UNLOCK();
Expand Down
36 changes: 31 additions & 5 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,37 @@ void JL_UV_LOCK(void);
extern "C" {
#endif

//--------------------------------------------------
// timers
// Returns time in nanosec
JL_DLLEXPORT uint64_t jl_hrtime(void);

// number of cycles since power-on
static inline uint64_t cycleclock(void)
{
#if defined(_CPU_X86_64_)
uint64_t low, high;
__asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
return (high << 32) | low;
#elif defined(_CPU_X86_)
int64_t ret;
__asm__ volatile("rdtsc" : "=A"(ret));
return ret;
#elif defined(_CPU_AARCH64_)
// System timer of ARMv8 runs at a different frequency than the CPU's.
// The frequency is fixed, typically in the range 1-50MHz. It can be
// read at CNTFRQ special register. We assume the OS has set up
// the virtual timer properly.
int64_t virtual_timer_value;
__asm__ volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
return virtual_timer_value;
#else
#warning No cycleclock() definition for your platform
// copy from https://github.com/google/benchmark/blob/v1.5.0/src/cycleclock.h
return 0;
#endif
}

#include "timing.h"

#ifdef _COMPILER_MICROSOFT_
Expand Down Expand Up @@ -829,11 +860,6 @@ void jl_push_excstack(jl_excstack_t **stack JL_REQUIRE_ROOTED_SLOT JL_ROOTING_AR
jl_bt_element_t *bt_data, size_t bt_size);
void jl_copy_excstack(jl_excstack_t *dest, jl_excstack_t *src) JL_NOTSAFEPOINT;

//--------------------------------------------------
// timers
// Returns time in nanosec
JL_DLLEXPORT uint64_t jl_hrtime(void);

// congruential random number generator
// for a small amount of thread-local randomness
// we could just use libc:`rand()`, but we want to ensure this is fast
Expand Down
16 changes: 13 additions & 3 deletions src/julia_threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
#include <atomics.h>
// threading ------------------------------------------------------------------

// WARNING: Threading support is incomplete and experimental
// Nonetheless, we define JL_THREAD and use it to give advanced notice to
// maintainers of what eventual threading support will change.
// JULIA_ENABLE_THREADING may be controlled by altering JULIA_THREADS in Make.user

// When running into scheduler issues, this may help provide information on the
// sequence of events that led to the issue. Normally, it is empty.
//#define JULIA_DEBUG_SLEEPWAKE(x) x
#define JULIA_DEBUG_SLEEPWAKE(x)

// Options for task switching algorithm (in order of preference):
// JL_HAVE_ASM -- mostly setjmp
Expand Down Expand Up @@ -221,6 +224,13 @@ struct _jl_tls_states_t {
// Saved exception for previous external API call or NULL if cleared.
// Access via jl_exception_occurred().
struct _jl_value_t *previous_exception;

JULIA_DEBUG_SLEEPWAKE(
uint64_t uv_run_enter;
uint64_t uv_run_leave;
uint64_t sleep_enter;
uint64_t sleep_leave;
)
};

// Update codegen version in `ccall.cpp` after changing either `pause` or `wake`
Expand Down
Loading

0 comments on commit bb56288

Please sign in to comment.