Skip to content

Commit

Permalink
Exclude threads test from rr tracing
Browse files Browse the repository at this point in the history
  • Loading branch information
Keno committed Dec 16, 2020
1 parent a0e0f97 commit f3d5288
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 8 deletions.
23 changes: 23 additions & 0 deletions src/jlapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,17 @@ static void lock_low32(void)
// Actual definition in `ast.c`
void jl_lisp_prompt(void);

static void rr_detach_teleport(void) {
#ifdef _OS_LINUX_
#define RR_CALL_BASE 1000
#define SYS_rrcall_detach_teleport (RR_CALL_BASE + 9)
int err = syscall(SYS_rrcall_detach_teleport, 0, 0, 0, 0, 0, 0);
if (err < 0 || jl_running_under_rr(1)) {
jl_error("Failed to detach from rr session");
}
#endif
}

JL_DLLEXPORT int repl_entrypoint(int argc, char *argv[])
{
// no-op on Windows, note that the caller must have already converted
Expand All @@ -678,7 +689,19 @@ JL_DLLEXPORT int repl_entrypoint(int argc, char *argv[])
memmove(&argv[1], &argv[2], (argc-2)*sizeof(void*));
argc--;
}
char **orig_argv = argv;
jl_parse_opts(&argc, (char***)&argv);

// The parent process requested that we detach from the rr session.
// N.B.: In a perfect world, we would only do this for the portion of
// the execution where we actually need to exclude rr (e.g. because we're
// testing for the absence of a memory-model-dependent bug).
if (jl_options.rr_detach && jl_running_under_rr(0)) {
rr_detach_teleport();
execv("/proc/self/exe", orig_argv);
jl_error("Failed to self-execute");
}

julia_init(jl_options.image_file_specified ? JL_IMAGE_CWD : JL_IMAGE_JULIA_HOME);
if (lisp_prompt) {
jl_get_ptls_states()->world_age = jl_get_world_counter();
Expand Down
6 changes: 6 additions & 0 deletions src/jloptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ jl_options_t jl_options = { 0, // quiet
0, // image_file_specified
JL_OPTIONS_WARN_SCOPE_ON, // ambiguous scope warning
0, // image-codegen
0, // rr-detach
};

static const char usage[] = "julia [switches] -- [programfile] [args...]\n";
Expand Down Expand Up @@ -203,6 +204,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
opt_project,
opt_bug_report,
opt_image_codegen,
opt_rr_detach,
};
static const char* const shortopts = "+vhqH:e:E:L:J:C:it:p:O:g:";
static const struct option longopts[] = {
Expand Down Expand Up @@ -254,6 +256,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
{ "bind-to", required_argument, 0, opt_bind_to },
{ "lisp", no_argument, 0, 1 },
{ "image-codegen", no_argument, 0, opt_image_codegen },
{ "rr-detach", no_argument, 0, opt_rr_detach },
{ 0, 0, 0, 0 }
};

Expand Down Expand Up @@ -655,6 +658,9 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp)
case opt_image_codegen:
jl_options.image_codegen = 1;
break;
case opt_rr_detach:
jl_options.rr_detach = 1;
break;
default:
jl_errorf("julia: unhandled option -- %c\n"
"This is a bug, please report it.", c);
Expand Down
1 change: 1 addition & 0 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1947,6 +1947,7 @@ typedef struct {
int8_t image_file_specified;
int8_t warn_scope;
int8_t image_codegen;
int8_t rr_detach;
} jl_options_t;

extern JL_DLLEXPORT jl_options_t jl_options;
Expand Down
2 changes: 2 additions & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ void JL_UV_LOCK(void);
extern "C" {
#endif

int jl_running_under_rr(int recheck);

//--------------------------------------------------
// timers
// Returns time in nanosec
Expand Down
6 changes: 3 additions & 3 deletions src/partr.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,14 @@ JL_DLLEXPORT int jl_enqueue_task(jl_task_t *task)
}


static int running_under_rr(void)
int jl_running_under_rr(int recheck)
{
#ifdef _OS_LINUX_
#define RR_CALL_BASE 1000
#define SYS_rrcall_check_presence (RR_CALL_BASE + 8)
static int checked_running_under_rr = 0;
static int is_running_under_rr = 0;
if (!checked_running_under_rr) {
if (!checked_running_under_rr || recheck) {
int ret = syscall(SYS_rrcall_check_presence, 0, 0, 0, 0, 0, 0);
if (ret == -1) {
// Should always be ENOSYS, but who knows what people do for
Expand Down Expand Up @@ -311,7 +311,7 @@ static int sleep_check_after_threshold(uint64_t *start_cycles)
* scheduling logic from switching to other threads. Just don't bother
* trying to wait here
*/
if (running_under_rr())
if (jl_running_under_rr(0))
return 1;
if (!(*start_cycles)) {
*start_cycles = jl_hrtime();
Expand Down
10 changes: 5 additions & 5 deletions test/threads.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

using Test

let cmd = `$(Base.julia_cmd()) --depwarn=error --startup-file=no threads_exec.jl`
let cmd = `$(Base.julia_cmd()) --depwarn=error --rr-detach --startup-file=no threads_exec.jl`
for test_nthreads in (1, 2, 4, 4) # run once to try single-threaded mode, then try a couple times to trigger bad races
new_env = copy(ENV)
new_env["JULIA_NUM_THREADS"] = string(test_nthreads)
Expand All @@ -11,12 +11,12 @@ let cmd = `$(Base.julia_cmd()) --depwarn=error --startup-file=no threads_exec.jl
end

# issue #34415 - make sure external affinity settings work
const SYS_rrcall_check_presence = 1008
running_under_rr() = 0 == ccall(:syscall, Int,
(Int, Int, Int, Int, Int, Int, Int),
SYS_rrcall_check_presence, 0, 0, 0, 0, 0, 0)

if Sys.islinux()
const SYS_rrcall_check_presence = 1008
running_under_rr() = 0 == ccall(:syscall, Int,
(Int, Int, Int, Int, Int, Int, Int),
SYS_rrcall_check_presence, 0, 0, 0, 0, 0, 0)
if Sys.CPU_THREADS > 1 && Sys.which("taskset") !== nothing && !running_under_rr()
run_with_affinity(spec) = readchomp(`taskset -c $spec $(Base.julia_cmd()) -e "run(\`taskset -p \$(getpid())\`)"`)
@test endswith(run_with_affinity("1"), "2")
Expand Down

0 comments on commit f3d5288

Please sign in to comment.