Merge branch 'nd/index-pack-one-fd-per-thread' into maint
We used to disable threaded "git index-pack" on platforms without thread-safe pread(); use a different workaround for such platforms to allow threaded "git index-pack". * nd/index-pack-one-fd-per-thread: index-pack: work around thread-unsafe pread()
This commit is contained in:
commit
a9041df7ab
7
Makefile
7
Makefile
@ -183,9 +183,6 @@ all::
|
|||||||
# Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval
|
# Define NO_STRUCT_ITIMERVAL if you don't have struct itimerval
|
||||||
# This also implies NO_SETITIMER
|
# This also implies NO_SETITIMER
|
||||||
#
|
#
|
||||||
# Define NO_THREAD_SAFE_PREAD if your pread() implementation is not
|
|
||||||
# thread-safe. (e.g. compat/pread.c or cygwin)
|
|
||||||
#
|
|
||||||
# Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
|
# Define NO_FAST_WORKING_DIRECTORY if accessing objects in pack files is
|
||||||
# generally faster on your platform than accessing the working directory.
|
# generally faster on your platform than accessing the working directory.
|
||||||
#
|
#
|
||||||
@ -1339,10 +1336,6 @@ endif
|
|||||||
ifdef NO_PREAD
|
ifdef NO_PREAD
|
||||||
COMPAT_CFLAGS += -DNO_PREAD
|
COMPAT_CFLAGS += -DNO_PREAD
|
||||||
COMPAT_OBJS += compat/pread.o
|
COMPAT_OBJS += compat/pread.o
|
||||||
NO_THREAD_SAFE_PREAD = YesPlease
|
|
||||||
endif
|
|
||||||
ifdef NO_THREAD_SAFE_PREAD
|
|
||||||
BASIC_CFLAGS += -DNO_THREAD_SAFE_PREAD
|
|
||||||
endif
|
endif
|
||||||
ifdef NO_FAST_WORKING_DIRECTORY
|
ifdef NO_FAST_WORKING_DIRECTORY
|
||||||
BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
|
BASIC_CFLAGS += -DNO_FAST_WORKING_DIRECTORY
|
||||||
|
@ -40,17 +40,13 @@ struct base_data {
|
|||||||
int ofs_first, ofs_last;
|
int ofs_first, ofs_last;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(NO_PTHREADS) && defined(NO_THREAD_SAFE_PREAD)
|
|
||||||
/* pread() emulation is not thread-safe. Disable threading. */
|
|
||||||
#define NO_PTHREADS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct thread_local {
|
struct thread_local {
|
||||||
#ifndef NO_PTHREADS
|
#ifndef NO_PTHREADS
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
#endif
|
#endif
|
||||||
struct base_data *base_cache;
|
struct base_data *base_cache;
|
||||||
size_t base_cache_used;
|
size_t base_cache_used;
|
||||||
|
int pack_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -91,7 +87,8 @@ static off_t consumed_bytes;
|
|||||||
static unsigned deepest_delta;
|
static unsigned deepest_delta;
|
||||||
static git_SHA_CTX input_ctx;
|
static git_SHA_CTX input_ctx;
|
||||||
static uint32_t input_crc32;
|
static uint32_t input_crc32;
|
||||||
static int input_fd, output_fd, pack_fd;
|
static int input_fd, output_fd;
|
||||||
|
static const char *curr_pack;
|
||||||
|
|
||||||
#ifndef NO_PTHREADS
|
#ifndef NO_PTHREADS
|
||||||
|
|
||||||
@ -134,6 +131,7 @@ static inline void unlock_mutex(pthread_mutex_t *mutex)
|
|||||||
*/
|
*/
|
||||||
static void init_thread(void)
|
static void init_thread(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
init_recursive_mutex(&read_mutex);
|
init_recursive_mutex(&read_mutex);
|
||||||
pthread_mutex_init(&counter_mutex, NULL);
|
pthread_mutex_init(&counter_mutex, NULL);
|
||||||
pthread_mutex_init(&work_mutex, NULL);
|
pthread_mutex_init(&work_mutex, NULL);
|
||||||
@ -141,11 +139,18 @@ static void init_thread(void)
|
|||||||
pthread_mutex_init(&deepest_delta_mutex, NULL);
|
pthread_mutex_init(&deepest_delta_mutex, NULL);
|
||||||
pthread_key_create(&key, NULL);
|
pthread_key_create(&key, NULL);
|
||||||
thread_data = xcalloc(nr_threads, sizeof(*thread_data));
|
thread_data = xcalloc(nr_threads, sizeof(*thread_data));
|
||||||
|
for (i = 0; i < nr_threads; i++) {
|
||||||
|
thread_data[i].pack_fd = open(curr_pack, O_RDONLY);
|
||||||
|
if (thread_data[i].pack_fd == -1)
|
||||||
|
die_errno(_("unable to open %s"), curr_pack);
|
||||||
|
}
|
||||||
|
|
||||||
threads_active = 1;
|
threads_active = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cleanup_thread(void)
|
static void cleanup_thread(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
if (!threads_active)
|
if (!threads_active)
|
||||||
return;
|
return;
|
||||||
threads_active = 0;
|
threads_active = 0;
|
||||||
@ -154,6 +159,8 @@ static void cleanup_thread(void)
|
|||||||
pthread_mutex_destroy(&work_mutex);
|
pthread_mutex_destroy(&work_mutex);
|
||||||
if (show_stat)
|
if (show_stat)
|
||||||
pthread_mutex_destroy(&deepest_delta_mutex);
|
pthread_mutex_destroy(&deepest_delta_mutex);
|
||||||
|
for (i = 0; i < nr_threads; i++)
|
||||||
|
close(thread_data[i].pack_fd);
|
||||||
pthread_key_delete(key);
|
pthread_key_delete(key);
|
||||||
free(thread_data);
|
free(thread_data);
|
||||||
}
|
}
|
||||||
@ -288,13 +295,13 @@ static const char *open_pack_file(const char *pack_name)
|
|||||||
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
|
output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
|
||||||
if (output_fd < 0)
|
if (output_fd < 0)
|
||||||
die_errno(_("unable to create '%s'"), pack_name);
|
die_errno(_("unable to create '%s'"), pack_name);
|
||||||
pack_fd = output_fd;
|
nothread_data.pack_fd = output_fd;
|
||||||
} else {
|
} else {
|
||||||
input_fd = open(pack_name, O_RDONLY);
|
input_fd = open(pack_name, O_RDONLY);
|
||||||
if (input_fd < 0)
|
if (input_fd < 0)
|
||||||
die_errno(_("cannot open packfile '%s'"), pack_name);
|
die_errno(_("cannot open packfile '%s'"), pack_name);
|
||||||
output_fd = -1;
|
output_fd = -1;
|
||||||
pack_fd = input_fd;
|
nothread_data.pack_fd = input_fd;
|
||||||
}
|
}
|
||||||
git_SHA1_Init(&input_ctx);
|
git_SHA1_Init(&input_ctx);
|
||||||
return pack_name;
|
return pack_name;
|
||||||
@ -542,7 +549,7 @@ static void *unpack_data(struct object_entry *obj,
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
ssize_t n = (len < 64*1024) ? len : 64*1024;
|
ssize_t n = (len < 64*1024) ? len : 64*1024;
|
||||||
n = pread(pack_fd, inbuf, n, from);
|
n = pread(get_thread_data()->pack_fd, inbuf, n, from);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
die_errno(_("cannot pread pack file"));
|
die_errno(_("cannot pread pack file"));
|
||||||
if (!n)
|
if (!n)
|
||||||
@ -1490,7 +1497,7 @@ static void show_pack_info(int stat_only)
|
|||||||
int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
int cmd_index_pack(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
|
int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
|
||||||
const char *curr_pack, *curr_index;
|
const char *curr_index;
|
||||||
const char *index_name = NULL, *pack_name = NULL;
|
const char *index_name = NULL, *pack_name = NULL;
|
||||||
const char *keep_name = NULL, *keep_msg = NULL;
|
const char *keep_name = NULL, *keep_msg = NULL;
|
||||||
char *index_name_buf = NULL, *keep_name_buf = NULL;
|
char *index_name_buf = NULL, *keep_name_buf = NULL;
|
||||||
|
@ -157,7 +157,6 @@ ifeq ($(uname_O),Cygwin)
|
|||||||
NO_SYMLINK_HEAD = YesPlease
|
NO_SYMLINK_HEAD = YesPlease
|
||||||
NO_IPV6 = YesPlease
|
NO_IPV6 = YesPlease
|
||||||
OLD_ICONV = UnfortunatelyYes
|
OLD_ICONV = UnfortunatelyYes
|
||||||
NO_THREAD_SAFE_PREAD = YesPlease
|
|
||||||
# There are conflicting reports about this.
|
# There are conflicting reports about this.
|
||||||
# On some boxes NO_MMAP is needed, and not so elsewhere.
|
# On some boxes NO_MMAP is needed, and not so elsewhere.
|
||||||
# Try commenting this out if you suspect MMAP is more efficient
|
# Try commenting this out if you suspect MMAP is more efficient
|
||||||
|
Loading…
Reference in New Issue
Block a user