diff options
Diffstat (limited to 'name-hash.c')
-rw-r--r-- | name-hash.c | 79 |
1 files changed, 41 insertions, 38 deletions
diff --git a/name-hash.c b/name-hash.c index 0e10f3eab8..623ca6923a 100644 --- a/name-hash.c +++ b/name-hash.c @@ -7,6 +7,7 @@ */ #define NO_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" +#include "thread-utils.h" struct dir_entry { struct hashmap_entry ent; @@ -17,10 +18,14 @@ struct dir_entry { }; static int dir_entry_cmp(const void *unused_cmp_data, - const struct dir_entry *e1, - const struct dir_entry *e2, - const char *name) + const void *entry, + const void *entry_or_key, + const void *keydata) { + const struct dir_entry *e1 = entry; + const struct dir_entry *e2 = entry_or_key; + const char *name = keydata; + return e1->namelen != e2->namelen || strncasecmp(e1->name, name ? name : e2->name, e1->namelen); } @@ -110,10 +115,12 @@ static void hash_index_entry(struct index_state *istate, struct cache_entry *ce) } static int cache_entry_cmp(const void *unused_cmp_data, - const struct cache_entry *ce1, - const struct cache_entry *ce2, + const void *entry, + const void *entry_or_key, const void *remove) { + const struct cache_entry *ce1 = entry; + const struct cache_entry *ce2 = entry_or_key; /* * For remove_name_hash, find the exact entry (pointer equality); for * index_file_exists, find all entries with matching hash code and @@ -125,22 +132,6 @@ static int cache_entry_cmp(const void *unused_cmp_data, static int lazy_try_threaded = 1; static int lazy_nr_dir_threads; -#ifdef NO_PTHREADS - -static inline int lookup_lazy_params(struct index_state *istate) -{ - return 0; -} - -static inline void threaded_lazy_init_name_hash( - struct index_state *istate) -{ -} - -#else - -#include "thread-utils.h" - /* * Set a minimum number of cache_entries that we will handle per * thread and use that to decide how many threads to run (upto @@ -503,6 +494,7 @@ static inline void lazy_update_dir_ref_counts( static void threaded_lazy_init_name_hash( struct index_state *istate) { + int err; int nr_each; int k_start; int t; @@ -510,6 +502,9 @@ static void threaded_lazy_init_name_hash( struct lazy_dir_thread_data *td_dir; struct lazy_name_thread_data *td_name; + if (!HAVE_THREADS) + return; + k_start = 0; nr_each = DIV_ROUND_UP(istate->cache_nr, lazy_nr_dir_threads); @@ -532,8 +527,9 @@ static void threaded_lazy_init_name_hash( if (k_start > istate->cache_nr) k_start = istate->cache_nr; td_dir_t->k_end = k_start; - if (pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t)) - die("unable to create lazy_dir_thread"); + err = pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t); + if (err) + die(_("unable to create lazy_dir thread: %s"), strerror(err)); } for (t = 0; t < lazy_nr_dir_threads; t++) { struct lazy_dir_thread_data *td_dir_t = td_dir + t; @@ -553,13 +549,15 @@ static void threaded_lazy_init_name_hash( */ td_name->istate = istate; td_name->lazy_entries = lazy_entries; - if (pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name)) - die("unable to create lazy_name_thread"); + err = pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name); + if (err) + die(_("unable to create lazy_name thread: %s"), strerror(err)); lazy_update_dir_ref_counts(istate, lazy_entries); - if (pthread_join(td_name->pthread, NULL)) - die("unable to join lazy_name_thread"); + err = pthread_join(td_name->pthread, NULL); + if (err) + die(_("unable to join lazy_name thread: %s"), strerror(err)); cleanup_dir_mutex(); @@ -568,21 +566,25 @@ static void threaded_lazy_init_name_hash( free(lazy_entries); } -#endif - static void lazy_init_name_hash(struct index_state *istate) { + if (istate->name_hash_initialized) return; - hashmap_init(&istate->name_hash, (hashmap_cmp_fn) cache_entry_cmp, - NULL, istate->cache_nr); - hashmap_init(&istate->dir_hash, (hashmap_cmp_fn) dir_entry_cmp, - NULL, istate->cache_nr); + trace_performance_enter(); + hashmap_init(&istate->name_hash, cache_entry_cmp, NULL, istate->cache_nr); + hashmap_init(&istate->dir_hash, dir_entry_cmp, NULL, istate->cache_nr); if (lookup_lazy_params(istate)) { - hashmap_disallow_rehash(&istate->dir_hash, 1); + /* + * Disable item counting and automatic rehashing because + * we do per-chain (mod n) locking rather than whole hashmap + * locking and we need to prevent the table-size from changing + * and bucket items from being redistributed. + */ + hashmap_disable_item_counting(&istate->dir_hash); threaded_lazy_init_name_hash(istate); - hashmap_disallow_rehash(&istate->dir_hash, 0); + hashmap_enable_item_counting(&istate->dir_hash); } else { int nr; for (nr = 0; nr < istate->cache_nr; nr++) @@ -590,6 +592,7 @@ static void lazy_init_name_hash(struct index_state *istate) } istate->name_hash_initialized = 1; + trace_performance_leave("initialize name hash"); } /* @@ -686,12 +689,12 @@ void adjust_dirname_case(struct index_state *istate, char *name) if (*ptr == '/') { struct dir_entry *dir; - ptr++; - dir = find_dir_entry(istate, name, ptr - name + 1); + dir = find_dir_entry(istate, name, ptr - name); if (dir) { memcpy((void *)startPtr, dir->name + (startPtr - name), ptr - startPtr); - startPtr = ptr; + startPtr = ptr + 1; } + ptr++; } } } |