File Coverage

deps/libgit2/src/thread-utils.h
Criterion Covered Total %
statement 0 3 0.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 0 3 0.0


line stmt bran cond sub pod time code
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 0           GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
173             {
174 0           a->val = val;
175 0           }
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