summaryrefslogtreecommitdiff
path: root/vp8/common/generic
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2012-04-18 16:03:40 -0700
committerJohn Koleszar <jkoleszar@google.com>2012-04-19 14:15:23 -0700
commitc311b3b3a9ceb0e45e0d5969bb20f1e95dbd9059 (patch)
tree57cc8e4cd3ae40bc7dfae43685f40ecc96368bc2 /vp8/common/generic
parent21173e19994a7ffcbdc321c35c8c8ea8e6219b78 (diff)
downloadlibvpx-c311b3b3a9ceb0e45e0d5969bb20f1e95dbd9059.tar
libvpx-c311b3b3a9ceb0e45e0d5969bb20f1e95dbd9059.tar.gz
libvpx-c311b3b3a9ceb0e45e0d5969bb20f1e95dbd9059.tar.bz2
libvpx-c311b3b3a9ceb0e45e0d5969bb20f1e95dbd9059.zip
rtcd: serialize function pointer initialization
Ensure that RTCD function pointers are set at most once, to silence some data race warnings. Implementation provided for POSIX threads and Win32, with the prior unsynchronized behavior left in place for other platforms. Change-Id: I65c5856df43ef67043b3d5f26ddafddd8fcb2f7e
Diffstat (limited to 'vp8/common/generic')
-rw-r--r--vp8/common/generic/systemdependent.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/vp8/common/generic/systemdependent.c b/vp8/common/generic/systemdependent.c
index 39660abaa..2a3016618 100644
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -82,6 +82,58 @@ static int get_cpu_count()
}
#endif
+
+#if HAVE_PTHREAD_H
+#include <pthread.h>
+static void once(void (*func)(void))
+{
+ static pthread_once_t lock = PTHREAD_ONCE_INIT;
+ pthread_once(&lock, func);
+}
+
+
+#elif defined(_WIN32)
+static void once(void (*func)(void))
+{
+ /* Using a static initializer here rather than InitializeCriticalSection()
+ * since there's no race-free context in which to execute it. Protecting
+ * it with an atomic op like InterlockedCompareExchangePointer introduces
+ * an x86 dependency, and InitOnceExecuteOnce requires Vista.
+ */
+ static CRITICAL_SECTION lock = {(void *)-1, -1, 0, 0, 0, 0};
+ static int done;
+
+ EnterCriticalSection(&lock);
+
+ if (!done)
+ {
+ func();
+ done = 1;
+ }
+
+ LeaveCriticalSection(&lock);
+}
+
+
+#else
+/* No-op version that performs no synchronization. vpx_rtcd() is idempotent,
+ * so as long as your platform provides atomic loads/stores of pointers
+ * no synchronization is strictly necessary.
+ */
+
+static void once(void (*func)(void))
+{
+ static int done;
+
+ if(!done)
+ {
+ func();
+ done = 1;
+ }
+}
+#endif
+
+
void vp8_machine_specific_config(VP8_COMMON *ctx)
{
#if CONFIG_MULTITHREAD
@@ -94,5 +146,5 @@ void vp8_machine_specific_config(VP8_COMMON *ctx)
ctx->cpu_caps = x86_simd_caps();
#endif
- vpx_rtcd();
+ once(vpx_rtcd);
}