patch-2.2.6 linux/include/asm-alpha/semaphore.h

Next file: linux/include/asm-alpha/uaccess.h
Previous file: linux/include/asm-alpha/semaphore-helper.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.5/linux/include/asm-alpha/semaphore.h linux/include/asm-alpha/semaphore.h
@@ -115,42 +115,46 @@
 
 extern inline int down_trylock(struct semaphore * sem)
 {
-	long ret, tmp, tmp2;
+	long ret, tmp, tmp2, sub;
 
 	/* "Equivalent" C.  Note that we have to do this all without
 	   (taken) branches in order to be a valid ll/sc sequence.
 
 	   do {
 	       tmp = ldq_l;
-	       ret = 0;
-	       tmp -= 1;
-	       if ((int)tmp < 0)		// count
-	           break;
-	       if ((long)tmp < 0)		// waking
-	           break;
-	       tmp += 0xffffffff00000000;
-	       ret = 1;
+	       sub = 0x0000000100000000;
+	       ret = ((int)tmp <= 0);		// count =< 0 ?
+	       if ((int)tmp >= 0) sub = 0;	// count >= 0 ?
+			// note that if count=0 subq overflows to the high
+			// longword (i.e waking)
+	       ret &= ((long)tmp < 0);		// waking < 0 ?
+	       sub += 1;
+	       if (ret) 
+			break;	
+	       tmp -= sub;
 	       tmp = stq_c = tmp;
 	   } while (tmp == 0);
 	*/
 
 	__asm__ __volatile__(
-		"1:	ldq_l	%1,%3\n"
-		"	lda	%0,0\n"
-		"	subl	%1,1,%2\n"
-		"	subq	%1,1,%1\n"
-		"	blt	%2,2f\n"
-		"	blt	%1,2f\n"
-		"	ldah	%1,-32768(%1)\n"
-		"	ldah	%1,-32768(%1)\n"
-		"	lda	%0,1\n"
-		"	stq_c	%1,%3\n"
+		"1:	ldq_l	%1,%4\n"
+		"	lda	%3,1\n"
+		"	addl	%1,0,%2\n"
+		"	sll	%3,32,%3\n"
+		"	cmple	%2,0,%0\n"
+		"	cmovge	%2,0,%3\n"
+		"	cmplt	%1,0,%2\n"
+		"	addq	%3,1,%3\n"
+		"	and	%0,%2,%0\n"
+		"	bne	%0,2f\n"
+		"	subq	%1,%3,%1\n"
+		"	stq_c	%1,%4\n"
 		"	beq	%1,3f\n"
-		"2:	mb\n"
+		"2:\n"
 		".section .text2,\"ax\"\n"
 		"3:	br	1b\n"
 		".previous"
-		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2)
+		: "=&r"(ret), "=&r"(tmp), "=&r"(tmp2), "=&r"(sub)
 		: "m"(*sem)
 		: "memory");
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)