Merge branch 'nd/index-pack-one-fd-per-thread'

Enable threaded index-pack on platforms without thread-unsafe
pread() emulation.

* nd/index-pack-one-fd-per-thread:
  index-pack: work around thread-unsafe pread()
This commit is contained in:
Junio C Hamano 2014-06-03 12:06:42 -07:00
commit 53f52cd92a
3 changed files with 17 additions and 18 deletions

View file

@ -185,9 +185,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.
# #
@ -1345,10 +1342,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

View file

@ -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 = xpread(pack_fd, inbuf, n, from); n = xpread(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;

View file

@ -160,7 +160,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