[libdispatch-dev] lib dispatch worker threads may loop depending on compiler optimization
Kevin Van Vechten
kvv at apple.com
Tue Sep 20 08:54:01 PDT 2011
Great find!
On Sep 20, 2011, at 12:48 AM, Paolo Bonzini wrote:
> On 09/19/2011 06:32 PM, Joakim Johansson wrote:
>> <http://libdispatch.macosforge.org/trac/ticket/35#comment:10>
>
> Thanks. It turns out it is _not_ a bug in GCC at all, but in libdispatch.
>
> Compiling the .i file shows the following:
>
> movq %r13, %rax
> movq $1, 0(%r13)
> movq %r12, 16(%r13)
> #APP
> # 110 "/tb/builds/thd/sbn/2.4/src/thirdparty/libdispatch/197/src/src/queue_internal.h" 1
> xchg %rax, 64(%rbx)
> # 0 "" 2
> #NO_APP
> testq %rax, %rax
> movq %rbp, 24(%r13)
> movq $0, 8(%r13)
> je .L172
>
>
> The APP/NO_APP markers signify that an asm is being used rather than sync
> builtins. Looking at the source code indeed reveals this...
>
> // GCC generates suboptimal register pressure
> // LLVM does better, but doesn't support tail calls
> // 6248590 __sync_*() intrinsics force a gratuitous "lea" instruction, with resulting register pressure
> #if 0 && defined(__i386__) || defined(__x86_64__)
> #define dispatch_atomic_xchg(p, n) ({ typeof(*(p)) _r; asm("xchg %0, %1" : "=r" (_r) : "m" (*(p)), "0" (n)); _r; })
> #else
> #define dispatch_atomic_xchg(p, n) ((typeof(*(p)))__sync_lock_test_and_set((p), (n)))
> #endif
>
>
> ... which is missing parentheses like
>
> #if 0 && (defined(__i386__) || defined(__x86_64__))
>
> The asm is wrong, because it doesn't have a clobber for "memory".
> That fixes the testcase.
>
> Paolo
> _______________________________________________
> libdispatch-dev mailing list
> libdispatch-dev at lists.macosforge.org
> http://lists.macosforge.org/mailman/listinfo.cgi/libdispatch-dev
More information about the libdispatch-dev
mailing list