On Wed, Oct 7, 2015 at 6:29 PM, Hendrik Leppkes <h.lepp...@gmail.com> wrote: > On Wed, Oct 7, 2015 at 6:23 PM, Matt Oliver <protogo...@gmail.com> wrote: >> On 6 October 2015 at 21:36, Hendrik Leppkes <h.lepp...@gmail.com> wrote: >> >>> The emulation uses native InitOnce* APIs on Windows Vista+, and a >>> lock-free/allocation-free approach using atomics and spinning for Windows >>> XP. >>> --- >>> >>> This is in preparation to use pthread_once for global static init >>> functions, >>> and eventually removing the global lock in avcodec_open2 >>> >>> compat/w32pthreads.h | 68 >>> ++++++++++++++++++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 68 insertions(+) >>> >>> diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h >>> index deb1c53..8523976 100644 >>> --- a/compat/w32pthreads.h >>> +++ b/compat/w32pthreads.h >>> @@ -154,6 +154,19 @@ static inline int pthread_cond_signal(pthread_cond_t >>> *cond) >>> return 0; >>> } >>> >>> +typedef INIT_ONCE pthread_once_t; >>> +#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT >>> + >>> +static av_unused int pthread_once(pthread_once_t *once_control, void >>> (*init_routine)(void)) >>> +{ >>> + BOOL pending = FALSE; >>> + InitOnceBeginInitialize(once_control, 0, &pending, NULL); >>> + if (pending) >>> + init_routine(); >>> + InitOnceComplete(once_control, 0, NULL); >>> + return 0; >>> +} >>> + >>> #else // _WIN32_WINNT < 0x0600 >>> /* for pre-Windows 6.0 platforms we need to define and use our own >>> condition >>> * variable and api */ >>> @@ -304,6 +317,57 @@ static av_unused int >>> pthread_cond_signal(pthread_cond_t *cond) >>> pthread_mutex_unlock(&win32_cond->mtx_broadcast); >>> return 0; >>> } >>> + >>> +/* for pre-Windows 6.0 platforms, define INIT_ONCE struct, >>> + * compatible to the one used in the native API */ >>> + >>> +typedef union pthread_once_t { >>> + void * Ptr; ///< For the Windows 6.0+ native functions >>> + LONG state; ///< For the pre-Windows 6.0 compat code >>> +} pthread_once_t; >>> + >>> +#define PTHREAD_ONCE_INIT {0} >>> + >>> +/* function pointers to init once API on windows 6.0+ kernels */ >>> +static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD >>> dwFlags, BOOL *fPending, void **lpContext); >>> +static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce, DWORD >>> dwFlags, void *lpContext); >>> + >>> +static av_unused int pthread_once(pthread_once_t *once_control, void >>> (*init_routine)(void)) >>> +{ >>> + /* Use native functions on Windows 6.0+ */ >>> + if (initonce_begin && initonce_complete) >>> + { >>> + BOOL pending = FALSE; >>> + initonce_begin(once_control, 0, &pending, NULL); >>> + if (pending) >>> + init_routine(); >>> + initonce_complete(once_control, 0, NULL); >>> + return 0; >>> + } >>> + >>> + /* pre-Windows 6.0 compat using a spin-lock */ >>> + switch (InterlockedCompareExchange(&once_control->state, 1, 0)) >>> + { >>> + /* Initial run */ >>> + case 0: >>> + init_routine(); >>> + InterlockedExchange(&once_control->state, 2); >>> + break; >>> + /* Another thread is running init */ >>> + case 1: >>> + while (1) { >>> + MemoryBarrier(); >>> + if (once_control->state == 2) >>> + break; >>> + Sleep(0); >>> + } >>> + break; >>> + /* Initialization complete */ >>> + case 2: >>> + break; >>> + } >>> + return 0; >>> +} >>> #endif >>> >>> static av_unused void w32thread_init(void) >>> @@ -319,6 +383,10 @@ static av_unused void w32thread_init(void) >>> (void*)GetProcAddress(kernel_dll, "WakeConditionVariable"); >>> cond_wait = >>> (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS"); >>> + initonce_begin = >>> + (void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize"); >>> + initonce_complete = >>> + (void*)GetProcAddress(kernel_dll, "InitOnceComplete"); >>> #endif >>> >>> } >>> -- >>> 2.5.3.windows.1 >> >> >> LGTM > > There is a new version of the patch which also solves the > w32thread_init mess, so this one isn't the final version anymore. > Current working version is here: > https://github.com/Nevcairiel/FFmpeg/commits/pthread_once >
This version has been applied. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel