From faebc1c6eccacd9659d21f848a9e2be55de671c7 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 17:44:04 +0200 Subject: [PATCH 1/9] threads: split up OS-dependent thread code --- src/pack-objects.c | 2 +- src/thread-utils.h | 13 ++----------- src/unix/pthread.h | 20 ++++++++++++++++++++ src/win32/pthread.c | 13 +++++-------- src/win32/pthread.h | 22 +++------------------- tests/object/cache.c | 4 ++-- tests/threads/refdb.c | 6 +++--- tests/threads/thread_helpers.c | 2 +- 8 files changed, 37 insertions(+), 45 deletions(-) create mode 100644 src/unix/pthread.h diff --git a/src/pack-objects.c b/src/pack-objects.c index 11e13f7d4..29231e028 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1186,7 +1186,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list, git_mutex_init(&p[i].mutex); git_cond_init(&p[i].cond); - ret = git_thread_create(&p[i].thread, NULL, + ret = git_thread_create(&p[i].thread, threaded_find_deltas, &p[i]); if (ret) { giterr_set(GITERR_THREAD, "unable to create thread"); diff --git a/src/thread-utils.h b/src/thread-utils.h index 14c8a41ff..11c026f33 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -41,16 +41,7 @@ typedef git_atomic git_atomic_ssize; #ifdef GIT_THREADS #if !defined(GIT_WIN32) - -typedef struct { - pthread_t thread; -} git_thread; - -#define git_thread_create(git_thread_ptr, attr, start_routine, arg) \ - pthread_create(&(git_thread_ptr)->thread, attr, start_routine, arg) -#define git_thread_join(git_thread_ptr, status) \ - pthread_join((git_thread_ptr)->thread, status) - +# include "unix/pthread.h" #endif /* Pthreads Mutex */ @@ -178,7 +169,7 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend) #else #define git_thread unsigned int -#define git_thread_create(thread, attr, start_routine, arg) 0 +#define git_thread_create(thread, start_routine, arg) 0 #define git_thread_join(id, status) (void)0 /* Pthreads Mutex */ diff --git a/src/unix/pthread.h b/src/unix/pthread.h new file mode 100644 index 000000000..87384a4ab --- /dev/null +++ b/src/unix/pthread.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) the libgit2 contributors. All rights reserved. + * + * This file is part of libgit2, distributed under the GNU GPL v2 with + * a Linking Exception. For full terms see the included COPYING file. + */ + +#ifndef INCLUDE_unix_pthread_h__ +#define INCLUDE_unix_pthread_h__ + +typedef struct { + pthread_t thread; +} git_thread; + +#define git_thread_create(git_thread_ptr, start_routine, arg) \ + pthread_create(&(git_thread_ptr)->thread, NULL, start_routine, arg) +#define git_thread_join(git_thread_ptr, status) \ + pthread_join((git_thread_ptr)->thread, status) + +#endif /* INCLUDE_unix_pthread_h__ */ diff --git a/src/win32/pthread.c b/src/win32/pthread.c index a1cc18932..d8ed4bb1b 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -16,7 +16,7 @@ * void pointer. This requires the indirection. */ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) { - git_win32_thread *thread = lpParameter; + git_thread *thread = lpParameter; thread->result = thread->proc(thread->param); @@ -25,14 +25,11 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) return CLEAN_THREAD_EXIT; } -int git_win32__thread_create( - git_win32_thread *GIT_RESTRICT thread, - const pthread_attr_t *GIT_RESTRICT attr, +int git_thread_create( + git_thread *GIT_RESTRICT thread, void *(*start_routine)(void*), void *GIT_RESTRICT arg) { - GIT_UNUSED(attr); - thread->result = NULL; thread->param = arg; thread->proc = start_routine; @@ -42,8 +39,8 @@ int git_win32__thread_create( return thread->thread ? 0 : -1; } -int git_win32__thread_join( - git_win32_thread *thread, +int git_thread_join( + git_thread *thread, void **value_ptr) { DWORD exit; diff --git a/src/win32/pthread.h b/src/win32/pthread.h index e4826ca7f..fa99b01d6 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -21,7 +21,7 @@ typedef struct { void *(*proc)(void *); void *param; void *result; -} git_win32_thread; +} git_thread; typedef int pthread_mutexattr_t; typedef int pthread_condattr_t; @@ -42,26 +42,10 @@ typedef struct { #define PTHREAD_MUTEX_INITIALIZER {(void*)-1} -int git_win32__thread_create( - git_win32_thread *GIT_RESTRICT, - const pthread_attr_t *GIT_RESTRICT, +int git_thread_create(git_thread *GIT_RESTRICT, void *(*) (void *), void *GIT_RESTRICT); - -int git_win32__thread_join( - git_win32_thread *, - void **); - -#ifdef GIT_THREADS - -typedef git_win32_thread git_thread; - -#define git_thread_create(git_thread_ptr, attr, start_routine, arg) \ - git_win32__thread_create(git_thread_ptr, attr, start_routine, arg) -#define git_thread_join(git_thread_ptr, status) \ - git_win32__thread_join(git_thread_ptr, status) - -#endif +int git_thread_join(git_thread *, void **); int pthread_mutex_init( pthread_mutex_t *GIT_RESTRICT mutex, diff --git a/tests/object/cache.c b/tests/object/cache.c index bdf12da7a..680f23630 100644 --- a/tests/object/cache.c +++ b/tests/object/cache.c @@ -220,7 +220,7 @@ void test_object_cache__threadmania(void) fn = (th & 1) ? cache_parsed : cache_raw; #ifdef GIT_THREADS - cl_git_pass(git_thread_create(&t[th], NULL, fn, data)); + cl_git_pass(git_thread_create(&t[th], fn, data)); #else cl_assert(fn(data) == data); git__free(data); @@ -267,7 +267,7 @@ void test_object_cache__fast_thread_rush(void) data[th] = th; #ifdef GIT_THREADS cl_git_pass( - git_thread_create(&t[th], NULL, cache_quick, &data[th])); + git_thread_create(&t[th], cache_quick, &data[th])); #else cl_assert(cache_quick(&data[th]) == &data[th]); #endif diff --git a/tests/threads/refdb.c b/tests/threads/refdb.c index 6589e3922..f869bcb44 100644 --- a/tests/threads/refdb.c +++ b/tests/threads/refdb.c @@ -75,7 +75,7 @@ void test_threads_refdb__iterator(void) for (t = 0; t < THREADS; ++t) { id[t] = t; #ifdef GIT_THREADS - cl_git_pass(git_thread_create(&th[t], NULL, iterate_refs, &id[t])); + cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t])); #else th[t] = t; iterate_refs(&id[t]); @@ -196,7 +196,7 @@ void test_threads_refdb__edit_while_iterate(void) * for now by just running on a single thread... */ /* #ifdef GIT_THREADS */ -/* cl_git_pass(git_thread_create(&th[t], NULL, fn, &id[t])); */ +/* cl_git_pass(git_thread_create(&th[t], fn, &id[t])); */ /* #else */ fn(&id[t]); /* #endif */ @@ -211,7 +211,7 @@ void test_threads_refdb__edit_while_iterate(void) for (t = 0; t < THREADS; ++t) { id[t] = t; - cl_git_pass(git_thread_create(&th[t], NULL, iterate_refs, &id[t])); + cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t])); } for (t = 0; t < THREADS; ++t) { diff --git a/tests/threads/thread_helpers.c b/tests/threads/thread_helpers.c index 760a7bd33..54bf6097d 100644 --- a/tests/threads/thread_helpers.c +++ b/tests/threads/thread_helpers.c @@ -24,7 +24,7 @@ void run_in_parallel( for (t = 0; t < threads; ++t) { id[t] = t; #ifdef GIT_THREADS - cl_git_pass(git_thread_create(&th[t], NULL, func, &id[t])); + cl_git_pass(git_thread_create(&th[t], func, &id[t])); #else cl_assert(func(&id[t]) == &id[t]); #endif From 1c13540510c054ca0f046cbadcfa72f01f6ace57 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 17:07:14 +0200 Subject: [PATCH 2/9] threads: split up OS-dependent mutex code --- src/thread-utils.h | 11 +++-------- src/unix/pthread.h | 7 +++++++ src/win32/pthread.c | 17 +++++++---------- src/win32/pthread.h | 14 ++++++-------- 4 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/thread-utils.h b/src/thread-utils.h index 11c026f33..29b5d1eee 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -40,17 +40,12 @@ typedef git_atomic git_atomic_ssize; #ifdef GIT_THREADS -#if !defined(GIT_WIN32) +#ifdef GIT_WIN32 +# include "win32/pthread.h" +#else # include "unix/pthread.h" #endif -/* Pthreads Mutex */ -#define git_mutex pthread_mutex_t -#define git_mutex_init(a) pthread_mutex_init(a, NULL) -#define git_mutex_lock(a) pthread_mutex_lock(a) -#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) pthread_cond_init(c, NULL) diff --git a/src/unix/pthread.h b/src/unix/pthread.h index 87384a4ab..7487cb5c5 100644 --- a/src/unix/pthread.h +++ b/src/unix/pthread.h @@ -17,4 +17,11 @@ typedef struct { #define git_thread_join(git_thread_ptr, status) \ pthread_join((git_thread_ptr)->thread, status) +/* Git Mutex */ +#define git_mutex pthread_mutex_t +#define git_mutex_init(a) pthread_mutex_init(a, NULL) +#define git_mutex_lock(a) pthread_mutex_lock(a) +#define git_mutex_unlock(a) pthread_mutex_unlock(a) +#define git_mutex_free(a) pthread_mutex_destroy(a) + #endif /* INCLUDE_unix_pthread_h__ */ diff --git a/src/win32/pthread.c b/src/win32/pthread.c index d8ed4bb1b..142c1afdf 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -67,28 +67,25 @@ int git_thread_join( return 0; } -int pthread_mutex_init( - pthread_mutex_t *GIT_RESTRICT mutex, - const pthread_mutexattr_t *GIT_RESTRICT mutexattr) +int git_mutex_init(git_mutex *GIT_RESTRICT mutex) { - GIT_UNUSED(mutexattr); InitializeCriticalSection(mutex); return 0; } -int pthread_mutex_destroy(pthread_mutex_t *mutex) +int git_mutex_free(git_mutex *mutex) { DeleteCriticalSection(mutex); return 0; } -int pthread_mutex_lock(pthread_mutex_t *mutex) +int git_mutex_lock(git_mutex *mutex) { EnterCriticalSection(mutex); return 0; } -int pthread_mutex_unlock(pthread_mutex_t *mutex) +int git_mutex_unlock(git_mutex *mutex) { LeaveCriticalSection(mutex); return 0; @@ -124,7 +121,7 @@ int pthread_cond_destroy(pthread_cond_t *cond) return 0; } -int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) +int pthread_cond_wait(pthread_cond_t *cond, git_mutex *mutex) { int error; DWORD wait_result; @@ -133,7 +130,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) return EINVAL; /* The caller must be holding the mutex. */ - error = pthread_mutex_unlock(mutex); + error = git_mutex_unlock(mutex); if (error) return error; @@ -142,7 +139,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) assert(WAIT_OBJECT_0 == wait_result); GIT_UNUSED(wait_result); - return pthread_mutex_lock(mutex); + return git_mutex_lock(mutex); } int pthread_cond_signal(pthread_cond_t *cond) diff --git a/src/win32/pthread.h b/src/win32/pthread.h index fa99b01d6..3ff95e89b 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -28,7 +28,7 @@ typedef int pthread_condattr_t; typedef int pthread_attr_t; typedef int pthread_rwlockattr_t; -typedef CRITICAL_SECTION pthread_mutex_t; +typedef CRITICAL_SECTION git_mutex; typedef HANDLE pthread_cond_t; typedef struct { void *Ptr; } GIT_SRWLOCK; @@ -47,16 +47,14 @@ int git_thread_create(git_thread *GIT_RESTRICT, void *GIT_RESTRICT); int git_thread_join(git_thread *, void **); -int pthread_mutex_init( - pthread_mutex_t *GIT_RESTRICT mutex, - const pthread_mutexattr_t *GIT_RESTRICT mutexattr); -int pthread_mutex_destroy(pthread_mutex_t *); -int pthread_mutex_lock(pthread_mutex_t *); -int pthread_mutex_unlock(pthread_mutex_t *); +int git_mutex_init(git_mutex *GIT_RESTRICT mutex); +int git_mutex_free(git_mutex *); +int git_mutex_lock(git_mutex *); +int git_mutex_unlock(git_mutex *); int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); int pthread_cond_destroy(pthread_cond_t *); -int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); +int pthread_cond_wait(pthread_cond_t *, git_mutex *); int pthread_cond_signal(pthread_cond_t *); /* pthread_cond_broadcast is not supported on Win32 yet. */ From 20d078dff166592b853f186096148c9b32262454 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 19:48:19 +0200 Subject: [PATCH 3/9] threads: remove unused function pthread_cond_broadcast --- src/thread-utils.h | 1 - src/win32/pthread.c | 4 ---- src/win32/pthread.h | 1 - 3 files changed, 6 deletions(-) diff --git a/src/thread-utils.h b/src/thread-utils.h index 29b5d1eee..5073c2a8b 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -52,7 +52,6 @@ typedef git_atomic git_atomic_ssize; #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) /* Pthread (-ish) rwlock * diff --git a/src/win32/pthread.c b/src/win32/pthread.c index 142c1afdf..abf047025 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -156,10 +156,6 @@ int pthread_cond_signal(pthread_cond_t *cond) return 0; } -/* pthread_cond_broadcast is not implemented because doing so with just - * Win32 events is quite complicated, and no caller in libgit2 uses it - * yet. - */ int pthread_num_processors_np(void) { DWORD_PTR p, s; diff --git a/src/win32/pthread.h b/src/win32/pthread.h index 3ff95e89b..9d314c89e 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -56,7 +56,6 @@ int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); int pthread_cond_destroy(pthread_cond_t *); int pthread_cond_wait(pthread_cond_t *, git_mutex *); int pthread_cond_signal(pthread_cond_t *); -/* pthread_cond_broadcast is not supported on Win32 yet. */ int pthread_num_processors_np(void); From 139bffa074c7a74af92ee9c97d1e876acfc8dcd3 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 17:20:13 +0200 Subject: [PATCH 4/9] threads: split up OS-dependent thread-condition code --- src/thread-utils.h | 7 ------- src/unix/pthread.h | 8 ++++++++ src/win32/pthread.c | 12 ++++-------- src/win32/pthread.h | 10 +++++----- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/thread-utils.h b/src/thread-utils.h index 5073c2a8b..1eb51de25 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -46,13 +46,6 @@ typedef git_atomic git_atomic_ssize; # include "unix/pthread.h" #endif -/* Pthreads condition vars */ -#define git_cond pthread_cond_t -#define git_cond_init(c) pthread_cond_init(c, NULL) -#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) - /* Pthread (-ish) rwlock * * This differs from normal pthreads rwlocks in two ways: diff --git a/src/unix/pthread.h b/src/unix/pthread.h index 7487cb5c5..0cba59b9c 100644 --- a/src/unix/pthread.h +++ b/src/unix/pthread.h @@ -24,4 +24,12 @@ typedef struct { #define git_mutex_unlock(a) pthread_mutex_unlock(a) #define git_mutex_free(a) pthread_mutex_destroy(a) +/* Git condition vars */ +#define git_cond pthread_cond_t +#define git_cond_init(c) pthread_cond_init(c, NULL) +#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) + #endif /* INCLUDE_unix_pthread_h__ */ diff --git a/src/win32/pthread.c b/src/win32/pthread.c index abf047025..9ce062ab8 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -91,12 +91,8 @@ int git_mutex_unlock(git_mutex *mutex) return 0; } -int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) +int git_cond_init(git_cond *cond) { - /* We don't support non-default attributes. */ - if (attr) - return EINVAL; - /* This is an auto-reset event. */ *cond = CreateEventW(NULL, FALSE, FALSE, NULL); assert(*cond); @@ -106,7 +102,7 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) return *cond ? 0 : ENOMEM; } -int pthread_cond_destroy(pthread_cond_t *cond) +int git_cond_free(git_cond *cond) { BOOL closed; @@ -121,7 +117,7 @@ int pthread_cond_destroy(pthread_cond_t *cond) return 0; } -int pthread_cond_wait(pthread_cond_t *cond, git_mutex *mutex) +int git_cond_wait(git_cond *cond, git_mutex *mutex) { int error; DWORD wait_result; @@ -142,7 +138,7 @@ int pthread_cond_wait(pthread_cond_t *cond, git_mutex *mutex) return git_mutex_lock(mutex); } -int pthread_cond_signal(pthread_cond_t *cond) +int git_cond_signal(git_cond *cond) { BOOL signaled; diff --git a/src/win32/pthread.h b/src/win32/pthread.h index 9d314c89e..35cb810e7 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -29,7 +29,7 @@ typedef int pthread_attr_t; typedef int pthread_rwlockattr_t; typedef CRITICAL_SECTION git_mutex; -typedef HANDLE pthread_cond_t; +typedef HANDLE git_cond; typedef struct { void *Ptr; } GIT_SRWLOCK; @@ -52,10 +52,10 @@ int git_mutex_free(git_mutex *); int git_mutex_lock(git_mutex *); int git_mutex_unlock(git_mutex *); -int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); -int pthread_cond_destroy(pthread_cond_t *); -int pthread_cond_wait(pthread_cond_t *, git_mutex *); -int pthread_cond_signal(pthread_cond_t *); +int git_cond_init(git_cond *); +int git_cond_free(git_cond *); +int git_cond_wait(git_cond *, git_mutex *); +int git_cond_signal(git_cond *); int pthread_num_processors_np(void); From 6551004fb19453f424337b5b7a5fed6becb3b746 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 17:49:47 +0200 Subject: [PATCH 5/9] threads: split up OS-dependent rwlock code --- src/thread-utils.h | 24 ------------------------ src/unix/pthread.h | 18 ++++++++++++++++++ src/win32/pthread.c | 16 ++++++---------- src/win32/pthread.h | 16 +++++++--------- 4 files changed, 31 insertions(+), 43 deletions(-) diff --git a/src/thread-utils.h b/src/thread-utils.h index 1eb51de25..f75e44087 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -46,30 +46,6 @@ typedef git_atomic git_atomic_ssize; # include "unix/pthread.h" #endif -/* Pthread (-ish) rwlock - * - * This differs from normal pthreads rwlocks in two ways: - * 1. Separate APIs for releasing read locks and write locks (as - * opposed to the pure POSIX API which only has one unlock fn) - * 2. You should not use recursive read locks (i.e. grabbing a read - * lock in a thread that already holds a read lock) because the - * Windows implementation doesn't support it - */ -#define git_rwlock pthread_rwlock_t -#define git_rwlock_init(a) pthread_rwlock_init(a, NULL) -#define git_rwlock_rdlock(a) pthread_rwlock_rdlock(a) -#define git_rwlock_rdunlock(a) pthread_rwlock_rdunlock(a) -#define git_rwlock_wrlock(a) pthread_rwlock_wrlock(a) -#define git_rwlock_wrunlock(a) pthread_rwlock_wrunlock(a) -#define git_rwlock_free(a) pthread_rwlock_destroy(a) -#define GIT_RWLOCK_STATIC_INIT PTHREAD_RWLOCK_INITIALIZER - -#ifndef GIT_WIN32 -#define pthread_rwlock_rdunlock pthread_rwlock_unlock -#define pthread_rwlock_wrunlock pthread_rwlock_unlock -#endif - - GIT_INLINE(void) git_atomic_set(git_atomic *a, int val) { #if defined(GIT_WIN32) diff --git a/src/unix/pthread.h b/src/unix/pthread.h index 0cba59b9c..773ce22f9 100644 --- a/src/unix/pthread.h +++ b/src/unix/pthread.h @@ -32,4 +32,22 @@ typedef struct { #define git_cond_signal(c) pthread_cond_signal(c) #define git_cond_broadcast(c) pthread_cond_broadcast(c) +/* Pthread (-ish) rwlock + * + * This differs from normal pthreads rwlocks in two ways: + * 1. Separate APIs for releasing read locks and write locks (as + * opposed to the pure POSIX API which only has one unlock fn) + * 2. You should not use recursive read locks (i.e. grabbing a read + * lock in a thread that already holds a read lock) because the + * Windows implementation doesn't support it + */ +#define git_rwlock pthread_rwlock_t +#define git_rwlock_init(a) pthread_rwlock_init(a, NULL) +#define git_rwlock_rdlock(a) pthread_rwlock_rdlock(a) +#define git_rwlock_rdunlock(a) pthread_rwlock_unlock(a) +#define git_rwlock_wrlock(a) pthread_rwlock_wrlock(a) +#define git_rwlock_wrunlock(a) pthread_rwlock_unlock(a) +#define git_rwlock_free(a) pthread_rwlock_destroy(a) +#define GIT_RWLOCK_STATIC_INIT PTHREAD_RWLOCK_INITIALIZER + #endif /* INCLUDE_unix_pthread_h__ */ diff --git a/src/win32/pthread.c b/src/win32/pthread.c index 9ce062ab8..62a691dba 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -172,12 +172,8 @@ static win32_srwlock_fn win32_srwlock_release_shared; static win32_srwlock_fn win32_srwlock_acquire_exclusive; static win32_srwlock_fn win32_srwlock_release_exclusive; -int pthread_rwlock_init( - pthread_rwlock_t *GIT_RESTRICT lock, - const pthread_rwlockattr_t *GIT_RESTRICT attr) +int git_rwlock_init(git_rwlock *GIT_RESTRICT lock) { - GIT_UNUSED(attr); - if (win32_srwlock_initialize) win32_srwlock_initialize(&lock->native.srwl); else @@ -186,7 +182,7 @@ int pthread_rwlock_init( return 0; } -int pthread_rwlock_rdlock(pthread_rwlock_t *lock) +int git_rwlock_rdlock(git_rwlock *lock) { if (win32_srwlock_acquire_shared) win32_srwlock_acquire_shared(&lock->native.srwl); @@ -196,7 +192,7 @@ int pthread_rwlock_rdlock(pthread_rwlock_t *lock) return 0; } -int pthread_rwlock_rdunlock(pthread_rwlock_t *lock) +int git_rwlock_rdunlock(git_rwlock *lock) { if (win32_srwlock_release_shared) win32_srwlock_release_shared(&lock->native.srwl); @@ -206,7 +202,7 @@ int pthread_rwlock_rdunlock(pthread_rwlock_t *lock) return 0; } -int pthread_rwlock_wrlock(pthread_rwlock_t *lock) +int git_rwlock_wrlock(git_rwlock *lock) { if (win32_srwlock_acquire_exclusive) win32_srwlock_acquire_exclusive(&lock->native.srwl); @@ -216,7 +212,7 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *lock) return 0; } -int pthread_rwlock_wrunlock(pthread_rwlock_t *lock) +int git_rwlock_wrunlock(git_rwlock *lock) { if (win32_srwlock_release_exclusive) win32_srwlock_release_exclusive(&lock->native.srwl); @@ -226,7 +222,7 @@ int pthread_rwlock_wrunlock(pthread_rwlock_t *lock) return 0; } -int pthread_rwlock_destroy(pthread_rwlock_t *lock) +int git_rwlock_free(git_rwlock *lock) { if (!win32_srwlock_initialize) DeleteCriticalSection(&lock->native.csec); diff --git a/src/win32/pthread.h b/src/win32/pthread.h index 35cb810e7..ef9285500 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -38,7 +38,7 @@ typedef struct { GIT_SRWLOCK srwl; CRITICAL_SECTION csec; } native; -} pthread_rwlock_t; +} git_rwlock; #define PTHREAD_MUTEX_INITIALIZER {(void*)-1} @@ -59,14 +59,12 @@ int git_cond_signal(git_cond *); int pthread_num_processors_np(void); -int pthread_rwlock_init( - pthread_rwlock_t *GIT_RESTRICT lock, - const pthread_rwlockattr_t *GIT_RESTRICT attr); -int pthread_rwlock_rdlock(pthread_rwlock_t *); -int pthread_rwlock_rdunlock(pthread_rwlock_t *); -int pthread_rwlock_wrlock(pthread_rwlock_t *); -int pthread_rwlock_wrunlock(pthread_rwlock_t *); -int pthread_rwlock_destroy(pthread_rwlock_t *); +int git_rwlock_init(git_rwlock *GIT_RESTRICT lock); +int git_rwlock_rdlock(git_rwlock *); +int git_rwlock_rdunlock(git_rwlock *); +int git_rwlock_wrlock(git_rwlock *); +int git_rwlock_wrunlock(git_rwlock *); +int git_rwlock_free(git_rwlock *); extern int win32_pthread_initialize(void); From 4f10c1e65c14a2c8b11577d2fd25b5c4f6912a85 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 19:40:45 +0200 Subject: [PATCH 6/9] threads: remove unused function pthread_num_processors_np The function pthread_num_processors_np is currently unused and superseded by the function `git_online_cpus`. Remove the function. --- src/win32/pthread.c | 11 ----------- src/win32/pthread.h | 2 -- 2 files changed, 13 deletions(-) diff --git a/src/win32/pthread.c b/src/win32/pthread.c index 62a691dba..80329b2b0 100644 --- a/src/win32/pthread.c +++ b/src/win32/pthread.c @@ -152,17 +152,6 @@ int git_cond_signal(git_cond *cond) return 0; } -int pthread_num_processors_np(void) -{ - DWORD_PTR p, s; - int n = 0; - - if (GetProcessAffinityMask(GetCurrentProcess(), &p, &s)) - for (; p; p >>= 1) - n += p&1; - - return n ? n : 1; -} typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *); diff --git a/src/win32/pthread.h b/src/win32/pthread.h index ef9285500..821bb64ee 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -57,8 +57,6 @@ int git_cond_free(git_cond *); int git_cond_wait(git_cond *, git_mutex *); int git_cond_signal(git_cond *); -int pthread_num_processors_np(void); - int git_rwlock_init(git_rwlock *GIT_RESTRICT lock); int git_rwlock_rdlock(git_rwlock *); int git_rwlock_rdunlock(git_rwlock *); From a342e870fcce7f524b54e5671cab4b0702e7540f Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 18:28:00 +0200 Subject: [PATCH 7/9] threads: remove now-useless typedefs --- src/win32/pthread.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/win32/pthread.h b/src/win32/pthread.h index 821bb64ee..977d2dfab 100644 --- a/src/win32/pthread.h +++ b/src/win32/pthread.h @@ -23,11 +23,6 @@ typedef struct { void *result; } git_thread; -typedef int pthread_mutexattr_t; -typedef int pthread_condattr_t; -typedef int pthread_attr_t; -typedef int pthread_rwlockattr_t; - typedef CRITICAL_SECTION git_mutex; typedef HANDLE git_cond; @@ -40,8 +35,6 @@ typedef struct { } native; } git_rwlock; -#define PTHREAD_MUTEX_INITIALIZER {(void*)-1} - int git_thread_create(git_thread *GIT_RESTRICT, void *(*) (void *), void *GIT_RESTRICT); From 8aaa9fb6238336b313766d7bd9c20cff07cb840b Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 18:21:42 +0200 Subject: [PATCH 8/9] win32: rename pthread.{c,h} to thread.{c,h} The old pthread-file did re-implement the pthreads API with exact symbol matching. As the thread-abstraction has now been split up between Unix- and Windows-specific files within the `git_` namespace to avoid symbol-clashes between libgit2 and pthreads, the rewritten wrappers have nothing to do with pthreads anymore. Rename the Windows-specific pthread-files to honor this change. --- src/common.h | 2 +- src/thread-utils.h | 2 +- src/win32/precompiled.h | 2 +- src/win32/{pthread.c => thread.c} | 2 +- src/win32/{pthread.h => thread.h} | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) rename src/win32/{pthread.c => thread.c} (99%) rename src/win32/{pthread.h => thread.h} (92%) diff --git a/src/common.h b/src/common.h index 9abd605cb..51fb9186e 100644 --- a/src/common.h +++ b/src/common.h @@ -45,7 +45,7 @@ # include "win32/error.h" # include "win32/version.h" # ifdef GIT_THREADS -# include "win32/pthread.h" +# include "win32/thread.h" # endif # if defined(GIT_MSVC_CRTDBG) # include "win32/w32_stack.h" diff --git a/src/thread-utils.h b/src/thread-utils.h index f75e44087..f0161989f 100644 --- a/src/thread-utils.h +++ b/src/thread-utils.h @@ -41,7 +41,7 @@ typedef git_atomic git_atomic_ssize; #ifdef GIT_THREADS #ifdef GIT_WIN32 -# include "win32/pthread.h" +# include "win32/thread.h" #else # include "unix/pthread.h" #endif diff --git a/src/win32/precompiled.h b/src/win32/precompiled.h index 33ce106d3..10ca0b80c 100644 --- a/src/win32/precompiled.h +++ b/src/win32/precompiled.h @@ -16,7 +16,7 @@ #include #include #ifdef GIT_THREADS - #include "win32/pthread.h" + #include "win32/thread.h" #endif #include "git2.h" diff --git a/src/win32/pthread.c b/src/win32/thread.c similarity index 99% rename from src/win32/pthread.c rename to src/win32/thread.c index 80329b2b0..8222c65fe 100644 --- a/src/win32/pthread.c +++ b/src/win32/thread.c @@ -5,7 +5,7 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#include "pthread.h" +#include "thread.h" #include "../global.h" #define CLEAN_THREAD_EXIT 0x6F012842 diff --git a/src/win32/pthread.h b/src/win32/thread.h similarity index 92% rename from src/win32/pthread.h rename to src/win32/thread.h index 977d2dfab..f5dd41ba3 100644 --- a/src/win32/pthread.h +++ b/src/win32/thread.h @@ -5,8 +5,8 @@ * a Linking Exception. For full terms see the included COPYING file. */ -#ifndef GIT_PTHREAD_H -#define GIT_PTHREAD_H +#ifndef INCLUDE_win32_thread_h__ +#define INCLUDE_win32_thread_h__ #include "../common.h" @@ -59,4 +59,4 @@ int git_rwlock_free(git_rwlock *); extern int win32_pthread_initialize(void); -#endif +#endif /* INCLUDE_win32_thread_h__ */ From aab266c93256fbf89a000778b454c5d60bae43a9 Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Mon, 20 Jun 2016 20:07:33 +0200 Subject: [PATCH 9/9] threads: add platform-independent thread initialization function --- src/global.c | 2 +- src/unix/pthread.h | 1 + src/win32/thread.c | 57 +++++++++++++++++++++++----------------------- src/win32/thread.h | 4 ++-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/global.c b/src/global.c index 32e497507..eee0aea57 100644 --- a/src/global.c +++ b/src/global.c @@ -134,7 +134,7 @@ static int synchronized_threads_init(void) _tls_index = TlsAlloc(); - win32_pthread_initialize(); + git_threads_init(); if (git_mutex_init(&git__mwindow_mutex)) return -1; diff --git a/src/unix/pthread.h b/src/unix/pthread.h index 773ce22f9..0f3f17927 100644 --- a/src/unix/pthread.h +++ b/src/unix/pthread.h @@ -12,6 +12,7 @@ typedef struct { pthread_t thread; } git_thread; +#define git_threads_init() (void)0 #define git_thread_create(git_thread_ptr, start_routine, arg) \ pthread_create(&(git_thread_ptr)->thread, NULL, start_routine, arg) #define git_thread_join(git_thread_ptr, status) \ diff --git a/src/win32/thread.c b/src/win32/thread.c index 8222c65fe..80d56ce5d 100644 --- a/src/win32/thread.c +++ b/src/win32/thread.c @@ -10,6 +10,14 @@ #define CLEAN_THREAD_EXIT 0x6F012842 +typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *); + +static win32_srwlock_fn win32_srwlock_initialize; +static win32_srwlock_fn win32_srwlock_acquire_shared; +static win32_srwlock_fn win32_srwlock_release_shared; +static win32_srwlock_fn win32_srwlock_acquire_exclusive; +static win32_srwlock_fn win32_srwlock_release_exclusive; + /* The thread procedure stub used to invoke the caller's procedure * and capture the return value for later collection. Windows will * only hold a DWORD, but we need to be able to store an entire @@ -25,6 +33,26 @@ static DWORD WINAPI git_win32__threadproc(LPVOID lpParameter) return CLEAN_THREAD_EXIT; } +int git_threads_init(void) +{ + HMODULE hModule = GetModuleHandleW(L"kernel32"); + + if (hModule) { + win32_srwlock_initialize = (win32_srwlock_fn) + GetProcAddress(hModule, "InitializeSRWLock"); + win32_srwlock_acquire_shared = (win32_srwlock_fn) + GetProcAddress(hModule, "AcquireSRWLockShared"); + win32_srwlock_release_shared = (win32_srwlock_fn) + GetProcAddress(hModule, "ReleaseSRWLockShared"); + win32_srwlock_acquire_exclusive = (win32_srwlock_fn) + GetProcAddress(hModule, "AcquireSRWLockExclusive"); + win32_srwlock_release_exclusive = (win32_srwlock_fn) + GetProcAddress(hModule, "ReleaseSRWLockExclusive"); + } + + return 0; +} + int git_thread_create( git_thread *GIT_RESTRICT thread, void *(*start_routine)(void*), @@ -152,15 +180,6 @@ int git_cond_signal(git_cond *cond) return 0; } - -typedef void (WINAPI *win32_srwlock_fn)(GIT_SRWLOCK *); - -static win32_srwlock_fn win32_srwlock_initialize; -static win32_srwlock_fn win32_srwlock_acquire_shared; -static win32_srwlock_fn win32_srwlock_release_shared; -static win32_srwlock_fn win32_srwlock_acquire_exclusive; -static win32_srwlock_fn win32_srwlock_release_exclusive; - int git_rwlock_init(git_rwlock *GIT_RESTRICT lock) { if (win32_srwlock_initialize) @@ -218,23 +237,3 @@ int git_rwlock_free(git_rwlock *lock) git__memzero(lock, sizeof(*lock)); return 0; } - -int win32_pthread_initialize(void) -{ - HMODULE hModule = GetModuleHandleW(L"kernel32"); - - if (hModule) { - win32_srwlock_initialize = (win32_srwlock_fn) - GetProcAddress(hModule, "InitializeSRWLock"); - win32_srwlock_acquire_shared = (win32_srwlock_fn) - GetProcAddress(hModule, "AcquireSRWLockShared"); - win32_srwlock_release_shared = (win32_srwlock_fn) - GetProcAddress(hModule, "ReleaseSRWLockShared"); - win32_srwlock_acquire_exclusive = (win32_srwlock_fn) - GetProcAddress(hModule, "AcquireSRWLockExclusive"); - win32_srwlock_release_exclusive = (win32_srwlock_fn) - GetProcAddress(hModule, "ReleaseSRWLockExclusive"); - } - - return 0; -} diff --git a/src/win32/thread.h b/src/win32/thread.h index f5dd41ba3..0d01822a6 100644 --- a/src/win32/thread.h +++ b/src/win32/thread.h @@ -35,6 +35,8 @@ typedef struct { } native; } git_rwlock; +int git_threads_init(void); + int git_thread_create(git_thread *GIT_RESTRICT, void *(*) (void *), void *GIT_RESTRICT); @@ -57,6 +59,4 @@ int git_rwlock_wrlock(git_rwlock *); int git_rwlock_wrunlock(git_rwlock *); int git_rwlock_free(git_rwlock *); -extern int win32_pthread_initialize(void); - #endif /* INCLUDE_win32_thread_h__ */