зеркало из https://github.com/mono/libgit2.git
Fix the threading implementation
This commit is contained in:
Родитель
12d67a2a4e
Коммит
cb3e1334e8
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -36,17 +36,27 @@ int pthread_create(pthread_t *GIT_RESTRICT thread,
|
|||
return *thread ? GIT_SUCCESS : GIT_EOSERR;
|
||||
}
|
||||
|
||||
int pthread_cond_signal(pthread_cond_t *cond)
|
||||
int pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
WakeConditionVariable(cond);
|
||||
int ret;
|
||||
ret = WaitForSingleObject(thread, INFINITE);
|
||||
if (ret && value_ptr)
|
||||
GetExitCodeThread(thread, (void*) value_ptr);
|
||||
return -(!!ret);
|
||||
}
|
||||
|
||||
int pthread_mutex_init(pthread_mutex_t *GIT_RESTRICT mutex,
|
||||
const pthread_mutexattr_t *GIT_RESTRICT GIT_UNUSED(mutexattr))
|
||||
{
|
||||
GIT_UNUSED_ARG(mutexattr);
|
||||
InitializeCriticalSection(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_cond_wait(pthread_cond_t *GIT_RESTRICT cond,
|
||||
pthread_mutex_t *GIT_RESTRICT mutex)
|
||||
int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
int ret;
|
||||
ret = SleepConditionVariableCS(cond, mutex, INFINITE);
|
||||
ret = CloseHandle(mutex);
|
||||
return -(!ret);
|
||||
}
|
||||
|
||||
|
@ -62,50 +72,6 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
int ret;
|
||||
ret = WaitForSingleObject(thread, INFINITE);
|
||||
if (ret && value_ptr)
|
||||
GetExitCodeThread(thread, (void*) value_ptr);
|
||||
return -(!!ret);
|
||||
}
|
||||
|
||||
int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
WakeAllConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
int ret;
|
||||
ret = CloseHandle(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))
|
||||
{
|
||||
GIT_UNUSED_ARG(condattr);
|
||||
InitializeConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_mutex_init(pthread_mutex_t *GIT_RESTRICT mutex,
|
||||
const pthread_mutexattr_t *GIT_RESTRICT GIT_UNUSED(mutexattr))
|
||||
{
|
||||
GIT_UNUSED_ARG(mutexattr);
|
||||
InitializeCriticalSection(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_num_processors_np(void)
|
||||
{
|
||||
DWORD_PTR p, s;
|
||||
|
|
|
@ -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
|
|
@ -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")
|
||||
|
|
Загрузка…
Ссылка в новой задаче