[PATCH?] Separate pthread patches, #2 take 2.

Dave Korn dave.korn.cygwin@googlemail.com
Wed Jun 3 23:13:00 GMT 2009

  The attached patch implements ilockexch and ilockcmpexch, using the inline
asm definition from __arch_compare_and_exchange_val_32_acq in
glibc-2.10.1/sysdeps/i386/i486/bits/atomic.h, trivially expanded inline rather
than in its original preprocessor macro form.

  It generates incorrect code.  The sequence discussed before,

126	  do
127	    node->next = head;
128	  while (InterlockedCompareExchangePointer (&head, node, node->next) !=

is now compiled down to this loop:

	.loc 3 127 0
	movl	__ZN13pthread_mutex7mutexesE+8, %edx	 # mutexes.head, D.28599
	.loc 2 58 0
	movl	%edx, %eax	 # D.28599, tmp68
 # 58 "/gnu/winsup/src/winsup/cygwin/winbase.h" 1
	lock cmpxchgl %ebx, __ZN13pthread_mutex7mutexesE+8	 # this,
 # 0 "" 2
	movl	%eax, -12(%ebp)	 # tmp68, ret
	.loc 2 59 0
	movl	-12(%ebp), %eax	 # ret, D.28596
	.loc 3 126 0
	cmpl	%eax, %edx	 # D.28596, D.28599
	jne	L186	 #,
	movl	%edx, 36(%ebx)	 # D.28599, <variable>.next

... which is in fact the equivalent of

126	  do
127	    ;
128	  while (InterlockedCompareExchangePointer (&head, node, node->next) !=
(126)     node->next = head;

  As it caches the values of head in %edx during the spin loop, and only
stores it to node->next after having overwritten *head with node, there is a
short window after the new node is linked to the front of the chain during
which its chain pointer is incorrect.

  Not OK for head?


-------------- next part --------------
A non-text attachment was scrubbed...
Name: pthread-interlocked-asms-v2.diff
Type: text/x-c
Size: 1502 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin-patches/attachments/20090603/348e7426/attachment.bin>

More information about the Cygwin-patches mailing list