about summary refs log tree commit diff
path: root/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S')
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S35
1 files changed, 25 insertions, 10 deletions
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
index f6b6ab246c..80cbf7e430 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
@@ -51,7 +51,8 @@ __pthread_cond_timedwait:
 .Lpush_r13:
 	pushq	%r14
 .Lpush_r14:
-	subq	$80, %rsp
+#define FRAME_SIZE 80
+	subq	$FRAME_SIZE, %rsp
 .Lsubq:
 	/* Stack frame:
 
@@ -67,6 +68,8 @@ __pthread_cond_timedwait:
 	            +--------------------------+
 	   rsp +  8 | condvar pointer          |
 	            +--------------------------+
+	   rsp +  4 | old broadcast_seq value  |
+	            +--------------------------+
 	   rsp +  0 | old cancellation mode    |
 	            +--------------------------+
 	*/
@@ -116,7 +119,9 @@ __pthread_cond_timedwait:
 	/* Get and store current wakeup_seq value.  */
 	movq	8(%rsp), %rdi
 	movq	wakeup_seq(%rdi), %r12
+	movl	broadcast_seq(%rdi), %edx
 	movq	%r12, 40(%rsp)
+	movl	%edx, 4(%rsp)
 
 	/* Get the current time.  */
 8:
@@ -160,7 +165,8 @@ __pthread_cond_timedwait:
 	decq	%rcx
 12:	testq	%rcx, %rcx
 	movq	8(%rsp), %rdi
-	js	13f
+	movq	$-ETIMEDOUT, %r14
+	js	6f
 
 	/* Store relative timeout.  */
 21:	movq	%rcx, 24(%rsp)
@@ -201,10 +207,15 @@ __pthread_cond_timedwait:
 #endif
 	jne	5f
 
-6:	movq	woken_seq(%rdi), %rax
+6:	movl	broadcast_seq(%rdi), %edx
+
+	movq	woken_seq(%rdi), %rax
 
 	movq	wakeup_seq(%rdi), %r12
 
+	cmpl	4(%rsp), %edx
+	jne	23f
+
 	cmpq	40(%rsp), %r12
 	jbe	15f
 
@@ -218,10 +229,13 @@ __pthread_cond_timedwait:
 	movq	$ETIMEDOUT, %r14
 	jmp	14f
 
+23:	xorq	%r14, %r14
+	jmp	24f
+
 9:	xorq	%r14, %r14
 14:	incq	woken_seq(%rdi)
 
-	LOCK
+24:	LOCK
 #if cond_lock == 0
 	decl	(%rdi)
 #else
@@ -239,7 +253,7 @@ __pthread_cond_timedwait:
 	testq	%rax, %rax
 	cmoveq	%r14, %rax
 
-18:	addq	$80, %rsp
+18:	addq	$FRAME_SIZE, %rsp
 .Laddq:
 	popq	%r14
 .Lpop_r14:
@@ -259,7 +273,7 @@ __pthread_cond_timedwait:
 	callq	__lll_mutex_lock_wait
 	jmp	2b
 
-	/* Unlock in loop requires waekup.  */
+	/* Unlock in loop requires wakeup.  */
 3:
 #if cond_lock != 0
 	addq	$cond_lock, %rdi
@@ -278,7 +292,7 @@ __pthread_cond_timedwait:
 #endif
 	jmp	6b
 
-	/* Unlock after loop requires waekup.  */
+	/* Unlock after loop requires wakeup.  */
 10:
 #if cond_lock != 0
 	addq	$cond_lock, %rdi
@@ -325,7 +339,8 @@ __pthread_cond_timedwait:
 	decq	%rcx
 20:	testq	%rcx, %rcx
 	movq	8(%rsp), %rdi
-	js	13b
+	movq	$-ETIMEDOUT, %r14
+	js	6b
 	jmp	21b
 #endif
 .LENDCODE:
@@ -394,7 +409,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
 	.uleb128 4
 	.byte	0x40+.Lsubq-.Lpush_r14		# DW_CFA_advance_loc+N
 	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 112
+	.uleb128 32+FRAME_SIZE
 	.byte	3				# DW_CFA_advance_loc2
 	.2byte	.Laddq-.Lsubq
 	.byte	14				# DW_CFA_def_cfa_offset
@@ -413,7 +428,7 @@ versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
 	.byte	0xcc				# DW_CFA_restore %r12
 	.byte	0x40+.LSbl1-.Lpop_r12		# DW_CFA_advance_loc+N
 	.byte	14				# DW_CFA_def_cfa_offset
-	.uleb128 112
+	.uleb128 32+FRAME_SIZE
 	.byte	0x8c				# DW_CFA_offset %r12
 	.uleb128 2
 	.byte	0x8d				# DW_CFA_offset %r13