diff --git a/src/threading.c b/src/threading.c index 77956786af3f4..caf5b86e0b208 100644 --- a/src/threading.c +++ b/src/threading.c @@ -794,6 +794,9 @@ void jl_start_threads(void) { int nthreads = jl_atomic_load_relaxed(&jl_n_threads); int ngcthreads = jl_n_gcthreads; + int nthreadsi = jl_n_threads_per_pool[0]; + int nmutator_threads = nthreads - ngcthreads; + int cpumasksize = uv_cpumask_size(); char *cp; int i, exclusive; @@ -812,32 +815,33 @@ void jl_start_threads(void) // according to a 'compact' policy // non-exclusive: no affinity settings; let the kernel move threads about if (exclusive) { - if (nthreads > jl_cpu_threads()) { + if (nmutator_threads - nthreadsi > jl_cpu_threads()) { jl_printf(JL_STDERR, "ERROR: Too many threads requested for %s option.\n", MACHINE_EXCLUSIVE_NAME); exit(1); } memset(mask, 0, cpumasksize); - mask[0] = 1; - uvtid = uv_thread_self(); - uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize); - mask[0] = 0; + + if (nthreadsi == 0) { + mask[0] = 1; + uvtid = uv_thread_self(); + uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize); + mask[0] = 0; + } } // create threads uv_barrier_init(&thread_init_done, nthreads); // GC/System threads need to be after the worker threads. - int nmutator_threads = nthreads - ngcthreads; - for (i = 1; i < nmutator_threads; ++i) { jl_threadarg_t *t = (jl_threadarg_t *)malloc_s(sizeof(jl_threadarg_t)); // ownership will be passed to the thread t->tid = i; t->barrier = &thread_init_done; uv_thread_create(&uvtid, jl_threadfun, t); - if (exclusive) { - mask[i] = 1; + if (exclusive && i > nthreadsi) { + mask[i - nthreadsi] = 1; uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize); - mask[i] = 0; + mask[i - nthreadsi] = 0; } uv_thread_detach(&uvtid); } diff --git a/test/threads.jl b/test/threads.jl index 179279dbab4e6..43fbea1e351a2 100644 --- a/test/threads.jl +++ b/test/threads.jl @@ -123,10 +123,11 @@ if AFFINITY_SUPPORTED end end -function get_nthreads(options = ``; cpus = nothing) +function get_nthreads(options = ``; cpus = nothing, exclusive = false) cmd = `$(Base.julia_cmd()) --startup-file=no $(options)` cmd = `$cmd -e "print(Threads.threadpoolsize())"` - cmd = addenv(cmd, "JULIA_EXCLUSIVE" => "0", "JULIA_NUM_THREADS" => "auto") + cmd = addenv(cmd, "JULIA_EXCLUSIVE" => exclusive ? "1" : "0", + "JULIA_NUM_THREADS" => "auto") if cpus !== nothing cmd = setcpuaffinity(cmd, cpus) end @@ -138,6 +139,7 @@ end allowed_cpus = findall(uv_thread_getaffinity()) if length(allowed_cpus) ≥ 2 @test get_nthreads() ≥ 2 + @test get_nthreads(exclusive = true) ≥ 2 @test get_nthreads(cpus = allowed_cpus[1:1]) == 1 @test get_nthreads(cpus = allowed_cpus[2:2]) == 1 @test get_nthreads(cpus = allowed_cpus[1:2]) == 2