Skip to content

read-cache: run verify_hdr() in background thread #978

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include "split-index.h"
#include "utf8.h"

#ifndef NO_PTHREADS
#include <pthread.h>
#endif

/* Mask for the name length in ce_flags in the on-disk index */

#define CE_NAMEMASK (0x0fff)
Expand Down Expand Up @@ -1400,6 +1404,34 @@ static int verify_hdr(struct cache_header *hdr, unsigned long size)
return 0;
}

#ifndef NO_PTHREADS
/*
* Require index file to be larger than this threshold before
* we bother using a thread to verify the SHA.
* This value was arbitrarily chosen.
*/
#define VERIFY_HDR_THRESHOLD 10*1024*1024

struct verify_hdr_thread_data
{
pthread_t thread_id;
struct cache_header *hdr;
size_t size;
int result;
};

/*
* A thread proc to run the verify_hdr() computation
* in a background thread.
*/
static void *verify_hdr_thread(void *_data)
{
struct verify_hdr_thread_data *p = _data;
p->result = verify_hdr(p->hdr, (unsigned long)p->size);
return NULL;
}
#endif

static int read_index_extension(struct index_state *istate,
const char *ext, void *data, unsigned long sz)
{
Expand Down Expand Up @@ -1588,6 +1620,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
void *mmap;
size_t mmap_size;
struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
#ifndef NO_PTHREADS
struct verify_hdr_thread_data verify_hdr_thread_data;
#endif

if (istate->initialized)
return istate->cache_nr;
Expand All @@ -1614,8 +1649,23 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
close(fd);

hdr = mmap;
#ifdef NO_PTHREADS
if (verify_hdr(hdr, mmap_size) < 0)
goto unmap;
#else
if (mmap_size < VERIFY_HDR_THRESHOLD) {
if (verify_hdr(hdr, mmap_size) < 0)
goto unmap;
} else {
verify_hdr_thread_data.hdr = hdr;
verify_hdr_thread_data.size = mmap_size;
verify_hdr_thread_data.result = -1;
if (pthread_create(
&verify_hdr_thread_data.thread_id, NULL,
verify_hdr_thread, &verify_hdr_thread_data))
die_errno("unable to start verify_hdr_thread");
}
#endif

hashcpy(istate->sha1, (const unsigned char *)hdr + mmap_size - 20);
istate->version = ntohl(hdr->hdr_version);
Expand Down Expand Up @@ -1663,6 +1713,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
src_offset += 8;
src_offset += extsize;
}

#ifndef NO_PTHREADS
if (mmap_size >= VERIFY_HDR_THRESHOLD) {
if (pthread_join(verify_hdr_thread_data.thread_id, NULL))
die_errno("unable to join verify_hdr_thread");
if (verify_hdr_thread_data.result < 0)
goto unmap;
}
#endif

munmap(mmap, mmap_size);
return istate->cache_nr;

Expand Down