Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Aug 2006 11:10:59 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 103633 for review
Message-ID:  <200608111110.k7BBAxIO059339@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103633

Change 103633 by rdivacky@rdivacky_witten on 2006/08/11 11:10:09

	Giantify futex code - this is necessary because the futex code is expected to be atomic.
	I need to assure the atomicity. I am using Giant because its sleepable mutex. I hope
	someone will point me to some other better solution. 
	
	This helps my pthread testing program reliably with with upto 37 threads (later it coredumps
	but I think this is userspace issue - its running out of memory for threads and starts
	doing wild things).
	
	Also - update comment in linux_machdep to satisfy netchild.

Affected files ...

.. //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_futex.c#19 edit
.. //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#39 edit

Differences ...

==== //depot/projects/soc2006/rdivacky_linuxolator/compat/linux/linux_futex.c#19 (text+ko) ====

@@ -68,7 +68,7 @@
 };
 
 LIST_HEAD(futex_list, futex) futex_list;
-struct mtx futex_mtx;
+struct mtx futex_mtx;		/* this protects the LIST of futexes */
 
 #define FUTEX_LOCK mtx_lock(&futex_mtx)
 #define FUTEX_UNLOCK mtx_unlock(&futex_mtx)
@@ -76,6 +76,9 @@
 #define FUTEX_LOCKED	1
 #define FUTEX_UNLOCKED	0
 
+#define FUTEX_SYSTEM_LOCK mtx_lock(&Giant)
+#define FUTEX_SYSTEM_UNLOCK mtx_unlock(&Giant)
+
 static struct futex *futex_get(void *, int);
 static void futex_put(struct futex *);
 static int futex_sleep(struct futex *, struct thread *, unsigned long);
@@ -109,17 +112,25 @@
 
 	switch (args->op) {
 	case LINUX_FUTEX_WAIT:
+	   	FUTEX_SYSTEM_LOCK;
+
 		if ((error = copyin(args->uaddr, 
-		    &val, sizeof(val))) != 0)
+		    &val, sizeof(val))) != 0) {
+		   	FUTEX_SYSTEM_UNLOCK;
 			return error;
+		}
 
-		if (val != args->val)
+		if (val != args->val) {
+		   	FUTEX_SYSTEM_UNLOCK;
 			return EWOULDBLOCK;
+		}
 
 		if (args->timeout != NULL) {
 			if ((error = copyin(args->timeout, 
-			    &timeout, sizeof(timeout))) != 0)
+			    &timeout, sizeof(timeout))) != 0) {
+			  	FUTEX_SYSTEM_UNLOCK;
 				return error;
+			}
 		}
 
 #ifdef DEBUG
@@ -157,6 +168,7 @@
 		    		"ret = %d\n", td->td_proc->p_pid, args->uaddr, ret); 
 #endif
 
+		FUTEX_SYSTEM_UNLOCK;
 		switch (ret) {
 		case EWOULDBLOCK:	/* timeout */
 			return ETIMEDOUT;
@@ -184,6 +196,8 @@
 		break;
 		
 	case LINUX_FUTEX_WAKE:
+		FUTEX_SYSTEM_LOCK;
+
 		/* 
 		 * XXX: Linux is able cope with different addresses 
 		 * corresponding to the same mapped memory in the sleeping 
@@ -197,24 +211,43 @@
 		f = futex_get(args->uaddr, FUTEX_UNLOCKED);
 		td->td_retval[0] = futex_wake(f, args->val, NULL);
 		futex_put(f);
+
+		FUTEX_SYSTEM_UNLOCK;
 		break;
 
 	case LINUX_FUTEX_CMP_REQUEUE:
+		FUTEX_SYSTEM_LOCK;
+
 		if ((error = copyin(args->uaddr, 
-		    &val, sizeof(val))) != 0)
+		    &val, sizeof(val))) != 0) {
+		   	FUTEX_SYSTEM_UNLOCK;
 			return error;
+		}
 
-		if (val != args->val3)
+		if (val != args->val3) {
+		   	FUTEX_SYSTEM_UNLOCK;
 			return EAGAIN;
-		/* FALLTHROUGH */
+		}
+
+		f = futex_get(args->uaddr, FUTEX_UNLOCKED);
+		newf = futex_get(args->uaddr2, FUTEX_UNLOCKED);
+		td->td_retval[0] = futex_wake(f, args->val, newf);
+		futex_put(f);
+		futex_put(newf);
+
+		FUTEX_SYSTEM_UNLOCK;
+		break;
 
 	case LINUX_FUTEX_REQUEUE:
+		FUTEX_SYSTEM_LOCK;
+		
 		f = futex_get(args->uaddr, FUTEX_UNLOCKED);
 		newf = futex_get(args->uaddr2, FUTEX_UNLOCKED);
 		td->td_retval[0] = futex_wake(f, args->val, newf);
 		futex_put(f);
 		futex_put(newf);
 		
+		FUTEX_SYSTEM_UNLOCK;
 		break;
 
 	case LINUX_FUTEX_FD:
@@ -223,6 +256,7 @@
 		break;
 
 	case LINUX_FUTEX_WAKE_OP:
+		FUTEX_SYSTEM_LOCK;
 #ifdef DEBUG
 		if (ldebug(sys_futex))
    		   	printf("FUTEX_WAKE_OP: %d: uaddr = %p, op = %d, val = %d, uaddr2 = %p, val3 = %d\n",
@@ -238,12 +272,14 @@
 		   	if (op_ret != -EFAULT) {
 			   	futex_put(f);
 			   	futex_put(f2);
+				FUTEX_SYSTEM_UNLOCK;
 			   	return (-op_ret);
 			}
 
 			futex_put(f);
 			futex_put(f2);
 
+		   	FUTEX_SYSTEM_UNLOCK;
 			return (EFAULT);
 
 		}
@@ -259,6 +295,8 @@
 		}
 		futex_put(f2);
 		td->td_retval[0] = ret;
+
+		FUTEX_SYSTEM_UNLOCK;
 	   	break;
 
 	default:

==== //depot/projects/soc2006/rdivacky_linuxolator/i386/linux/linux_machdep.c#39 (text+ko) ====

@@ -1168,7 +1168,7 @@
    		MALLOC(em, struct linux_emuldata *, sizeof *em, M_LINUX, M_WAITOK | M_ZERO);
 		em->pid = child;
 		if (flags & CLONE_VM) {
-		   	/* handled later */
+		   	/* handled later in the code */
 		} else {
 		   	struct linux_emuldata_shared *s;
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608111110.k7BBAxIO059339>