[FFmpeg-devel] [PATCH/RFC] Trac ticket 2363
James Almer
jamrial at gmail.com
Sun Mar 17 22:27:28 CET 2013
lavu/atomic.c is not compiling with gcc when using -march=i386 and w32threads
or os2threads because __sync_val_compare_and_swap() is not defined and the
fallback implementation currently only supports pthreads.
Mingw-w64 has MemoryBarrier() defined even when using -march=i386, so this is
not as much of a problem as it is with mingw32.
I was able to make it work using the pthreads wrappers from libavcodec, but
I'm not sure if this is a proper fix or not since threading is not my field of
expertise.
I'm attaching two versions of the proposed patch. Both are essentially the
same, but one alters the pthreads implementation for the sake of cleaner code.
I didn't test with the pthreads wrapper for os2threads because i have no way
to do it, but in theory it should work as well.
I'll send an actual patch once (and if) one of these is accepted.
Regards.
-------------- next part --------------
diff --git a/libavutil/atomic.c b/libavutil/atomic.c
index 7a701e1..12537ad 100644
--- a/libavutil/atomic.c
+++ b/libavutil/atomic.c
@@ -22,38 +22,50 @@
#if !HAVE_MEMORYBARRIER && !HAVE_SYNC_VAL_COMPARE_AND_SWAP && !HAVE_MACHINE_RW_BARRIER
-#if HAVE_PTHREADS
+#if HAVE_THREADS
+#if HAVE_PTHREADS
#include <pthread.h>
+#elif HAVE_W32THREADS
+#include "w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "os2threads.h"
+#endif
-static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t atomic_lock;
int avpriv_atomic_int_get(volatile int *ptr)
{
int res;
+ pthread_mutex_init(&atomic_lock, NULL);
pthread_mutex_lock(&atomic_lock);
res = *ptr;
pthread_mutex_unlock(&atomic_lock);
+ pthread_mutex_destroy(&atomic_lock);
return res;
}
void avpriv_atomic_int_set(volatile int *ptr, int val)
{
+ pthread_mutex_init(&atomic_lock, NULL);
pthread_mutex_lock(&atomic_lock);
*ptr = val;
pthread_mutex_unlock(&atomic_lock);
+ pthread_mutex_destroy(&atomic_lock);
}
int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
{
int res;
+ pthread_mutex_init(&atomic_lock, NULL);
pthread_mutex_lock(&atomic_lock);
*ptr += inc;
res = *ptr;
pthread_mutex_unlock(&atomic_lock);
+ pthread_mutex_destroy(&atomic_lock);
return res;
}
@@ -61,15 +73,18 @@ int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
{
void *ret;
+ pthread_mutex_init(&atomic_lock, NULL);
pthread_mutex_lock(&atomic_lock);
ret = *ptr;
if (*ptr == oldval)
*ptr = newval;
pthread_mutex_unlock(&atomic_lock);
+ pthread_mutex_destroy(&atomic_lock);
+
return ret;
}
-#elif !HAVE_THREADS
+#else /* HAVE_THREADS */
int avpriv_atomic_int_get(volatile int *ptr)
{
@@ -96,11 +111,7 @@ void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
return *ptr;
}
-#else
-
-#error "Threading is enabled, but there is no implementation of atomic operations available"
-
-#endif /* HAVE_PTHREADS */
+#endif /* HAVE_THREADS */
#endif /* !HAVE_MEMORYBARRIER && !HAVE_SYNC_VAL_COMPARE_AND_SWAP && !HAVE_MACHINE_RW_BARRIER */
-------------- next part --------------
diff --git a/libavutil/atomic.c b/libavutil/atomic.c
index 7a701e1..7c5d1db 100644
--- a/libavutil/atomic.c
+++ b/libavutil/atomic.c
@@ -22,38 +22,67 @@
#if !HAVE_MEMORYBARRIER && !HAVE_SYNC_VAL_COMPARE_AND_SWAP && !HAVE_MACHINE_RW_BARRIER
-#if HAVE_PTHREADS
+#if HAVE_THREADS
+#if HAVE_PTHREADS
#include <pthread.h>
static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
+#else
+
+#if HAVE_W32THREADS
+#include "libavcodec/w32pthreads.h"
+#elif HAVE_OS2THREADS
+#include "libavcodec/os2threads.h"
+#endif
+
+static pthread_mutex_t atomic_lock;
+
+#endif
+
+static void atomic_init(void)
+{
+#if HAVE_W32THREADS || HAVE_OS2THREADS
+ pthread_mutex_init(&atomic_lock, NULL);
+#endif
+ pthread_mutex_lock(&atomic_lock);
+}
+
+static void atomic_destroy(void)
+{
+ pthread_mutex_unlock(&atomic_lock);
+#if HAVE_W32THREADS || HAVE_OS2THREADS
+ pthread_mutex_destroy(&atomic_lock);
+#endif
+}
+
int avpriv_atomic_int_get(volatile int *ptr)
{
int res;
- pthread_mutex_lock(&atomic_lock);
+ atomic_init();
res = *ptr;
- pthread_mutex_unlock(&atomic_lock);
+ atomic_destroy();
return res;
}
void avpriv_atomic_int_set(volatile int *ptr, int val)
{
- pthread_mutex_lock(&atomic_lock);
+ atomic_init();
*ptr = val;
- pthread_mutex_unlock(&atomic_lock);
+ atomic_destroy();
}
int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
{
int res;
- pthread_mutex_lock(&atomic_lock);
+ atomic_init();
*ptr += inc;
res = *ptr;
- pthread_mutex_unlock(&atomic_lock);
+ atomic_destroy();
return res;
}
@@ -61,15 +90,16 @@ int avpriv_atomic_int_add_and_fetch(volatile int *ptr, int inc)
void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
{
void *ret;
- pthread_mutex_lock(&atomic_lock);
+ atomic_init();
ret = *ptr;
if (*ptr == oldval)
*ptr = newval;
- pthread_mutex_unlock(&atomic_lock);
+ atomic_destroy();
+
return ret;
}
-#elif !HAVE_THREADS
+#else /* HAVE_THREADS */
int avpriv_atomic_int_get(volatile int *ptr)
{
@@ -96,11 +126,7 @@ void *avpriv_atomic_ptr_cas(void * volatile *ptr, void *oldval, void *newval)
return *ptr;
}
-#else
-
-#error "Threading is enabled, but there is no implementation of atomic operations available"
-
-#endif /* HAVE_PTHREADS */
+#endif /* HAVE_THREADS */
#endif /* !HAVE_MEMORYBARRIER && !HAVE_SYNC_VAL_COMPARE_AND_SWAP && !HAVE_MACHINE_RW_BARRIER */
More information about the ffmpeg-devel
mailing list