Commit f9774eea3a37e3a2a44d3c7e9dbc895280c3d90a

Vicent Marti 2013-04-22T17:22:31

atomic: Add an atomic type for 64-bit operations

diff --git a/src/thread-utils.h b/src/thread-utils.h
index dafe70a..28ecd29 100644
--- a/src/thread-utils.h
+++ b/src/thread-utils.h
@@ -18,6 +18,14 @@ typedef struct {
 #endif
 } git_atomic;
 
+typedef struct {
+#if defined(GIT_WIN32)
+	__int64 val;
+#else
+	int64_t val;
+#endif
+} git_atomic64;
+
 GIT_INLINE(void) git_atomic_set(git_atomic *a, int val)
 {
 	a->val = val;
@@ -57,6 +65,17 @@ GIT_INLINE(int) git_atomic_inc(git_atomic *a)
 #endif
 }
 
+GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
+{
+#if defined(GIT_WIN32)
+	return _InterlockedExchangeAdd(&a->val, addend);
+#elif defined(__GNUC__)
+	return __sync_add_and_fetch(&a->val, addend);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
 GIT_INLINE(int) git_atomic_dec(git_atomic *a)
 {
 #if defined(GIT_WIN32)
@@ -82,6 +101,17 @@ GIT_INLINE(void *) git___compare_and_swap(
 	return (foundval == oldval) ? oldval : newval;
 }
 
+GIT_INLINE(int) git_atomic64_add(git_atomic64 *a, int64_t addend)
+{
+#if defined(GIT_WIN32)
+	return _InterlockedExchangeAdd64(&a->val, addend);
+#elif defined(__GNUC__)
+	return __sync_add_and_fetch(&a->val, addend);
+#else
+#	error "Unsupported architecture for atomic operations"
+#endif
+}
+
 #else
 
 #define git_thread unsigned int
@@ -110,6 +140,12 @@ GIT_INLINE(int) git_atomic_inc(git_atomic *a)
 	return ++a->val;
 }
 
+GIT_INLINE(int) git_atomic_add(git_atomic *a, int32_t addend)
+{
+	a->val += addend;
+	return a->val;
+}
+
 GIT_INLINE(int) git_atomic_dec(git_atomic *a)
 {
 	return --a->val;
@@ -125,6 +161,12 @@ GIT_INLINE(void *) git___compare_and_swap(
 	return oldval;
 }
 
+GIT_INLINE(int) git_atomic64_add(git_atomic64 *a, int64_t addend)
+{
+	a->val += addend;
+	return a->val;
+}
+
 #endif
 
 /* Atomically replace oldval with newval