@@ -74,6 +74,9 @@ typedef git_atomic32 git_atomic_ssize;
7474# include "unix/pthread.h"
7575#endif
7676
77+ /*
78+ * Atomically sets the contents of *a to be val.
79+ */
7780GIT_INLINE (void ) git_atomic32_set (git_atomic32 * a , int val )
7881{
7982#if defined(GIT_WIN32 )
@@ -87,6 +90,10 @@ GIT_INLINE(void) git_atomic32_set(git_atomic32 *a, int val)
8790#endif
8891}
8992
93+ /*
94+ * Atomically increments the contents of *a by 1, and stores the result back into *a.
95+ * @return the result of the operation.
96+ */
9097GIT_INLINE (int ) git_atomic32_inc (git_atomic32 * a )
9198{
9299#if defined(GIT_WIN32 )
@@ -100,10 +107,14 @@ GIT_INLINE(int) git_atomic32_inc(git_atomic32 *a)
100107#endif
101108}
102109
110+ /*
111+ * Atomically adds the contents of *a and addend, and stores the result back into *a.
112+ * @return the result of the operation.
113+ */
103114GIT_INLINE (int ) git_atomic32_add (git_atomic32 * a , int32_t addend )
104115{
105116#if defined(GIT_WIN32 )
106- return InterlockedExchangeAdd (& a -> val , addend );
117+ return InterlockedAdd (& a -> val , addend );
107118#elif defined(GIT_BUILTIN_ATOMIC )
108119 return __atomic_add_fetch (& a -> val , addend , __ATOMIC_SEQ_CST );
109120#elif defined(GIT_BUILTIN_SYNC )
@@ -113,6 +124,10 @@ GIT_INLINE(int) git_atomic32_add(git_atomic32 *a, int32_t addend)
113124#endif
114125}
115126
127+ /*
128+ * Atomically decrements the contents of *a by 1, and stores the result back into *a.
129+ * @return the result of the operation.
130+ */
116131GIT_INLINE (int ) git_atomic32_dec (git_atomic32 * a )
117132{
118133#if defined(GIT_WIN32 )
@@ -126,6 +141,10 @@ GIT_INLINE(int) git_atomic32_dec(git_atomic32 *a)
126141#endif
127142}
128143
144+ /*
145+ * Atomically gets the contents of *a.
146+ * @return the contents of *a.
147+ */
129148GIT_INLINE (int ) git_atomic32_get (git_atomic32 * a )
130149{
131150#if defined(GIT_WIN32 )
@@ -143,16 +162,13 @@ GIT_INLINE(void *) git_atomic__compare_and_swap(
143162 void * volatile * ptr , void * oldval , void * newval )
144163{
145164#if defined(GIT_WIN32 )
146- volatile void * foundval ;
147- foundval = InterlockedCompareExchangePointer ((volatile PVOID * )ptr , newval , oldval );
148- return (foundval == oldval ) ? oldval : newval ;
165+ return InterlockedCompareExchangePointer ((volatile PVOID * )ptr , newval , oldval );
149166#elif defined(GIT_BUILTIN_ATOMIC )
150- bool success = __atomic_compare_exchange (ptr , & oldval , & newval , false, __ATOMIC_SEQ_CST , __ATOMIC_SEQ_CST );
151- return success ? oldval : newval ;
167+ void * foundval = oldval ;
168+ __atomic_compare_exchange (ptr , & foundval , & newval , false, __ATOMIC_SEQ_CST , __ATOMIC_SEQ_CST );
169+ return foundval ;
152170#elif defined(GIT_BUILTIN_SYNC )
153- volatile void * foundval ;
154- foundval = __sync_val_compare_and_swap (ptr , oldval , newval );
155- return (foundval == oldval ) ? oldval : newval ;
171+ return __sync_val_compare_and_swap (ptr , oldval , newval );
156172#else
157173# error "Unsupported architecture for atomic operations"
158174#endif
@@ -164,11 +180,11 @@ GIT_INLINE(volatile void *) git_atomic__swap(
164180#if defined(GIT_WIN32 )
165181 return InterlockedExchangePointer (ptr , newval );
166182#elif defined(GIT_BUILTIN_ATOMIC )
167- void * volatile foundval ;
183+ void * volatile foundval = NULL ;
168184 __atomic_exchange (ptr , & newval , & foundval , __ATOMIC_SEQ_CST );
169185 return foundval ;
170186#elif defined(GIT_BUILTIN_SYNC )
171- return __sync_lock_test_and_set (ptr , newval );
187+ return ( volatile void * ) __sync_lock_test_and_set (ptr , newval );
172188#else
173189# error "Unsupported architecture for atomic operations"
174190#endif
@@ -178,9 +194,7 @@ GIT_INLINE(volatile void *) git_atomic__load(void * volatile *ptr)
178194{
179195#if defined(GIT_WIN32 )
180196 void * newval = NULL , * oldval = NULL ;
181- volatile void * foundval = NULL ;
182- foundval = InterlockedCompareExchangePointer ((volatile PVOID * )ptr , newval , oldval );
183- return foundval ;
197+ return (volatile void * )InterlockedCompareExchangePointer ((volatile PVOID * )ptr , newval , oldval );
184198#elif defined(GIT_BUILTIN_ATOMIC )
185199 return (volatile void * )__atomic_load_n (ptr , __ATOMIC_SEQ_CST );
186200#elif defined(GIT_BUILTIN_SYNC )
@@ -192,10 +206,14 @@ GIT_INLINE(volatile void *) git_atomic__load(void * volatile *ptr)
192206
193207#ifdef GIT_ARCH_64
194208
209+ /*
210+ * Atomically adds the contents of *a and addend, and stores the result back into *a.
211+ * @return the result of the operation.
212+ */
195213GIT_INLINE (int64_t ) git_atomic64_add (git_atomic64 * a , int64_t addend )
196214{
197215#if defined(GIT_WIN32 )
198- return InterlockedExchangeAdd64 (& a -> val , addend );
216+ return InterlockedAdd64 (& a -> val , addend );
199217#elif defined(GIT_BUILTIN_ATOMIC )
200218 return __atomic_add_fetch (& a -> val , addend , __ATOMIC_SEQ_CST );
201219#elif defined(GIT_BUILTIN_SYNC )
@@ -205,6 +223,9 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
205223#endif
206224}
207225
226+ /*
227+ * Atomically sets the contents of *a to be val.
228+ */
208229GIT_INLINE (void ) git_atomic64_set (git_atomic64 * a , int64_t val )
209230{
210231#if defined(GIT_WIN32 )
@@ -218,6 +239,10 @@ GIT_INLINE(void) git_atomic64_set(git_atomic64 *a, int64_t val)
218239#endif
219240}
220241
242+ /*
243+ * Atomically gets the contents of *a.
244+ * @return the contents of *a.
245+ */
221246GIT_INLINE (int64_t ) git_atomic64_get (git_atomic64 * a )
222247{
223248#if defined(GIT_WIN32 )
@@ -297,11 +322,10 @@ GIT_INLINE(int) git_atomic32_get(git_atomic32 *a)
297322GIT_INLINE (void * ) git_atomic__compare_and_swap (
298323 void * volatile * ptr , void * oldval , void * newval )
299324{
300- if (* ptr == oldval )
325+ void * foundval = * ptr ;
326+ if (foundval == oldval )
301327 * ptr = newval ;
302- else
303- oldval = newval ;
304- return oldval ;
328+ return foundval ;
305329}
306330
307331GIT_INLINE (volatile void * ) git_atomic__swap (
@@ -339,17 +363,50 @@ GIT_INLINE(int64_t) git_atomic64_get(git_atomic64 *a)
339363
340364#endif
341365
342- /* Atomically replace oldval with newval
343- * @return oldval if it was replaced or newval if it was not
366+ /*
367+ * Atomically replace the contents of *ptr (if they are equal to oldval) with
368+ * newval. ptr must point to a pointer or a value that is the same size as a
369+ * pointer. This is semantically compatible with:
370+ *
371+ * #define git_atomic_compare_and_swap(ptr, oldval, newval) \
372+ * ({ \
373+ * void *foundval = *ptr; \
374+ * if (foundval == oldval) \
375+ * *ptr = newval; \
376+ * foundval; \
377+ * })
378+ *
379+ * @return the original contents of *ptr.
344380 */
345- #define git_atomic_compare_and_swap (P , O , N ) \
346- git_atomic__compare_and_swap((void * volatile *)P, O, N )
381+ #define git_atomic_compare_and_swap (ptr , oldval , newval ) \
382+ git_atomic__compare_and_swap((void * volatile *)ptr, oldval, newval )
347383
348- #define git_atomic_swap (ptr , val ) \
349- (void *)git_atomic__swap((void * volatile *)&ptr, val)
384+ /*
385+ * Atomically replace the contents of v with newval. v must be the same size as
386+ * a pointer. This is semantically compatible with:
387+ *
388+ * #define git_atomic_swap(v, newval) \
389+ * ({ \
390+ * volatile void *old = v; \
391+ * v = newval; \
392+ * old; \
393+ * })
394+ *
395+ * @return the original contents of v.
396+ */
397+ #define git_atomic_swap (v , newval ) \
398+ (void *)git_atomic__swap((void * volatile *)&(v), newval)
350399
351- #define git_atomic_load (ptr ) \
352- (void *)git_atomic__load((void * volatile *)&ptr)
400+ /*
401+ * Atomically reads the contents of v. v must be the same size as a pointer.
402+ * This is semantically compatible with:
403+ *
404+ * #define git_atomic_load(v) v
405+ *
406+ * @return the contents of v.
407+ */
408+ #define git_atomic_load (v ) \
409+ (void *)git_atomic__load((void * volatile *)&(v))
353410
354411#if defined(GIT_THREADS )
355412
0 commit comments