summaryrefslogtreecommitdiff
path: root/src/thread-utils.h
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2011-02-17 21:32:00 +0200
committerVicent Marti <tanoku@gmail.com>2011-02-17 23:20:47 +0200
commit348c7335dd804ea12eabac7106c5f9675a421ba0 (patch)
tree89d918bbc50ee95c44609947d284d49597c157fd /src/thread-utils.h
parent81d0ff1ca5db0ab1a3920c96605899c6161467c8 (diff)
downloadlibgit2-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.h156
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);