1 /* 2 * Copyright (c) 2012 Ronald S. Bultje <rsbultje@gmail.com> 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include "config.h" 22 #include "atomic.h" 23 24 #if !HAVE_ATOMICS_NATIVE 25 26 #if HAVE_PTHREADS 27 28 #include <pthread.h> 29 30 static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER; 31 32 int avpriv_atomic_int_get(volatile int *ptr) 33 { 34 int res; 35 36 pthread_mutex_lock(&atomic_lock); 37 res = *ptr; 38 pthread_mutex_unlock(&atomic_lock); 39 40 return res; 41 } 42 43 void avpriv_atomic_int_set(volatile int *ptr, int val) 44 { 45 pthread_mutex_lock(&atomic_lock); 46 *ptr = val; 47 pthread_mutex_unlock(&atomic_lock); 48 } 49 50 int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc) 51 { 52 int res; 53 54 pthread_mutex_lock(&atomic_lock); 55 *ptr += inc; 56 res = *ptr; 57 pthread_mutex_unlock(&atomic_lock); 58 59 return res; 60 } 61 62 void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval) 63 { 64 void *ret; 65 pthread_mutex_lock(&atomic_lock); 66 ret = *ptr; 67 if (ret == oldval) 68 *ptr = newval; 69 pthread_mutex_unlock(&atomic_lock); 70 return ret; 71 } 72 73 #elif !HAVE_THREADS 74 75 int avpriv_atomic_int_get(volatile int *ptr) 76 { 77 return *ptr; 78 } 79 80 void avpriv_atomic_int_set(volatile int *ptr, int val) 81 { 82 *ptr = val; 83 } 84 85 int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc) 86 { 87 *ptr += inc; 88 return *ptr; 89 } 90 91 void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval) 92 { 93 if (*ptr == oldval) { 94 *ptr = newval; 95 return oldval; 96 } 97 return *ptr; 98 } 99 100 #else /* HAVE_THREADS */ 101 102 /* This should never trigger, unless a new threading implementation 103 * without correct atomics dependencies in configure or a corresponding 104 * atomics implementation is added. */ 105 #error "Threading is enabled, but there is no implementation of atomic operations available" 106 107 #endif /* HAVE_PTHREADS */ 108 109 #endif /* !HAVE_ATOMICS_NATIVE */ 110