@@ -24,11 +24,11 @@ static char const * const grep_usage[] = {
2424 NULL
2525};
2626
27- static int use_threads = 1 ;
27+ #define GREP_NUM_THREADS_DEFAULT 8
28+ static int num_threads ;
2829
2930#ifndef NO_PTHREADS
30- #define THREADS 8
31- static pthread_t threads [THREADS ];
31+ static pthread_t * threads ;
3232
3333/* We use one producer thread and THREADS consumer
3434 * threads. The producer adds struct work_items to 'todo' and the
@@ -63,13 +63,13 @@ static pthread_mutex_t grep_mutex;
6363
6464static inline void grep_lock (void )
6565{
66- if (use_threads )
66+ if (num_threads )
6767 pthread_mutex_lock (& grep_mutex );
6868}
6969
7070static inline void grep_unlock (void )
7171{
72- if (use_threads )
72+ if (num_threads )
7373 pthread_mutex_unlock (& grep_mutex );
7474}
7575
@@ -206,7 +206,8 @@ static void start_threads(struct grep_opt *opt)
206206 strbuf_init (& todo [i ].out , 0 );
207207 }
208208
209- for (i = 0 ; i < ARRAY_SIZE (threads ); i ++ ) {
209+ threads = xcalloc (num_threads , sizeof (* threads ));
210+ for (i = 0 ; i < num_threads ; i ++ ) {
210211 int err ;
211212 struct grep_opt * o = grep_opt_dup (opt );
212213 o -> output = strbuf_out ;
@@ -238,12 +239,14 @@ static int wait_all(void)
238239 pthread_cond_broadcast (& cond_add );
239240 grep_unlock ();
240241
241- for (i = 0 ; i < ARRAY_SIZE ( threads ) ; i ++ ) {
242+ for (i = 0 ; i < num_threads ; i ++ ) {
242243 void * h ;
243244 pthread_join (threads [i ], & h );
244245 hit |= (int ) (intptr_t ) h ;
245246 }
246247
248+ free (threads );
249+
247250 pthread_mutex_destroy (& grep_mutex );
248251 pthread_mutex_destroy (& grep_read_mutex );
249252 pthread_mutex_destroy (& grep_attr_mutex );
@@ -267,6 +270,14 @@ static int grep_cmd_config(const char *var, const char *value, void *cb)
267270 int st = grep_config (var , value , cb );
268271 if (git_color_default_config (var , value , cb ) < 0 )
269272 st = -1 ;
273+
274+ if (!strcmp (var , "grep.threads" )) {
275+ num_threads = git_config_int (var , value );
276+ if (num_threads < 0 )
277+ die (_ ("invalid number of threads specified (%d) for %s" ),
278+ num_threads , var );
279+ }
280+
270281 return st ;
271282}
272283
@@ -294,7 +305,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
294305 }
295306
296307#ifndef NO_PTHREADS
297- if (use_threads ) {
308+ if (num_threads ) {
298309 add_work (opt , GREP_SOURCE_SHA1 , pathbuf .buf , path , sha1 );
299310 strbuf_release (& pathbuf );
300311 return 0 ;
@@ -323,7 +334,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
323334 strbuf_addstr (& buf , filename );
324335
325336#ifndef NO_PTHREADS
326- if (use_threads ) {
337+ if (num_threads ) {
327338 add_work (opt , GREP_SOURCE_FILE , buf .buf , filename , filename );
328339 strbuf_release (& buf );
329340 return 0 ;
@@ -697,6 +708,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
697708 N_ ("show <n> context lines before matches" )),
698709 OPT_INTEGER ('A' , "after-context" , & opt .post_context ,
699710 N_ ("show <n> context lines after matches" )),
711+ OPT_INTEGER (0 , "threads" , & num_threads ,
712+ N_ ("use <n> worker threads" )),
700713 OPT_NUMBER_CALLBACK (& opt , N_ ("shortcut for -C NUM" ),
701714 context_callback ),
702715 OPT_BOOL ('p' , "show-function" , & opt .funcname ,
@@ -786,7 +799,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
786799 opt .output_priv = & path_list ;
787800 opt .output = append_path ;
788801 string_list_append (& path_list , show_in_pager );
789- use_threads = 0 ;
790802 }
791803
792804 if (!opt .pattern_list )
@@ -817,14 +829,18 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
817829 }
818830
819831#ifndef NO_PTHREADS
820- if (list .nr || cached || online_cpus () == 1 )
821- use_threads = 0 ;
832+ if (list .nr || cached || show_in_pager )
833+ num_threads = 0 ;
834+ else if (num_threads == 0 )
835+ num_threads = GREP_NUM_THREADS_DEFAULT ;
836+ else if (num_threads < 0 )
837+ die (_ ("invalid number of threads specified (%d)" ), num_threads );
822838#else
823- use_threads = 0 ;
839+ num_threads = 0 ;
824840#endif
825841
826842#ifndef NO_PTHREADS
827- if (use_threads ) {
843+ if (num_threads ) {
828844 if (!(opt .name_only || opt .unmatch_name_only || opt .count )
829845 && (opt .pre_context || opt .post_context ||
830846 opt .file_break || opt .funcbody ))
@@ -894,7 +910,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
894910 hit = grep_objects (& opt , & pathspec , & list );
895911 }
896912
897- if (use_threads )
913+ if (num_threads )
898914 hit |= wait_all ();
899915 if (hit && show_in_pager )
900916 run_pager (& opt , prefix );
0 commit comments