]> git.proxmox.com Git - libgit2.git/blob - src/thread-utils.h
Fixes for Windows cas/threading stuff
[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 #include "common.h"
11
12 /* Common operations even if threading has been disabled */
13 typedef struct {
14 #if defined(GIT_WIN32)
15 volatile long val;
16 #else
17 volatile int val;
18 #endif
19 } git_atomic;
20
21 GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
22 {
23 a->val = val;
24 }
25
26 #ifdef GIT_THREADS
27
28 #define git_thread pthread_t
29 #define git_thread_create(thread, attr, start_routine, arg) pthread_create(thread, attr, start_routine, arg)
30 #define git_thread_kill(thread) pthread_cancel(thread)
31 #define git_thread_exit(status) pthread_exit(status)
32 #define git_thread_join(id, status) pthread_join(id, status)
33
34 /* Pthreads Mutex */
35 #define git_mutex pthread_mutex_t
36 #define git_mutex_init(a) pthread_mutex_init(a, NULL)
37 #define git_mutex_lock(a) pthread_mutex_lock(a)
38 #define git_mutex_unlock(a) pthread_mutex_unlock(a)
39 #define git_mutex_free(a) pthread_mutex_destroy(a)
40
41 /* Pthreads condition vars */
42 #define git_cond pthread_cond_t
43 #define git_cond_init(c) pthread_cond_init(c, NULL)
44 #define git_cond_free(c) pthread_cond_destroy(c)
45 #define git_cond_wait(c, l) pthread_cond_wait(c, l)
46 #define git_cond_signal(c) pthread_cond_signal(c)
47 #define git_cond_broadcast(c) pthread_cond_broadcast(c)
48
49 GIT_INLINE(int) git_atomic_inc(git_atomic *a)
50 {
51 #if defined(GIT_WIN32)
52 return InterlockedIncrement(&a->val);
53 #elif defined(__GNUC__)
54 return __sync_add_and_fetch(&a->val, 1);
55 #else
56 # error "Unsupported architecture for atomic operations"
57 #endif
58 }
59
60 GIT_INLINE(int) git_atomic_dec(git_atomic *a)
61 {
62 #if defined(GIT_WIN32)
63 return InterlockedDecrement(&a->val);
64 #elif defined(__GNUC__)
65 return __sync_sub_and_fetch(&a->val, 1);
66 #else
67 # error "Unsupported architecture for atomic operations"
68 #endif
69 }
70
71 GIT_INLINE(void *) git___compare_and_swap(
72 volatile void **ptr, void *oldval, void *newval)
73 {
74 void *foundval;
75 #if defined(GIT_WIN32)
76 foundval = InterlockedCompareExchangePointer(ptr, newval, oldval);
77 #elif defined(__GNUC__)
78 foundval = __sync_val_compare_and_swap(ptr, oldval, newval);
79 #else
80 # error "Unsupported architecture for atomic operations"
81 #endif
82 return (foundval == oldval) ? oldval : newval;
83 }
84
85 #else
86
87 #define git_thread unsigned int
88 #define git_thread_create(thread, attr, start_routine, arg) (void)0
89 #define git_thread_kill(thread) (void)0
90 #define git_thread_exit(status) (void)0
91 #define git_thread_join(id, status) (void)0
92
93 /* Pthreads Mutex */
94 #define git_mutex unsigned int
95 #define git_mutex_init(a) (void)0
96 #define git_mutex_lock(a) 0
97 #define git_mutex_unlock(a) (void)0
98 #define git_mutex_free(a) (void)0
99
100 /* Pthreads condition vars */
101 #define git_cond unsigned int
102 #define git_cond_init(c, a) (void)0
103 #define git_cond_free(c) (void)0
104 #define git_cond_wait(c, l) (void)0
105 #define git_cond_signal(c) (void)0
106 #define git_cond_broadcast(c) (void)0
107
108 GIT_INLINE(int) git_atomic_inc(git_atomic *a)
109 {
110 return ++a->val;
111 }
112
113 GIT_INLINE(int) git_atomic_dec(git_atomic *a)
114 {
115 return --a->val;
116 }
117
118 GIT_INLINE(void *) git___compare_and_swap(
119 volatile void **ptr, void *oldval, void *newval)
120 {
121 if (*ptr == oldval)
122 *ptr = newval;
123 else
124 oldval = newval;
125 return oldval;
126 }
127
128 #endif
129
130 /* Atomically replace oldval with newval
131 * @return oldval if it was replaced or newval if it was not
132 */
133 #define git__compare_and_swap(P,O,N) \
134 git___compare_and_swap((volatile void **)P, O, N)
135
136 #define git__swap(ptr, val) git__compare_and_swap(&ptr, ptr, val)
137
138 extern int git_online_cpus(void);
139
140 #if defined(GIT_THREADS) && defined(GIT_WIN32)
141 # define GIT_MEMORY_BARRIER MemoryBarrier()
142 #elif defined(GIT_THREADS)
143 # define GIT_MEMORY_BARRIER __sync_synchronize()
144 #else
145 # define GIT_MEMORY_BARRIER /* noop */
146 #endif
147
148 #endif /* INCLUDE_thread_utils_h__ */