From 8df79e9d427fe2e334f110a8abfe3e43449d87c4 Mon Sep 17 00:00:00 2001 From: John Koleszar Date: Fri, 15 Jun 2012 15:40:13 -0700 Subject: [PATCH] Remove threading dependencies with --disable-multithread Avoid a pthreads dependency via pthread_once() when compiled with --disable-multithread. In addition, this synchronization is disabled for Win32 as well, even though we can be sure that the required primatives exist, so that the requirements on the application when built with --disable-multithread are consistent across platforms. Users using libvpx built with --disable-multithread in a multithreaded context should provide their own synchronization. Updated the documentation to vpx_codec_enc_init_ver() and vpx_codec_dec_init_ver() to note this requirement. Moved the RTCD initialization call to match this description, as previously it didn't happen until the first frame. Change-Id: Id576f6bce2758362188278d3085051c218a56d4a --- build/make/rtcd.sh | 13 ++++---- vp8/common/generic/systemdependent.c | 53 --------------------------------- vp8/common/rtcd.c | 57 ++++++++++++++++++++++++++++++++++++ vp8/vp8_cx_iface.c | 3 ++ vp8/vp8_dx_iface.c | 3 ++ vpx/vpx_decoder.h | 4 +++ vpx/vpx_encoder.h | 4 +++ 7 files changed, 76 insertions(+), 61 deletions(-) diff --git a/build/make/rtcd.sh b/build/make/rtcd.sh index 1dffde5..2123aa1 100755 --- a/build/make/rtcd.sh +++ b/build/make/rtcd.sh @@ -211,6 +211,8 @@ common_top() { $(process_forward_decls) $(declare_function_pointers c $ALL_ARCHS) + +void ${symbol:-rtcd}(void); EOF } @@ -231,11 +233,10 @@ x86() { cat < -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 @@ -145,6 +94,4 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) #elif ARCH_X86 || ARCH_X86_64 ctx->cpu_caps = x86_simd_caps(); #endif - - once(vpx_rtcd); } diff --git a/vp8/common/rtcd.c b/vp8/common/rtcd.c index 232640d..4980f48 100644 --- a/vp8/common/rtcd.c +++ b/vp8/common/rtcd.c @@ -10,3 +10,60 @@ #include "vpx_config.h" #define RTCD_C #include "vpx_rtcd.h" + +#if CONFIG_MULTITHREAD && HAVE_PTHREAD_H +#include +static void once(void (*func)(void)) +{ + static pthread_once_t lock = PTHREAD_ONCE_INIT; + pthread_once(&lock, func); +} + + +#elif CONFIG_MULTITHREAD && defined(_WIN32) +#include +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 vpx_rtcd() +{ + once(setup_rtcd_internal); +} diff --git a/vp8/vp8_cx_iface.c b/vp8/vp8_cx_iface.c index 9671107..a499825 100644 --- a/vp8/vp8_cx_iface.c +++ b/vp8/vp8_cx_iface.c @@ -9,6 +9,7 @@ */ +#include "vpx_rtcd.h" #include "vpx/vpx_codec.h" #include "vpx/internal/vpx_codec_internal.h" #include "vpx_version.h" @@ -572,6 +573,8 @@ static vpx_codec_err_t vp8e_init(vpx_codec_ctx_t *ctx, struct VP8_COMP *optr; + vpx_rtcd(); + if (!ctx->priv) { priv = calloc(1, sizeof(struct vpx_codec_alg_priv)); diff --git a/vp8/vp8_dx_iface.c b/vp8/vp8_dx_iface.c index 37773db..fe8c9a0 100644 --- a/vp8/vp8_dx_iface.c +++ b/vp8/vp8_dx_iface.c @@ -11,6 +11,7 @@ #include #include +#include "vpx_rtcd.h" #include "vpx/vpx_decoder.h" #include "vpx/vp8dx.h" #include "vpx/internal/vpx_codec_internal.h" @@ -187,6 +188,8 @@ static vpx_codec_err_t vp8_init(vpx_codec_ctx_t *ctx, vpx_codec_err_t res = VPX_CODEC_OK; (void) data; + vpx_rtcd(); + /* This function only allocates space for the vpx_codec_alg_priv_t * structure. More memory may be required at the time the stream * information becomes known. diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h index 7992cc4..1ccf1c5 100644 --- a/vpx/vpx_decoder.h +++ b/vpx/vpx_decoder.h @@ -113,6 +113,10 @@ extern "C" { * function directly, to ensure that the ABI version number parameter * is properly initialized. * + * If the library was configured with --disable-multithread, this call + * is not thread safe and should be guarded with a lock if being used + * in a multithreaded context. + * * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the flags * parameter), the storage pointed to by the cfg parameter must be * kept readable and stable until all memory maps have been set. diff --git a/vpx/vpx_encoder.h b/vpx/vpx_encoder.h index 239036e..67d9033 100644 --- a/vpx/vpx_encoder.h +++ b/vpx/vpx_encoder.h @@ -655,6 +655,10 @@ extern "C" { * function directly, to ensure that the ABI version number parameter * is properly initialized. * + * If the library was configured with --disable-multithread, this call + * is not thread safe and should be guarded with a lock if being used + * in a multithreaded context. + * * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the flags * parameter), the storage pointed to by the cfg parameter must be * kept readable and stable until all memory maps have been set. -- 2.7.4