Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Aug 2004 04:04:43 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 59052 for review
Message-ID:  <200408070404.i7744hLV042429@repoman.freebsd.org>

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

Change 59052 by davidxu@davidxu_alona on 2004/08/07 04:04:28

	add pl_flags into struct ptrace_lwpinfo to indicate a SA thread
	is in critical region.

Affected files ...

.. //depot/projects/davidxu_ksedbg/src/sys/kern/kern_kse.c#12 edit
.. //depot/projects/davidxu_ksedbg/src/sys/kern/sys_process.c#15 edit
.. //depot/projects/davidxu_ksedbg/src/sys/sys/kse.h#8 edit
.. //depot/projects/davidxu_ksedbg/src/sys/sys/ptrace.h#9 edit

Differences ...

==== //depot/projects/davidxu_ksedbg/src/sys/kern/kern_kse.c#12 (text+ko) ====

@@ -185,6 +185,9 @@
 {
 	struct proc *p;
 	struct thread *td2;
+	struct kse_upcall *ku;
+	struct kse_thr_mailbox *tmbx;
+	uint32_t flags;
 
 	p = td->td_proc;
 
@@ -236,6 +239,30 @@
 		PROC_LOCK(p);
 		sigexit(td, (int)uap->data);
 		break;
+
+	case KSE_INTR_DBSUSPEND:
+		/* this sub-function is only for bound thread */
+		if (td->td_pflags & TDP_SA)
+			return (EINVAL);
+		ku = td->td_upcall;
+		tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
+		if (tmbx == NULL || tmbx == (void *)-1)
+			return (EINVAL);
+		flags = 0;
+		while ((p->p_flag & P_TRACED) && !(p->p_flag & P_SINGLE_EXIT)) {
+			flags = fuword32(&tmbx->tm_dflags);
+			if (!(flags & TMDF_SUSPEND))
+				break;
+			PROC_LOCK(p);
+			mtx_lock_spin(&sched_lock);
+			thread_stopped(p);
+			thread_suspend_one(td);
+			PROC_UNLOCK(p);
+			mi_switch(SW_VOL, NULL);
+			mtx_unlock_spin(&sched_lock);
+		}
+		return (0);
+
 	default:
 		return (EINVAL);
 	}
@@ -1078,10 +1105,14 @@
 	 * If it is a short term event, just suspend it in
 	 * a way that takes its KSE with it.
 	 * Select the events for which we want to schedule upcalls.
-	 * For now it's just sleep.
+	 * For now it's just sleep or if thread is suspended but
+	 * not process wide suspending flag is not set (debugger
+	 * suspends thread).
 	 * XXXKSE eventually almost any inhibition could do.
 	 */
-	if (TD_CAN_UNBIND(td) && (td->td_standin) && TD_ON_SLEEPQ(td)) {
+	if (TD_CAN_UNBIND(td) && (td->td_standin) &&
+	    (TD_ON_SLEEPQ(td) || (TD_IS_SUSPENDED(td) &&
+	     !P_SHOULDSTOP(td->td_proc)))) {
 		/*
 		 * Release ownership of upcall, and schedule an upcall
 		 * thread, this new upcall thread becomes the owner of
@@ -1134,14 +1165,14 @@
 	KASSERT(ku->ku_owner == td, ("wrong owner"));
 	KASSERT(!TD_CAN_UNBIND(td), ("can unbind"));
 
+	if (td->td_standin == NULL)
+		thread_alloc_spare(td);
 	ku->ku_mflags = fuword32((void *)&ku->ku_mailbox->km_flags);
 	tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
 	if ((tmbx == NULL) || (tmbx == (void *)-1L) ||
 	    (ku->ku_mflags & KMF_NOUPCALL)) {
 		td->td_mailbox = NULL;
 	} else {
-		if (td->td_standin == NULL)
-			thread_alloc_spare(td);
 		flags = fuword32(&tmbx->tm_flags);
 		/*
 		 * On some architectures, TP register points to thread
@@ -1210,16 +1241,6 @@
 		td->td_pflags &= ~TDP_USTATCLOCK;
 	}
 
-	/*
-	 * Check if we should unbind and schedule upcall
-	 * after returned from interrupt or etcs, this
-	 * is usually true when process is being debugged.
-	 */
-	if (td->td_mailbox == NULL && ku != NULL &&
-	    !(td->td_pflags & TDP_UPCALLING) &&
-	    (kg->kg_completed || ku->ku_flags & KUF_DOUPCALL))
-		thread_user_enter(p, td);
-
 	uts_crit = (td->td_mailbox == NULL);
 	/*
 	 * Optimisation:
@@ -1372,12 +1393,6 @@
 	}
 
 	ku->ku_mflags = 0;
-	/*
-	 * Clear thread mailbox first, then clear system tick count.
-	 * The order is important because thread_statclock() use
-	 * mailbox pointer to see if it is an userland thread or
-	 * an UTS kernel thread.
-	 */
 	td->td_mailbox = NULL;
 	td->td_usticks = 0;
 	return (error);	/* go sync */

==== //depot/projects/davidxu_ksedbg/src/sys/kern/sys_process.c#15 (text+ko) ====

@@ -807,19 +807,13 @@
 			else
 				pl->pl_event = 0;
 		}
-		if (!(td2->td_pflags & TDP_SA)) {
-			printf("not sa\n");
-			pl->pl_bound = 1;
+		if (td2->td_pflags & TDP_SA) {
+			pl->pl_flags = PL_FLAG_SA;
+			if (td2->td_upcall && !TD_CAN_UNBIND(td2))
+				pl->pl_flags |= PL_FLAG_BOUND;
+		} else {
+			pl->pl_flags = 0;
 		}
-		else if (td2->td_upcall == NULL) {
-			pl->pl_bound = 0;
-			printf("upcall == NULL\n");
-		}
-		else if (TD_CAN_UNBIND(td2)) {
-			pl->pl_bound = 0;
-			printf("lwp=%d can unbind\n", saved_pid);
-		} else
-			pl->pl_bound = 1;
 		_PRELE(p);
 		PROC_UNLOCK(p);
 		return (0);

==== //depot/projects/davidxu_ksedbg/src/sys/sys/kse.h#8 (text+ko) ====

@@ -107,10 +107,11 @@
 #define KSE_SWITCHIN_SETTMBX	0x01
 
 /* Commands for kse_thr_interrupt */
-#define KSE_INTR_INTERRUPT	0x01
-#define KSE_INTR_RESTART	0x02
-#define KSE_INTR_SENDSIG	0x03
-#define KSE_INTR_SIGEXIT	0x04
+#define KSE_INTR_INTERRUPT	1
+#define KSE_INTR_RESTART	2
+#define KSE_INTR_SENDSIG	3
+#define KSE_INTR_SIGEXIT	4
+#define KSE_INTR_DBSUSPEND	5
 
 #ifndef _KERNEL
 int	kse_create(struct kse_mailbox *, int);

==== //depot/projects/davidxu_ksedbg/src/sys/sys/ptrace.h#9 (text+ko) ====

@@ -89,7 +89,9 @@
 	int	pl_event;	/* Event that stopped the LWP. */
 #define	PL_EVENT_NONE	0
 #define	PL_EVENT_SIGNAL	1
-	int	pl_bound;
+	int	pl_flags;	/* LWP flags. */
+#define	PL_FLAG_SA	0x01	/* M:N thread */
+#define	PL_FLAG_BOUND	0x02	/* M:N bound thread */
 };
 
 #ifdef _KERNEL



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