@ -24,11 +24,11 @@ static char const * const grep_usage[] = {
@@ -24,11 +24,11 @@ static char const * const grep_usage[] = {
NULL
};
static int use_threads = 1;
#define GREP_NUM_THREADS_DEFAULT 8
static int num_threads;
#ifndef NO_PTHREADS
#define THREADS 8
static pthread_t threads[THREADS];
static pthread_t *threads;
/* We use one producer thread and THREADS consumer
* threads. The producer adds struct work_items to 'todo' and the
@ -63,13 +63,13 @@ static pthread_mutex_t grep_mutex;
@@ -63,13 +63,13 @@ static pthread_mutex_t grep_mutex;
static inline void grep_lock(void)
{
if (use_threads)
if (num_threads)
pthread_mutex_lock(&grep_mutex);
}
static inline void grep_unlock(void)
{
if (use_threads)
if (num_threads)
pthread_mutex_unlock(&grep_mutex);
}
@ -206,7 +206,8 @@ static void start_threads(struct grep_opt *opt)
@@ -206,7 +206,8 @@ static void start_threads(struct grep_opt *opt)
strbuf_init(&todo[i].out, 0);
}
for (i = 0; i < ARRAY_SIZE(threads); i++) {
threads = xcalloc(num_threads, sizeof(*threads));
for (i = 0; i < num_threads; i++) {
int err;
struct grep_opt *o = grep_opt_dup(opt);
o->output = strbuf_out;
@ -238,12 +239,14 @@ static int wait_all(void)
@@ -238,12 +239,14 @@ static int wait_all(void)
pthread_cond_broadcast(&cond_add);
grep_unlock();
for (i = 0; i < ARRAY_SIZE(threads); i++) {
for (i = 0; i < num_threads; i++) {
void *h;
pthread_join(threads[i], &h);
hit |= (int) (intptr_t) h;
}
free(threads);
pthread_mutex_destroy(&grep_mutex);
pthread_mutex_destroy(&grep_read_mutex);
pthread_mutex_destroy(&grep_attr_mutex);
@ -267,6 +270,14 @@ static int grep_cmd_config(const char *var, const char *value, void *cb)
@@ -267,6 +270,14 @@ static int grep_cmd_config(const char *var, const char *value, void *cb)
int st = grep_config(var, value, cb);
if (git_color_default_config(var, value, cb) < 0)
st = -1;
if (!strcmp(var, "grep.threads")) {
num_threads = git_config_int(var, value);
if (num_threads < 0)
die(_("invalid number of threads specified (%d) for %s"),
num_threads, var);
}
return st;
}
@ -294,7 +305,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
@@ -294,7 +305,7 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1,
}
#ifndef NO_PTHREADS
if (use_threads) {
if (num_threads) {
add_work(opt, GREP_SOURCE_SHA1, pathbuf.buf, path, sha1);
strbuf_release(&pathbuf);
return 0;
@ -323,7 +334,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
@@ -323,7 +334,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
strbuf_addstr(&buf, filename);
#ifndef NO_PTHREADS
if (use_threads) {
if (num_threads) {
add_work(opt, GREP_SOURCE_FILE, buf.buf, filename, filename);
strbuf_release(&buf);
return 0;
@ -702,6 +713,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
@@ -702,6 +713,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
N_("show <n> context lines before matches")),
OPT_INTEGER('A', "after-context", &opt.post_context,
N_("show <n> context lines after matches")),
OPT_INTEGER(0, "threads", &num_threads,
N_("use <n> worker threads")),
OPT_NUMBER_CALLBACK(&opt, N_("shortcut for -C NUM"),
context_callback),
OPT_BOOL('p', "show-function", &opt.funcname,
@ -832,13 +845,17 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
@@ -832,13 +845,17 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
#ifndef NO_PTHREADS
if (list.nr || cached || show_in_pager)
use_threads = 0;
num_threads = 0;
else if (num_threads == 0)
num_threads = GREP_NUM_THREADS_DEFAULT;
else if (num_threads < 0)
die(_("invalid number of threads specified (%d)"), num_threads);
#else
use_threads = 0;
num_threads = 0;
#endif
#ifndef NO_PTHREADS
if (use_threads) {
if (num_threads) {
if (!(opt.name_only || opt.unmatch_name_only || opt.count)
&& (opt.pre_context || opt.post_context ||
opt.file_break || opt.funcbody))
@ -908,7 +925,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
@@ -908,7 +925,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
hit = grep_objects(&opt, &pathspec, &list);
}
if (use_threads)
if (num_threads)
hit |= wait_all();
if (hit && show_in_pager)
run_pager(&opt, prefix);