]> git.proxmox.com Git - libgit2.git/blame - src/thread-utils.h
Update branching information in d/gbp.conf
[libgit2.git] / src / thread-utils.h
CommitLineData
bb742ede 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
bb742ede
VM
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
36f0f61f
AE
7#ifndef INCLUDE_thread_utils_h__
8#define INCLUDE_thread_utils_h__
9
aa5ea47f
ET
10#if defined(__GNUC__) && defined(GIT_THREADS)
11# if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1))
12# error Atomic primitives do not exist on this version of gcc; configure libgit2 with -DTHREADSAFE=OFF
13# endif
14#endif
15
bb3de0c4
VM
16/* Common operations even if threading has been disabled */
17typedef struct {
7a6f51de 18#if defined(GIT_WIN32)
b932ef5b
VM
19 volatile long val;
20#else
bb3de0c4 21 volatile int val;
b932ef5b 22#endif
bb3de0c4
VM
23} git_atomic;
24
eb63fda2
ET
25#ifdef GIT_ARCH_64
26
f9774eea
VM
27typedef struct {
28#if defined(GIT_WIN32)
29 __int64 val;
30#else
31 int64_t val;
32#endif
33} git_atomic64;
34
eb63fda2
ET
35typedef git_atomic64 git_atomic_ssize;
36
37#define git_atomic_ssize_add git_atomic64_add
38
39#else
40
41typedef git_atomic git_atomic_ssize;
42
43#define git_atomic_ssize_add git_atomic_add
44
45#endif
46
bb3de0c4
VM
47#ifdef GIT_THREADS
48
1c135405 49#ifdef GIT_WIN32
8aaa9fb6 50# include "win32/thread.h"
1c135405 51#else
faebc1c6 52# include "unix/pthread.h"
fb591767 53#endif
bbcc7ffc 54
814de0bc
RB
55GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
56{
57#if defined(GIT_WIN32)
58 InterlockedExchange(&a->val, (LONG)val);
59#elif defined(__GNUC__)
60 __sync_lock_test_and_set(&a->val, val);
61#else
62# error "Unsupported architecture for atomic operations"
63#endif
64}
65
72a3fe42 66GIT_INLINE(int) git_atomic_inc(git_atomic *a)
bb3de0c4 67{
7a6f51de 68#if defined(GIT_WIN32)
bb3de0c4 69 return InterlockedIncrement(&a->val);
7a6f51de
VM
70#elif defined(__GNUC__)
71 return __sync_add_and_fetch(&a->val, 1);
bb3de0c4
VM
72#else
73# error "Unsupported architecture for atomic operations"
74#endif
75}
76
f9774eea
VM
77GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
78{
79#if defined(GIT_WIN32)
eb63fda2 80 return InterlockedExchangeAdd(&a->val, addend);
f9774eea
VM
81#elif defined(__GNUC__)
82 return __sync_add_and_fetch(&a->val, addend);
83#else
84# error "Unsupported architecture for atomic operations"
85#endif
86}
87
72a3fe42 88GIT_INLINE(int) git_atomic_dec(git_atomic *a)
bb3de0c4 89{
7a6f51de 90#if defined(GIT_WIN32)
bb3de0c4 91 return InterlockedDecrement(&a->val);
7a6f51de
VM
92#elif defined(__GNUC__)
93 return __sync_sub_and_fetch(&a->val, 1);
bb3de0c4
VM
94#else
95# error "Unsupported architecture for atomic operations"
96#endif
97}
98
e976b56d 99GIT_INLINE(void *) git___compare_and_swap(
814de0bc 100 void * volatile *ptr, void *oldval, void *newval)
e976b56d 101{
38eef611 102 volatile void *foundval;
e976b56d 103#if defined(GIT_WIN32)
c4ac556e 104 foundval = InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval);
e976b56d 105#elif defined(__GNUC__)
c6289186 106 foundval = __sync_val_compare_and_swap(ptr, oldval, newval);
e976b56d
RB
107#else
108# error "Unsupported architecture for atomic operations"
109#endif
c6289186 110 return (foundval == oldval) ? oldval : newval;
e976b56d
RB
111}
112
814de0bc
RB
113GIT_INLINE(volatile void *) git___swap(
114 void * volatile *ptr, void *newval)
115{
116#if defined(GIT_WIN32)
117 return InterlockedExchangePointer(ptr, newval);
118#else
119 return __sync_lock_test_and_set(ptr, newval);
120#endif
121}
122
eb63fda2
ET
123#ifdef GIT_ARCH_64
124
125GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
f9774eea
VM
126{
127#if defined(GIT_WIN32)
eb63fda2 128 return InterlockedExchangeAdd64(&a->val, addend);
f9774eea
VM
129#elif defined(__GNUC__)
130 return __sync_add_and_fetch(&a->val, addend);
131#else
132# error "Unsupported architecture for atomic operations"
133#endif
134}
135
eb63fda2
ET
136#endif
137
bb3de0c4
VM
138#else
139
140#define git_thread unsigned int
faebc1c6 141#define git_thread_create(thread, start_routine, arg) 0
bb3de0c4
VM
142#define git_thread_join(id, status) (void)0
143
144/* Pthreads Mutex */
145#define git_mutex unsigned int
369b0217
ET
146GIT_INLINE(int) git_mutex_init(git_mutex *mutex) \
147 { GIT_UNUSED(mutex); return 0; }
148GIT_INLINE(int) git_mutex_lock(git_mutex *mutex) \
149 { GIT_UNUSED(mutex); return 0; }
bb3de0c4
VM
150#define git_mutex_unlock(a) (void)0
151#define git_mutex_free(a) (void)0
152
bbcc7ffc 153/* Pthreads condition vars */
bb3de0c4
VM
154#define git_cond unsigned int
155#define git_cond_init(c, a) (void)0
156#define git_cond_free(c) (void)0
157#define git_cond_wait(c, l) (void)0
158#define git_cond_signal(c) (void)0
159#define git_cond_broadcast(c) (void)0
160
8d9a85d4
RB
161/* Pthreads rwlock */
162#define git_rwlock unsigned int
163#define git_rwlock_init(a) 0
164#define git_rwlock_rdlock(a) 0
165#define git_rwlock_rdunlock(a) (void)0
166#define git_rwlock_wrlock(a) 0
167#define git_rwlock_wrunlock(a) (void)0
168#define git_rwlock_free(a) (void)0
169#define GIT_RWLOCK_STATIC_INIT 0
170
171
814de0bc
RB
172GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
173{
174 a->val = val;
175}
176
72a3fe42 177GIT_INLINE(int) git_atomic_inc(git_atomic *a)
bb3de0c4
VM
178{
179 return ++a->val;
180}
181
f9774eea
VM
182GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
183{
184 a->val += addend;
185 return a->val;
186}
187
72a3fe42 188GIT_INLINE(int) git_atomic_dec(git_atomic *a)
bb3de0c4
VM
189{
190 return --a->val;
191}
192
e976b56d 193GIT_INLINE(void *) git___compare_and_swap(
814de0bc 194 void * volatile *ptr, void *oldval, void *newval)
e976b56d
RB
195{
196 if (*ptr == oldval)
197 *ptr = newval;
198 else
199 oldval = newval;
200 return oldval;
201}
202
814de0bc
RB
203GIT_INLINE(volatile void *) git___swap(
204 void * volatile *ptr, void *newval)
205{
206 volatile void *old = *ptr;
207 *ptr = newval;
208 return old;
209}
210
eb63fda2
ET
211#ifdef GIT_ARCH_64
212
213GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
f9774eea
VM
214{
215 a->val += addend;
216 return a->val;
217}
218
bb3de0c4 219#endif
36f0f61f 220
eb63fda2
ET
221#endif
222
814de0bc
RB
223GIT_INLINE(int) git_atomic_get(git_atomic *a)
224{
225 return (int)a->val;
226}
227
e976b56d
RB
228/* Atomically replace oldval with newval
229 * @return oldval if it was replaced or newval if it was not
230 */
231#define git__compare_and_swap(P,O,N) \
814de0bc 232 git___compare_and_swap((void * volatile *)P, O, N)
e976b56d 233
814de0bc 234#define git__swap(ptr, val) (void *)git___swap((void * volatile *)&ptr, val)
e976b56d 235
e035685f 236extern int git_online_cpus(void);
36f0f61f 237
6e0fc1a6 238#if defined(GIT_THREADS) && defined(_MSC_VER)
e976b56d
RB
239# define GIT_MEMORY_BARRIER MemoryBarrier()
240#elif defined(GIT_THREADS)
241# define GIT_MEMORY_BARRIER __sync_synchronize()
242#else
243# define GIT_MEMORY_BARRIER /* noop */
244#endif
245
eae0bfdc 246#endif