[vlc-commits] Rewrite vlc_atomic_* using the new atomic operations

Rémi Denis-Courmont git at videolan.org
Fri May 11 19:58:16 CEST 2012


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri May 11 20:43:32 2012 +0300| [535e8b60f17a11c967aa8d8ea8458a000f7cbf63] | committer: Rémi Denis-Courmont

Rewrite vlc_atomic_* using the new atomic operations

This way, the official atomic functions will be used when available,
rather than VLC's own implementation.

This commit also enables proper atomic operations on some platforms
or with some toolchains. __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 is not
defined on some platforms such as ARM Linux, nor by other compilers
than GCC such as LLVM/clang. Then atomic operations wrongly fell
back to the lame mutex-based implementation.

This will break support for some old compilers and old or irrelevant
instruction set architectures. They would need to provide replacement
for the Intel-originated __sync_* builtin functions.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=535e8b60f17a11c967aa8d8ea8458a000f7cbf63
---

 include/vlc_atomic.h |   31 ++++++++++--
 src/Makefile.am      |    6 --
 src/libvlccore.sym   |    5 --
 src/misc/atomic.c    |  125 --------------------------------------------------
 src/win32/atomic.c   |   71 ----------------------------
 5 files changed, 25 insertions(+), 213 deletions(-)

diff --git a/include/vlc_atomic.h b/include/vlc_atomic.h
index 11b2711..8e891e7 100644
--- a/include/vlc_atomic.h
+++ b/include/vlc_atomic.h
@@ -189,14 +189,25 @@ bool vlc_atomic_compare_exchange(volatile void *object, void *expected,
 # define VLC_ATOMIC_INIT(val) { (val) }
 
 /* All functions return the atom value _after_ the operation. */
+static inline uintptr_t vlc_atomic_get(const vlc_atomic_t *atom)
+{
+    return atomic_load(&atom->u);
+}
+
+static inline uintptr_t vlc_atomic_set(vlc_atomic_t *atom, uintptr_t v)
+{
+    atomic_store(&atom->u, v);
+    return v;
+}
 
-VLC_API uintptr_t vlc_atomic_get(const vlc_atomic_t *);
-VLC_API uintptr_t vlc_atomic_set(vlc_atomic_t *, uintptr_t);
-VLC_API uintptr_t vlc_atomic_add(vlc_atomic_t *, uintptr_t);
+static inline uintptr_t vlc_atomic_add(vlc_atomic_t *atom, uintptr_t v)
+{
+    return atomic_fetch_add(&atom->u, v) + v;
+}
 
 static inline uintptr_t vlc_atomic_sub (vlc_atomic_t *atom, uintptr_t v)
 {
-    return vlc_atomic_add (atom, -v);
+    return atomic_fetch_sub (&atom->u, v) - v;
 }
 
 static inline uintptr_t vlc_atomic_inc (vlc_atomic_t *atom)
@@ -209,8 +220,16 @@ static inline uintptr_t vlc_atomic_dec (vlc_atomic_t *atom)
     return vlc_atomic_sub (atom, 1);
 }
 
-VLC_API uintptr_t vlc_atomic_swap(vlc_atomic_t *, uintptr_t);
-VLC_API uintptr_t vlc_atomic_compare_swap(vlc_atomic_t *, uintptr_t, uintptr_t);
+static inline uintptr_t vlc_atomic_swap(vlc_atomic_t *atom, uintptr_t v)
+{
+    return atomic_exchange(&atom->u, v);
+}
+
+static inline uintptr_t vlc_atomic_compare_swap(vlc_atomic_t *atom,
+                                                uintptr_t u, uintptr_t v)
+{
+    return atomic_compare_exchange_strong(&atom->u, &u, v);
+}
 
 /** Helper to retrieve a single precision from an atom. */
 static inline float vlc_atomic_getf(const vlc_atomic_t *atom)
diff --git a/src/Makefile.am b/src/Makefile.am
index 69357d7..d6d083e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -239,7 +239,6 @@ endif
 
 SOURCES_libvlc_darwin = \
 	posix/darwin_dirs.c \
-	misc/atomic.c \
 	posix/filesystem.c \
 	posix/plugin.c \
 	posix/thread.c \
@@ -249,7 +248,6 @@ SOURCES_libvlc_darwin = \
 
 SOURCES_libvlc_linux = \
 	posix/dirs.c \
-	misc/atomic.c \
 	posix/filesystem.c \
 	posix/plugin.c \
 	posix/thread.c \
@@ -261,7 +259,6 @@ SOURCES_libvlc_linux = \
 
 SOURCES_libvlc_win32 = \
 	win32/dirs.c \
-	win32/atomic.c \
 	win32/filesystem.c \
 	win32/plugin.c \
 	win32/thread.c \
@@ -273,7 +270,6 @@ SOURCES_libvlc_win32 = \
 SOURCES_libvlc_symbian = \
 	symbian/path.cpp \
 	symbian/dirs.c \
-	misc/atomic.c \
 	win32/plugin.c \
 	posix/rand.c \
 	$(NULL)
@@ -281,7 +277,6 @@ SOURCES_libvlc_symbian = \
 SOURCES_libvlc_os2 = \
 	os2/getaddrinfo.c \
 	os2/dirs.c \
-	misc/atomic.c \
 	os2/filesystem.c \
 	os2/plugin.c \
 	os2/thread.c \
@@ -291,7 +286,6 @@ SOURCES_libvlc_os2 = \
 
 SOURCES_libvlc_other = \
 	posix/dirs.c \
-	misc/atomic.c \
 	posix/filesystem.c \
 	posix/thread.c \
 	posix/plugin.c \
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 5d35457..921e513 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -489,11 +489,6 @@ vlc_clone
 VLC_CompileBy
 VLC_CompileHost
 VLC_Compiler
-vlc_atomic_get
-vlc_atomic_set
-vlc_atomic_add
-vlc_atomic_swap
-vlc_atomic_compare_swap
 vlc_cond_broadcast
 vlc_cond_destroy
 vlc_cond_init
diff --git a/src/misc/atomic.c b/src/misc/atomic.c
deleted file mode 100644
index f79a491..0000000
--- a/src/misc/atomic.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*****************************************************************************
- * atomic.c:
- *****************************************************************************
- * Copyright (C) 2010 Rémi Denis-Courmont
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <vlc_common.h>
-#include <vlc_atomic.h>
-
-#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
-/* GCC intrinsics */
-
-uintptr_t vlc_atomic_get (const vlc_atomic_t *atom)
-{
-    __sync_synchronize ();
-    return atom->u;
-}
-
-uintptr_t vlc_atomic_set (vlc_atomic_t *atom, uintptr_t v)
-{
-    atom->u = v;
-    __sync_synchronize ();
-    return v;
-}
-
-uintptr_t vlc_atomic_add (vlc_atomic_t *atom, uintptr_t v)
-{
-    return __sync_add_and_fetch (&atom->u, v);
-}
-
-uintptr_t vlc_atomic_swap (vlc_atomic_t *atom, uintptr_t v)
-{
-    /* grmbl, gcc does not provide an intrinsic for this! */
-    uintptr_t u;
-
-    do
-        u = vlc_atomic_get (atom);
-    while (vlc_atomic_compare_swap (atom, u, v) != u);
-
-    return u;
-}
-
-uintptr_t vlc_atomic_compare_swap (vlc_atomic_t *atom,
-                                   uintptr_t oldval, uintptr_t newval)
-{
-    return __sync_val_compare_and_swap (&atom->u, oldval, newval);
-}
-
-#else
-/* Worst-case fallback implementation with a mutex */
-
-static vlc_mutex_t lock = VLC_STATIC_MUTEX;
-
-uintptr_t vlc_atomic_get (const vlc_atomic_t *atom)
-{
-    uintptr_t v;
-
-    vlc_mutex_lock (&lock);
-    v = atom->u;
-    vlc_mutex_unlock (&lock);
-    return v;
-}
-
-uintptr_t vlc_atomic_set (vlc_atomic_t *atom, uintptr_t v)
-{
-    vlc_mutex_lock (&lock);
-    atom->u = v;
-    vlc_mutex_unlock (&lock);
-    return v;
-}
-
-uintptr_t vlc_atomic_add (vlc_atomic_t *atom, uintptr_t v)
-{
-    vlc_mutex_lock (&lock);
-    atom->u += v;
-    v = atom->u;
-    vlc_mutex_unlock (&lock);
-    return v;
-}
-
-uintptr_t vlc_atomic_swap (vlc_atomic_t *atom, uintptr_t v)
-{
-    uintptr_t u;
-
-    vlc_mutex_lock (&lock);
-    u = atom->u;
-    atom->u = v;
-    vlc_mutex_unlock (&lock);
-
-    return u;
-}
-
-uintptr_t vlc_atomic_compare_swap (vlc_atomic_t *atom,
-                                       uintptr_t oldval, uintptr_t newval)
-{
-    uintptr_t u;
-
-    vlc_mutex_lock (&lock);
-    u = atom->u;
-    if (u == oldval)
-        atom->u = newval;
-    vlc_mutex_unlock (&lock);
-
-    return u;
-}
-
-#endif
diff --git a/src/win32/atomic.c b/src/win32/atomic.c
deleted file mode 100644
index cb2bc84..0000000
--- a/src/win32/atomic.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*****************************************************************************
- * atomic.c:
- *****************************************************************************
- * Copyright (C) 2010 Rémi Denis-Courmont
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <vlc_common.h>
-#include <vlc_atomic.h>
-
-#include <windows.h>
-
-uintptr_t vlc_atomic_get (const vlc_atomic_t *atom)
-{
-    return atom->u;
-}
-
-uintptr_t vlc_atomic_set (vlc_atomic_t *atom, uintptr_t v)
-{
-#if defined (WIN64)
-    InterlockedExchange64 (&atom->u, v);
-#else
-    InterlockedExchange (&atom->u, v);
-#endif
-    return v;
-}
-
-uintptr_t vlc_atomic_add (vlc_atomic_t *atom, uintptr_t v)
-{
-#if defined (WIN64)
-    return InterlockedExchangeAdd64 (&atom->s, v) + v;
-#else
-    return InterlockedExchangeAdd (&atom->s, v) + v;
-#endif
-}
-
-uintptr_t vlc_atomic_swap (vlc_atomic_t *atom, uintptr_t v)
-{
-#if defined (WIN64)
-    return InterlockedExchange64 (&atom->s, v);
-#else
-    return InterlockedExchange (&atom->s, v);
-#endif
-}
-
-uintptr_t vlc_atomic_compare_swap (vlc_atomic_t *atom,
-                                   uintptr_t oldval, uintptr_t newval)
-{
-#if defined (WIN64)
-    return InterlockedCompareExchange64 (&atom->s, newval, oldval);
-#else
-    return InterlockedCompareExchange (&atom->s, newval, oldval);
-#endif
-}



More information about the vlc-commits mailing list