Fix the threading implementation

This commit is contained in:
Vicent Marti 2011-03-17 22:11:35 +02:00
Родитель 12d67a2a4e
Коммит cb3e1334e8
6 изменённых файлов: 70 добавлений и 69 удалений

Просмотреть файл

@ -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
#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")