blob: 64cff2576fd3032822e499ad2c8036935289714d
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 |