On Tue, Oct 6, 2015 at 7:43 PM, wm4 <[email protected]> wrote:
> On Tue,  6 Oct 2015 12:41:13 +0200
> Hendrik Leppkes <[email protected]> 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(+)
>
> Somewhat related to this patch, we were discussing ways to deal with
> w32thread_init().
>
> Personally, I think we should not have to litter the code with
> w32thread_init() calls. Nor should the user somehow have to make
> sure that this function is somehow called implicitly, when calling
> API functions which use threads.
>
> There are a few ways to handle this:
>
> 1. Don't handle it, but put it e.g. in avcodec_register_all(), and hope
>    the user calls it before calling other APIs which might require it.
> 2. Call it from DllMain() only. This breaks static linking, or requires
>    special care if an application uses a statically linked libav.
> 3. Make w32thread_init() thread-safe, and call it from all entrypoints
>    that need it, like pthread_cond_init() and pthread_once().
>
> Choice 1. is pretty simple, but I think avcodec_register_all() should
> eventually go away. And a lib should not require a global init function
> in general. And there might be API in other sub-libs which require this
> function to be called. It's also hard to guarantee that the API user
> calls it in a safe way when no concurrent calls are possible. I think
> this solution sucks. It's fragile and error-prone.
>
> Using a DllMain() is probably most elegant. It still needs to be put in
> all the sub-libs. It breaks static linking, but nev says static linking
> on Windows is insanity. Maybe that's true, but personally I think it's
> not a good idea to silently break static linking. (Assuming it works
> currently.)
>
> Choice 3. is my favorite. It could work like the XP-compatibility path
> in pthread_once(). (In fact, pthread_once() can be reused for this
> purpose.) Spinning is not a huge problem, because the protected code
> only runs a bunch of GetProcAddress() call, and likely finishes very
> quickly. Performance won't be affected much - it's only an additional
> atomic operation in relatively rare calls like pthread_cond_init()
> (pthread_once() will have to be avoided in performance-critical code
> paths). This code would run on modern Windows releases too, but could
> be disabled completely if compiling for Vista+ targets.
>
> Which way should we go? Suggestions and discussion welcome.

FWIW, i restructured my pthread_once emulation for (3), so the
fallback spinning implementation can be used directly.
See here: https://github.com/Nevcairiel/FFmpeg/commits/pthread_once

It seems ok, i guess. Once the init is done, all it comes down to is
one CAS call and a comparison of the result .. thats not much work.
Both pthread_cond_init and pthread_once should only really be used in
"init" type code, not in performance critical paths, so..

- Hendrik
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to