summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}