diff options
author | Vicent Marti <tanoku@gmail.com> | 2011-03-17 22:11:35 +0200 |
---|---|---|
committer | Vicent Marti <tanoku@gmail.com> | 2011-03-17 22:16:54 +0200 |
commit | cb3e1334e8a5c3003fa0419442fc06d45508ac31 (patch) | |
tree | 6be2facd0014fff4a4769b6a6a082c722c03ad87 | |
parent | 12d67a2a4e7f673e6239ac8865dfe8cb6ddcae53 (diff) | |
download | libgit2-threadsafe.tar.gz |
Fix the threading implementationthreadsafe
-rw-r--r-- | src/cache.c | 4 | ||||
-rw-r--r-- | src/cache.h | 2 | ||||
-rw-r--r-- | src/thread-utils.h | 58 | ||||
-rw-r--r-- | src/win32/pthread.c | 50 | ||||
-rw-r--r-- | src/win32/pthread.h | 9 | ||||
-rw-r--r-- | tests/t13-threads.c | 2 |
6 files changed, 63 insertions, 62 deletions
diff --git a/src/cache.c b/src/cache.c index cabd286ab..5a9b8415c 100644 --- a/src/cache.c +++ b/src/cache.c @@ -39,12 +39,12 @@ GIT_INLINE(int) cached_obj_compare(git_cached_obj *obj, const git_oid *oid) GIT_INLINE(void) cached_obj_incref(git_cached_obj *obj) { - obj->refcount++; + git_atomic_inc(&obj->refcount); } GIT_INLINE(void) cached_obj_decref(git_cached_obj *obj, git_cached_obj_freeptr free_obj) { - if (--obj->refcount == 0) + if (git_atomic_dec(&obj->refcount) == 0) free_obj(obj); } diff --git a/src/cache.h b/src/cache.h index a84267b49..9f525e68c 100644 --- a/src/cache.h +++ b/src/cache.h @@ -11,7 +11,7 @@ typedef void (*git_cached_obj_freeptr)(void *); typedef struct { git_oid oid; - unsigned int refcount; + git_atomic refcount; } git_cached_obj; typedef struct { diff --git a/src/thread-utils.h b/src/thread-utils.h index ee26ad251..1cf0e3407 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -1,6 +1,18 @@ #ifndef INCLUDE_thread_utils_h__ #define INCLUDE_thread_utils_h__ + + +/* Common operations even if threading has been disabled */ +typedef struct { + volatile int val; +} git_atomic; + +static inline void git_atomic_set(git_atomic *a, int val) +{ + a->val = val; +} + #ifdef GIT_THREADS #define git_thread pthread_t @@ -16,13 +28,35 @@ #define git_mutex_unlock(a) pthread_mutex_unlock(a) #define git_mutex_free(a) pthread_mutex_destroy(a) -/* Pthreads condition vars */ -#define git_cond pthread_cond_t -#define git_cond_init(c, a) pthread_cond_init(c, a) -#define git_cond_free(c) pthread_cond_destroy(c) -#define git_cond_wait(c, l) pthread_cond_wait(c, l) -#define git_cond_signal(c) pthread_cond_signal(c) -#define git_cond_broadcast(c) pthread_cond_broadcast(c) +/* Pthreads condition vars -- disabled by now */ +#define git_cond unsigned int //pthread_cond_t +#define git_cond_init(c, a) (void)0 //pthread_cond_init(c, a) +#define git_cond_free(c) (void)0 //pthread_cond_destroy(c) +#define git_cond_wait(c, l) (void)0 //pthread_cond_wait(c, l) +#define git_cond_signal(c) (void)0 //pthread_cond_signal(c) +#define git_cond_broadcast(c) (void)0 //pthread_cond_broadcast(c) + +static inline int git_atomic_inc(git_atomic *a) +{ +#ifdef __GNUC__ + return __sync_add_and_fetch(&a->val, 1); +#elif defined(_MSC_VER) + return InterlockedIncrement(&a->val); +#else +# error "Unsupported architecture for atomic operations" +#endif +} + +static inline int git_atomic_dec(git_atomic *a) +{ +#ifdef __GNUC__ + return __sync_sub_and_fetch(&a->val, 1); +#elif defined(_MSC_VER) + return InterlockedDecrement(&a->val); +#else +# error "Unsupported architecture for atomic operations" +#endif +} #else @@ -47,6 +81,16 @@ #define git_cond_signal(c) (void)0 #define git_cond_broadcast(c) (void)0 +static inline int git_atomic_inc(git_atomic *a) +{ + return ++a->val; +} + +static inline int git_atomic_dec(git_atomic *a) +{ + return --a->val; +} + #endif extern int git_online_cpus(void); diff --git a/src/win32/pthread.c b/src/win32/pthread.c index fffff81df..f47364a76 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -36,32 +36,6 @@ int pthread_create(pthread_t *GIT_RESTRICT thread, return *thread ? GIT_SUCCESS : GIT_EOSERR; } -int pthread_cond_signal(pthread_cond_t *cond) -{ - WakeConditionVariable(cond); - return 0; -} - -int pthread_cond_wait(pthread_cond_t *GIT_RESTRICT cond, - pthread_mutex_t *GIT_RESTRICT mutex) -{ - int ret; - ret = SleepConditionVariableCS(cond, mutex, INFINITE); - return -(!ret); -} - -int pthread_mutex_lock(pthread_mutex_t *mutex) -{ - EnterCriticalSection(mutex); - return 0; -} - -int pthread_mutex_unlock(pthread_mutex_t *mutex) -{ - LeaveCriticalSection(mutex); - return 0; -} - int pthread_join(pthread_t thread, void **value_ptr) { int ret; @@ -71,9 +45,11 @@ int pthread_join(pthread_t thread, void **value_ptr) return -(!!ret); } -int pthread_cond_broadcast(pthread_cond_t *cond) +int pthread_mutex_init(pthread_mutex_t *GIT_RESTRICT mutex, + const pthread_mutexattr_t *GIT_RESTRICT GIT_UNUSED(mutexattr)) { - WakeAllConditionVariable(cond); + GIT_UNUSED_ARG(mutexattr); + InitializeCriticalSection(mutex); return 0; } @@ -84,25 +60,15 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex) return -(!ret); } -int pthread_cond_destroy(pthread_cond_t *GIT_UNUSED(cond)) -{ - GIT_UNUSED_ARG(cond); - return 0; -} - -int pthread_cond_init(pthread_cond_t *GIT_RESTRICT cond, - const pthread_condattr_t *GIT_RESTRICT GIT_UNUSED(condattr)) +int pthread_mutex_lock(pthread_mutex_t *mutex) { - GIT_UNUSED_ARG(condattr); - InitializeConditionVariable(cond); + EnterCriticalSection(mutex); return 0; } -int pthread_mutex_init(pthread_mutex_t *GIT_RESTRICT mutex, - const pthread_mutexattr_t *GIT_RESTRICT GIT_UNUSED(mutexattr)) +int pthread_mutex_unlock(pthread_mutex_t *mutex) { - GIT_UNUSED_ARG(mutexattr); - InitializeCriticalSection(mutex); + LeaveCriticalSection(mutex); return 0; } diff --git a/src/win32/pthread.h b/src/win32/pthread.h index ff694e303..10949f1eb 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -40,7 +40,6 @@ typedef int pthread_mutexattr_t; typedef int pthread_condattr_t; typedef int pthread_attr_t; typedef CRITICAL_SECTION pthread_mutex_t; -typedef CONDITION_VARIABLE pthread_cond_t; typedef HANDLE pthread_t; #define PTHREAD_MUTEX_INITIALIZER {(void*)-1}; @@ -56,12 +55,6 @@ int pthread_mutex_destroy(pthread_mutex_t *); int pthread_mutex_lock(pthread_mutex_t *); int pthread_mutex_unlock(pthread_mutex_t *); -int pthread_cond_init(pthread_cond_t *GIT_RESTRICT, const pthread_condattr_t *GIT_RESTRICT); -int pthread_cond_destroy(pthread_cond_t *); -int pthread_cond_broadcast(pthread_cond_t *); -int pthread_cond_signal(pthread_cond_t *); -int pthread_cond_wait(pthread_cond_t *GIT_RESTRICT, pthread_mutex_t *GIT_RESTRICT); - int pthread_num_processors_np(void); -#endif
\ No newline at end of file +#endif diff --git a/tests/t13-threads.c b/tests/t13-threads.c index 7da1076c9..62ca73ac2 100644 --- a/tests/t13-threads.c +++ b/tests/t13-threads.c @@ -37,8 +37,6 @@ void *cache0_thread(void *data) git_cache *cache = (git_cache*)data; unsigned int num; - - } BEGIN_TEST(cache0, "run several threads polling the cache at the same time") |