@@ -287,17 +287,46 @@ void jl_pgcstack_getkey(jl_get_pgcstack_func **f, jl_pgcstack_key_t *k)
287287#endif 
288288
289289jl_ptls_t  * jl_all_tls_states  JL_GLOBALLY_ROOTED ;
290+ int  * jl_threadpool_map ;
291+ int  * jl_threadpool_sizes ;
290292uint8_t  jl_measure_compile_time_enabled  =  0 ;
291293uint64_t  jl_cumulative_compile_time  =  0 ;
292294
293- // return calling thread's ID 
294- // Also update the suspended_threads list in signals-mach when changing the 
295- // type of the thread id. 
295+ // return calling thread's absolute ID 
296296JL_DLLEXPORT  int16_t  jl_threadid (void )
297297{
298298    return  jl_current_task -> tid ;
299299}
300300
301+ // return calling thread's relative ID (with respect to its threadpool) 
302+ int16_t  jl_tid_to_relative (int16_t  rawtid )
303+ {
304+     if  (rawtid  <  0 )
305+         return  rawtid ;
306+     int  poolid  =  jl_threadpool_map [rawtid ];
307+     int  tp_offset  =  0 ;
308+     for  (int  tp  =  0 ; tp  <  poolid ; tp ++ ) {
309+         tp_offset  +=  jl_threadpool_sizes [tp ];
310+     }
311+     return  rawtid  -  tp_offset ;
312+ }
313+ JL_DLLEXPORT  int16_t  jl_relative_threadid (void )
314+ {
315+     return  jl_tid_to_relative (jl_current_task -> tid );
316+ }
317+ 
318+ int16_t  jl_tid_to_poolid (int16_t  tid )
319+ {
320+     int  tp_offset  =  0 ;
321+     for  (int  tp  =  0 ; tp  <  jl_threadpools ; tp ++ ) {
322+         int  tp_size  =  jl_threadpool_sizes [tp ];
323+         if  (tp_offset  +  tp_size  >  tid )
324+             return  tp ;
325+         tp_offset  +=  tp_size ;
326+     }
327+     return  -1 ;
328+ }
329+ 
301330jl_ptls_t  jl_init_threadtls (int16_t  tid )
302331{
303332    jl_ptls_t  ptls  =  (jl_ptls_t )calloc (1 , sizeof (jl_tls_states_t ));
@@ -467,18 +496,61 @@ void jl_init_threading(void)
467496    }
468497    if  (jl_n_threads  <= 0 )
469498        jl_n_threads  =  1 ;
499+     int  jl_extra_threads  =  8 ; // FIXME: ENV[NUM_EXTRA_THREADS_NAME] 
500+     int  jl_max_threadpools  =  8 ; // FIXME: ENV[NUM_THREADPOOLS_NAME] 
470501#ifndef  __clang_analyzer__ 
471-     jl_all_tls_states  =  (jl_ptls_t * )calloc (jl_n_threads , sizeof (void * ));
502+     jl_all_tls_states  =  (jl_ptls_t * )calloc (jl_n_threads + jl_extra_threads , sizeof (void * ));
472503#endif 
504+     jl_threadpools  =  0 ;
505+     jl_threadpool_map  =  (int * )calloc (jl_max_threadpools , sizeof (int ));
506+     jl_threadpool_sizes  =  (int * )calloc (jl_max_threadpools , sizeof (int ));
473507}
474508
475509static  uv_barrier_t  thread_init_done ;
476510
511+ int  jl_start_threads_ (size_t  nthreads , size_t  cur_n_threads , uv_barrier_t  * barrier , int  exclusive )
512+ {
513+     int  cpumasksize  =  uv_cpumask_size ();
514+     if  (cpumasksize  <  jl_n_threads ) // also handles error case 
515+         cpumasksize  =  jl_n_threads ;
516+     char  * mask  =  (char * )alloca (cpumasksize );
517+     int  i ;
518+     uv_thread_t  uvtid ;
519+ 
520+     int  tp  =  jl_threadpools ;
521+     jl_threadpools ++ ;
522+     if  (tp  >  0 ) {
523+         jl_threadpool_sizes [tp ] =  nthreads ;
524+     } else  {
525+         jl_threadpool_sizes [tp ] =  jl_n_threads ;
526+     }
527+ 
528+     uv_barrier_init (barrier , nthreads );
529+ 
530+     for  (i  =  cur_n_threads ; i  <  cur_n_threads + nthreads ; ++ i ) {
531+         jl_threadarg_t  * t  =  (jl_threadarg_t * )malloc_s (sizeof (jl_threadarg_t )); // ownership will be passed to the thread 
532+         t -> tid  =  i ;
533+         t -> barrier  =  barrier ;
534+         uv_thread_create (& uvtid , jl_threadfun , t );
535+         jl_threadpool_map [i ] =  tp ;
536+         if  (exclusive ) {
537+             mask [i ] =  1 ;
538+             uv_thread_setaffinity (& uvtid , mask , NULL , cpumasksize );
539+             mask [i ] =  0 ;
540+         }
541+         uv_thread_detach (& uvtid );
542+     }
543+ 
544+     uv_barrier_wait (barrier );
545+ 
546+     return  tp ;
547+ }
548+ 
477549void  jl_start_threads (void )
478550{
479551    int  cpumasksize  =  uv_cpumask_size ();
480552    char  * cp ;
481-     int  i ,  exclusive ;
553+     int  exclusive ;
482554    uv_thread_t  uvtid ;
483555    if  (cpumasksize  <  jl_n_threads ) // also handles error case 
484556        cpumasksize  =  jl_n_threads ;
@@ -509,22 +581,27 @@ void jl_start_threads(void)
509581    size_t  nthreads  =  jl_n_threads ;
510582
511583    // create threads 
512-     uv_barrier_init (& thread_init_done , nthreads );
584+     jl_start_threads_ (nthreads - 1 , 1 , & thread_init_done , exclusive );
585+ }
513586
514-     for  (i  =  1 ; i  <  nthreads ; ++ i ) {
515-         jl_threadarg_t  * t  =  (jl_threadarg_t * )malloc_s (sizeof (jl_threadarg_t )); // ownership will be passed to the thread 
516-         t -> tid  =  i ;
517-         t -> barrier  =  & thread_init_done ;
518-         uv_thread_create (& uvtid , jl_threadfun , t );
519-         if  (exclusive ) {
520-             mask [i ] =  1 ;
521-             uv_thread_setaffinity (& uvtid , mask , NULL , cpumasksize );
522-             mask [i ] =  0 ;
523-         }
524-         uv_thread_detach (& uvtid );
525-     }
587+ JL_DLLEXPORT  int  jl_start_threads_dedicated (size_t  nthreads , int  exclusive )
588+ {
589+     uv_barrier_t  tbar ;
590+     return  jl_start_threads_ (nthreads , jl_n_threads , & tbar , exclusive );
591+ }
592+ 
593+ JL_DLLEXPORT  int  jl_num_threads (int  tp )
594+ {
595+     if  (jl_threadpools  ==  0 )
596+         // Pre-init 
597+         return  jl_n_threads ;
598+     assert (tp  <  jl_threadpools );
599+     return  jl_threadpool_sizes [tp ];
600+ }
526601
527-     uv_barrier_wait (& thread_init_done );
602+ JL_DLLEXPORT  int  jl_threadpoolid (void )
603+ {
604+     return  jl_threadpool_map [jl_current_task -> tid ];
528605}
529606
530607unsigned volatile   _threadedregion ; // HACK: keep track of whether it is safe to do IO 
0 commit comments