diff options
author | Vicent Marti <tanoku@gmail.com> | 2011-02-17 21:32:00 +0200 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2011-02-17 23:20:47 +0200 |
commit | 348c7335dd804ea12eabac7106c5f9675a421ba0 (patch) | |
tree | 89d918bbc50ee95c44609947d284d49597c157fd /src/thread-utils.h | |
parent | 81d0ff1ca5db0ab1a3920c96605899c6161467c8 (diff) | |
download | libgit2-348c7335dd804ea12eabac7106c5f9675a421ba0.tar.gz |
Improve the performance when writing Index files
In response to issue #60 (git_index_write really slow), the write_index
function has been rewritten to improve its performance -- it should now
be in par with the performance of git.git.
On top of that, if Posix Threads are available when compiling libgit2, a
new threaded writing system will be used (3 separate threads take care
of solving byte-endianness, hashing the contents of the index and
writing to disk, respectively). For very long Index files, this method
is up to 3x times faster than git.git.
Signed-off-by: Vicent Marti <tanoku@gmail.com>
Diffstat (limited to 'src/thread-utils.h')
-rw-r--r-- | src/thread-utils.h | 156 |
1 files changed, 88 insertions, 68 deletions
diff --git a/src/thread-utils.h b/src/thread-utils.h index 0395b97d1..588c919bf 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -2,86 +2,106 @@ #define INCLUDE_thread_utils_h__ #if defined(GIT_HAS_PTHREAD) -typedef pthread_mutex_t git_lck; -# define GITLCK_INIT PTHREAD_MUTEX_INITIALIZER -# define gitlck_init(a) pthread_mutex_init(a, NULL) -# define gitlck_lock(a) pthread_mutex_lock(a) -# define gitlck_unlock(a) pthread_mutex_unlock(a) -# define gitlck_free(a) pthread_mutex_destroy(a) + typedef pthread_t git_thread; +# define git_thread_create(thread, attr, start_routine, arg) pthread_create(thread, attr, start_routine, arg) +# define git_thread_kill(thread) pthread_cancel(thread) +# define git_thread_exit(status) pthread_exit(status) +# define git_thread_join(id, status) pthread_join(id, status) -# if defined(GIT_HAS_ASM_ATOMIC) -# include <asm/atomic.h> -typedef atomic_t git_refcnt; -# define gitrc_init(a) atomic_set(a, 0) -# define gitrc_inc(a) atomic_inc_return(a) -# define gitrc_dec(a) atomic_dec_and_test(a) -# define gitrc_free(a) (void)0 + /* Pthreads Mutex */ + typedef pthread_mutex_t git_lck; +# define GITLCK_INIT PTHREAD_MUTEX_INITIALIZER +# define gitlck_init(a) pthread_mutex_init(a, NULL) +# define gitlck_lock(a) pthread_mutex_lock(a) +# define gitlck_unlock(a) pthread_mutex_unlock(a) +# define gitlck_free(a) pthread_mutex_destroy(a) -# else -typedef struct { git_lck lock; int counter; } git_refcnt; + /* Pthreads condition vars */ + typedef pthread_cond_t git_cnd; +# define GITCND_INIT PTHREAD_COND_INITIALIZER +# define gitcnd_init(c, a) pthread_cond_init(c, a) +# define gitcnd_free(c) pthread_cond_destroy(c) +# define gitcnd_wait(c, l) pthread_cond_wait(c, l) +# define gitcnd_signal(c) pthread_cond_signal(c) +# define gitcnd_broadcast(c) pthread_cond_broadcast(c) -/** Initialize to 0. No memory barrier is issued. */ -GIT_INLINE(void) gitrc_init(git_refcnt *p) -{ - gitlck_init(&p->lock); - p->counter = 0; -} +# if defined(GIT_HAS_ASM_ATOMIC) +# include <asm/atomic.h> + typedef atomic_t git_refcnt; +# define gitrc_init(a, v) atomic_set(a, v) +# define gitrc_inc(a) atomic_inc_return(a) +# define gitrc_dec(a) atomic_dec_and_test(a) +# define gitrc_free(a) (void)0 +# elif defined(GIT_WIN32) + typedef long git_refcnt; +# define gitrc_init(a, v) *a = v +# define gitrc_inc(a) InterlockedIncrement(a) +# define gitrc_dec(a) !InterlockedDecrement(a) +# define gitrc_free(a) (void)0 +# else + typedef struct { git_lck lock; int counter; } git_refcnt; -/** - * Increment. - * - * Atomically increments @p by 1. A memory barrier is also - * issued before and after the operation. - * - * @param p pointer of type git_refcnt - */ -GIT_INLINE(void) gitrc_inc(git_refcnt *p) -{ - gitlck_lock(&p->lock); - p->counter++; - gitlck_unlock(&p->lock); -} + /** Initialize to 0. No memory barrier is issued. */ + GIT_INLINE(void) gitrc_init(git_refcnt *p, int value) + { + gitlck_init(&p->lock); + p->counter = value; + } -/** - * Decrement and test. - * - * Atomically decrements @p by 1 and returns true if the - * result is 0, or false for all other cases. A memory - * barrier is also issued before and after the operation. - * - * @param p pointer of type git_refcnt - */ -GIT_INLINE(int) gitrc_dec(git_refcnt *p) -{ - int c; - gitlck_lock(&p->lock); - c = --p->counter; - gitlck_unlock(&p->lock); - return !c; -} + /** + * Increment. + * + * Atomically increments @p by 1. A memory barrier is also + * issued before and after the operation. + * + * @param p pointer of type git_refcnt + */ + GIT_INLINE(void) gitrc_inc(git_refcnt *p) + { + gitlck_lock(&p->lock); + p->counter++; + gitlck_unlock(&p->lock); + } -/** Free any resources associated with the counter. */ -# define gitrc_free(p) gitlck_free(&(p)->lock) + /** + * Decrement and test. + * + * Atomically decrements @p by 1 and returns true if the + * result is 0, or false for all other cases. A memory + * barrier is also issued before and after the operation. + * + * @param p pointer of type git_refcnt + */ + GIT_INLINE(int) gitrc_dec(git_refcnt *p) + { + int c; + gitlck_lock(&p->lock); + c = --p->counter; + gitlck_unlock(&p->lock); + return !c; + } -# endif + /** Free any resources associated with the counter. */ +# define gitrc_free(p) gitlck_free(&(p)->lock) +# endif #elif defined(GIT_THREADS) -# error GIT_THREADS but no git_lck implementation +# error GIT_THREADS but no git_lck implementation #else -typedef struct { int dummy; } git_lck; -# define GIT_MUTEX_INIT {} -# define gitlck_init(a) (void)0 -# define gitlck_lock(a) (void)0 -# define gitlck_unlock(a) (void)0 -# define gitlck_free(a) (void)0 - -typedef struct { int counter; } git_refcnt; -# define gitrc_init(a) ((a)->counter = 0) -# define gitrc_inc(a) ((a)->counter++) -# define gitrc_dec(a) (--(a)->counter == 0) -# define gitrc_free(a) (void)0 + /* no threads support */ + typedef struct { int dummy; } git_lck; +# define GIT_MUTEX_INIT {} +# define gitlck_init(a) (void)0 +# define gitlck_lock(a) (void)0 +# define gitlck_unlock(a) (void)0 +# define gitlck_free(a) (void)0 + typedef struct { int counter; } git_refcnt; +# define gitrc_init(a) ((a)->counter = 0) +# define gitrc_inc(a) ((a)->counter++) +# define gitrc_dec(a) (--(a)->counter == 0) +# define gitrc_free(a) (void)0 #endif extern int git_online_cpus(void); |