@@ -778,9 +778,9 @@ void jl_init_threading(void)
778778 }
779779
780780 jl_all_tls_states_size = nthreads + nthreadsi + ngcthreads ;
781- jl_n_threads_per_pool = (int * )malloc_s ( 2 * sizeof (int ));
782- jl_n_threads_per_pool [0 ] = nthreadsi ;
783- jl_n_threads_per_pool [1 ] = nthreads ;
781+ jl_n_threads_per_pool = (int * )calloc_s ( jl_n_threadpools * sizeof (int ));
782+ jl_n_threads_per_pool [JL_THREADPOOL_ID_INTERACTIVE ] = nthreadsi ;
783+ jl_n_threads_per_pool [JL_THREADPOOL_ID_DEFAULT ] = nthreads ;
784784 assert (jl_all_tls_states_size > 0 );
785785 jl_atomic_store_release (& jl_all_tls_states , (jl_ptls_t * )calloc (jl_all_tls_states_size , sizeof (jl_ptls_t )));
786786 jl_atomic_store_release (& jl_n_threads , jl_all_tls_states_size );
@@ -793,7 +793,10 @@ uv_barrier_t thread_init_done;
793793void jl_start_threads (void )
794794{
795795 int nthreads = jl_atomic_load_relaxed (& jl_n_threads );
796- int ngcthreads = jl_n_gcthreads ;
796+ int ninteractive_threads = jl_n_threads_per_pool [JL_THREADPOOL_ID_INTERACTIVE ];
797+ int ndefault_threads = jl_n_threads_per_pool [JL_THREADPOOL_ID_DEFAULT ];
798+ int nmutator_threads = nthreads - jl_n_gcthreads ;
799+
797800 int cpumasksize = uv_cpumask_size ();
798801 char * cp ;
799802 int i , exclusive ;
@@ -808,36 +811,43 @@ void jl_start_threads(void)
808811 if (cp && strcmp (cp , "0" ) != 0 )
809812 exclusive = 1 ;
810813
811- // exclusive use: affinitize threads, master thread on proc 0, rest
812- // according to a 'compact' policy
814+ // exclusive use: affinitize threads, master thread on proc 0, threads in
815+ // default pool according to a 'compact' policy
813816 // non-exclusive: no affinity settings; let the kernel move threads about
814817 if (exclusive ) {
815- if (nthreads > jl_cpu_threads ()) {
818+ if (ndefault_threads > jl_cpu_threads ()) {
816819 jl_printf (JL_STDERR , "ERROR: Too many threads requested for %s option.\n" , MACHINE_EXCLUSIVE_NAME );
817820 exit (1 );
818821 }
819822 memset (mask , 0 , cpumasksize );
820- mask [0 ] = 1 ;
821- uvtid = uv_thread_self ();
822- uv_thread_setaffinity (& uvtid , mask , NULL , cpumasksize );
823- mask [0 ] = 0 ;
823+
824+ // If there are no interactive threads, the master thread is in the
825+ // default pool and we must affinitize it
826+ if (ninteractive_threads == 0 ) {
827+ mask [0 ] = 1 ;
828+ uvtid = uv_thread_self ();
829+ uv_thread_setaffinity (& uvtid , mask , NULL , cpumasksize );
830+ mask [0 ] = 0 ;
831+ }
824832 }
825833
826834 // create threads
827835 uv_barrier_init (& thread_init_done , nthreads );
828836
829837 // GC/System threads need to be after the worker threads.
830- int nmutator_threads = nthreads - ngcthreads ;
831-
832838 for (i = 1 ; i < nmutator_threads ; ++ i ) {
833839 jl_threadarg_t * t = (jl_threadarg_t * )malloc_s (sizeof (jl_threadarg_t )); // ownership will be passed to the thread
834840 t -> tid = i ;
835841 t -> barrier = & thread_init_done ;
836842 uv_thread_create (& uvtid , jl_threadfun , t );
837- if (exclusive ) {
838- mask [i ] = 1 ;
843+
844+ // Interactive pool threads get the low IDs, so check if this is a
845+ // default pool thread. The master thread is already on CPU 0.
846+ if (exclusive && i >= ninteractive_threads ) {
847+ assert (i - ninteractive_threads < cpumasksize );
848+ mask [i - ninteractive_threads ] = 1 ;
839849 uv_thread_setaffinity (& uvtid , mask , NULL , cpumasksize );
840- mask [i ] = 0 ;
850+ mask [i - ninteractive_threads ] = 0 ;
841851 }
842852 uv_thread_detach (& uvtid );
843853 }
0 commit comments