From 34f3dfb172a44155148df362efb8a0831da757ca Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Mon, 28 Jun 2010 02:13:33 +0300 Subject: [PATCH] Atomic operations (currently same ones as in garbage collector) --- include/vlc_atomic.h | 59 ++++++++++++++++++++++++++++++++ src/Makefile.am | 6 ++++ src/libvlccore.sym | 3 ++ src/misc/atomic.c | 81 ++++++++++++++++++++++++++++++++++++++++++++ src/win32/atomic.c | 46 +++++++++++++++++++++++++ 5 files changed, 195 insertions(+) create mode 100644 include/vlc_atomic.h create mode 100644 src/misc/atomic.c create mode 100644 src/win32/atomic.c diff --git a/include/vlc_atomic.h b/include/vlc_atomic.h new file mode 100644 index 0000000000..2b0ff88e67 --- /dev/null +++ b/include/vlc_atomic.h @@ -0,0 +1,59 @@ +/***************************************************************************** + * vlc_atomic.h: + ***************************************************************************** + * 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 General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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. + *****************************************************************************/ + +#ifndef VLC_ATOMIC_H +# define VLC_ATOMIC_H + +/** + * \file + * Atomic operations do not require locking, but they are not very powerful. + */ + +/** + * Memory storage space for an atom. Never access it directly. + */ +typedef union +{ + uintptr_t u; + intptr_t s; +} vlc_atomic_t; + +/* All functions return the atom value _after_ the operation. */ + +VLC_EXPORT(uintptr_t, vlc_atomic_get, (const vlc_atomic_t *)); +VLC_EXPORT(uintptr_t, vlc_atomic_set, (vlc_atomic_t *, uintptr_t)); +VLC_EXPORT(uintptr_t, vlc_atomic_add, (vlc_atomic_t *, uintptr_t)); + +static inline uintptr_t vlc_atomic_sub (vlc_atomic_t *atom, uintptr_t v) +{ + return vlc_atomic_add (atom, -v); +} + +static inline uintptr_t vlc_atomic_inc (vlc_atomic_t *atom) +{ + return vlc_atomic_add (atom, 1); +} + +static inline uintptr_t vlc_atomic_dec (vlc_atomic_t *atom) +{ + return vlc_atomic_sub (atom, 1); +} + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 1ce58d5635..b05eb67477 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,7 @@ pluginsinclude_HEADERS = \ ../include/vlc_aout_mixer.h \ ../include/vlc_arrays.h \ ../include/vlc_art_finder.h \ + ../include/vlc_atomic.h \ ../include/vlc_avcodec.h \ ../include/vlc_bits.h \ ../include/vlc_block.h \ @@ -271,17 +272,20 @@ endif endif SOURCES_libvlc_beos = \ + misc/atomic.c \ misc/pthread.c \ $(NULL) SOURCES_libvlc_darwin = \ config/dirs_macos.c \ + misc/atomic.c \ misc/pthread.c \ misc/darwin_specific.c \ $(NULL) SOURCES_libvlc_linux = \ config/dirs_xdg.c \ + misc/atomic.c \ misc/pthread.c \ misc/linux_specific.c \ $(NULL) @@ -289,12 +293,14 @@ SOURCES_libvlc_linux = \ SOURCES_libvlc_win32 = \ win32/dirs.c \ win32/specific.c \ + win32/atomic.c \ win32/thread.c \ win32/winsock.c \ $(NULL) SOURCES_libvlc_other = \ config/dirs_xdg.c \ + misc/atomic.c \ misc/pthread.c \ misc/not_specific.c diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 9dacc33317..054af8cf94 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -497,6 +497,9 @@ vlc_clone VLC_CompileBy VLC_CompileHost VLC_Compiler +vlc_atomic_get +vlc_atomic_set +vlc_atomic_add vlc_cond_broadcast vlc_cond_destroy vlc_cond_init diff --git a/src/misc/atomic.c b/src/misc/atomic.c new file mode 100644 index 0000000000..1f97f599e1 --- /dev/null +++ b/src/misc/atomic.c @@ -0,0 +1,81 @@ +/***************************************************************************** + * 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 General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 +#endif + +#include +#include + +#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); +} + +#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; +} + +#endif diff --git a/src/win32/atomic.c b/src/win32/atomic.c new file mode 100644 index 0000000000..d6f77c249e --- /dev/null +++ b/src/win32/atomic.c @@ -0,0 +1,46 @@ +/***************************************************************************** + * 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 General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License for more details. + * + * You should have received a copy of the GNU 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 +#endif + +#include +#include + +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) +{ + atom->u = v; + return v; +} + +uintptr_t vlc_atomic_add (vlc_atomic_t *atom, uintptr_t v) +{ +#if defined (WIN64) + return InterlockedAdd64 (&atom->s, v); +#else + return InterlockedAdd (&atom->s, v); +#endif +} -- 2.39.2