5 changed files with 195 additions and 0 deletions
@ -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 |
|||
@ -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 <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); |
|||
} |
|||
|
|||
#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 |
|||
@ -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 <config.h> |
|||
#endif |
|||
|
|||
#include <vlc_common.h> |
|||
#include <vlc_atomic.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) |
|||
{ |
|||
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 |
|||
} |
|||
Loading…
Reference in new issue