Browse Source
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.pull/2/head
5 changed files with 25 additions and 213 deletions
@ -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 |
|||
@ -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 |
|||
} |
|||
Loading…
Reference in new issue