]> git.proxmox.com Git - libgit2.git/blob - src/thread-utils.h
Add BD on ca-certificates
[libgit2.git] / src / thread-utils.h
1 /*
2 * Copyright (C) the libgit2 contributors. All rights reserved.
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 */
7 #ifndef INCLUDE_thread_utils_h__
8 #define INCLUDE_thread_utils_h__
9
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
16 /* Common operations even if threading has been disabled */
17 typedef struct {
18 #if defined(GIT_WIN32)
19 volatile long val;
20 #else
21 volatile int val;
22 #endif
23 } git_atomic;
24
25 #ifdef GIT_ARCH_64
26
27 typedef struct {
28 #if defined(GIT_WIN32)
29 __int64 val;
30 #else
31 int64_t val;
32 #endif
33 } git_atomic64;
34
35 typedef git_atomic64 git_atomic_ssize;
36
37 #define git_atomic_ssize_add git_atomic64_add
38
39 #else
40
41 typedef git_atomic git_atomic_ssize;
42
43 #define git_atomic_ssize_add git_atomic_add
44
45 #endif
46
47 #ifdef GIT_THREADS
48
49 #ifdef GIT_WIN32
50 # include "win32/thread.h"
51 #else
52 # include "unix/pthread.h"
53 #endif
54
55 GIT_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
66 GIT_INLINE(int) git_atomic_inc(git_atomic *a)
67 {
68 #if defined(GIT_WIN32)
69 return InterlockedIncrement(&a->val);
70 #elif defined(__GNUC__)
71 return __sync_add_and_fetch(&a->val, 1);
72 #else
73 # error "Unsupported architecture for atomic operations"
74 #endif
75 }
76
77 GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
78 {
79 #if defined(GIT_WIN32)
80 return InterlockedExchangeAdd(&a->val, addend);
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
88 GIT_INLINE(int) git_atomic_dec(git_atomic *a)
89 {
90 #if defined(GIT_WIN32)
91 return InterlockedDecrement(&a->val);
92 #elif defined(__GNUC__)
93 return __sync_sub_and_fetch(&a->val, 1);
94 #else
95 # error "Unsupported architecture for atomic operations"
96 #endif
97 }
98
99 GIT_INLINE(void *) git___compare_and_swap(
100 void * volatile *ptr, void *oldval, void *newval)
101 {
102 volatile void *foundval;
103 #if defined(GIT_WIN32)
104 foundval = InterlockedCompareExchangePointer((volatile PVOID *)ptr, newval, oldval);
105 #elif defined(__GNUC__)
106 foundval = __sync_val_compare_and_swap(ptr, oldval, newval);
107 #else
108 # error "Unsupported architecture for atomic operations"
109 #endif
110 return (foundval == oldval) ? oldval : newval;
111 }
112
113 GIT_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
123 #ifdef GIT_ARCH_64
124
125 GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
126 {
127 #if defined(GIT_WIN32)
128 return InterlockedExchangeAdd64(&a->val, addend);
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
136 #endif
137
138 #else
139
140 #define git_thread unsigned int
141 #define git_thread_create(thread, start_routine, arg) 0
142 #define git_thread_join(id, status) (void)0
143
144 /* Pthreads Mutex */
145 #define git_mutex unsigned int
146 GIT_INLINE(int) git_mutex_init(git_mutex *mutex) \
147 { GIT_UNUSED(mutex); return 0; }
148 GIT_INLINE(int) git_mutex_lock(git_mutex *mutex) \
149 { GIT_UNUSED(mutex); return 0; }
150 #define git_mutex_unlock(a) (void)0
151 #define git_mutex_free(a) (void)0
152
153 /* Pthreads condition vars */
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
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
172 GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
173 {
174 a->val = val;
175 }
176
177 GIT_INLINE(int) git_atomic_inc(git_atomic *a)
178 {
179 return ++a->val;
180 }
181
182 GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
183 {
184 a->val += addend;
185 return a->val;
186 }
187
188 GIT_INLINE(int) git_atomic_dec(git_atomic *a)
189 {
190 return --a->val;
191 }
192
193 GIT_INLINE(void *) git___compare_and_swap(
194 void * volatile *ptr, void *oldval, void *newval)
195 {
196 if (*ptr == oldval)
197 *ptr = newval;
198 else
199 oldval = newval;
200 return oldval;
201 }
202
203 GIT_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
211 #ifdef GIT_ARCH_64
212
213 GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
214 {
215 a->val += addend;
216 return a->val;
217 }
218
219 #endif
220
221 #endif
222
223 GIT_INLINE(int) git_atomic_get(git_atomic *a)
224 {
225 return (int)a->val;
226 }
227
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) \
232 git___compare_and_swap((void * volatile *)P, O, N)
233
234 #define git__swap(ptr, val) (void *)git___swap((void * volatile *)&ptr, val)
235
236 extern int git_online_cpus(void);
237
238 #if defined(GIT_THREADS) && defined(_MSC_VER)
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
246 #endif