PERFORCE change 56959 for review
David Xu
davidxu at FreeBSD.org
Sat Jul 10 07:04:37 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=56959
Change 56959 by davidxu at davidxu_alona on 2004/07/10 14:03:38
Check TMDF_DONOTRUNUSER when being debugged. If the flag is set by
debugger, the current thread should relinquish CPU after left critical
region, UTS should select a thread without TMDF_DONOTRUNUSER set
in mailbox to run.
Affected files ...
.. //depot/projects/davidxu_ksedbg/src/lib/libpthread/thread/thr_kern.c#4 edit
.. //depot/projects/davidxu_ksedbg/src/lib/libpthread/thread/thr_priority_queue.c#2 edit
.. //depot/projects/davidxu_ksedbg/src/lib/libpthread/thread/thr_private.h#5 edit
Differences ...
==== //depot/projects/davidxu_ksedbg/src/lib/libpthread/thread/thr_kern.c#4 (text+ko) ====
@@ -99,7 +99,10 @@
_pq_insert_tail(&(kse)->k_schedq->sq_runq, thrd)
#define KSE_RUNQ_REMOVE(kse, thrd) \
_pq_remove(&(kse)->k_schedq->sq_runq, thrd)
-#define KSE_RUNQ_FIRST(kse) _pq_first(&(kse)->k_schedq->sq_runq)
+#define KSE_RUNQ_FIRST(kse) \
+ ((_libkse_debug == 0) ? \
+ _pq_first(&(kse)->k_schedq->sq_runq) : \
+ _pq_first_debug(&(kse)->k_schedq->sq_runq))
#define KSE_RUNQ_THREADS(kse) ((kse)->k_schedq->sq_runq.pq_threads)
@@ -2517,3 +2520,27 @@
}
return (NULL);
}
+
+void
+_thr_debug_check_yield(struct pthread *curthread)
+{
+ /*
+ * Note that TMDF_DONOTRUNUSER is set after process is suspended.
+ * When we are being debugged, every suspension in process
+ * will cause all KSEs to schedule an upcall in kernel, unless the
+ * KSE is in critical region.
+ * If the function is being called, it means the KSE is no longer
+ * in critical region, if the TMDF_DONOTRUNUSER is set by debugger
+ * before KSE leaves critical region, we will catch it here, else
+ * if the flag is changed during testing, it also not a problem,
+ * because the change only occurs after a process suspension event
+ * occurs. A suspension event will always cause KSE to schedule an
+ * upcall, in the case, because we are not in critical region,
+ * upcall will be scheduled sucessfully, the flag will be checked
+ * again in kse_sched_multi, we won't back until the flag
+ * is cleared by debugger, the flag will be cleared in next
+ * suspension event.
+ */
+ if (curthread->tcb->tcb_tmbx.tm_dflags & TMDF_DONOTRUNUSER)
+ _thr_sched_switch(curthread);
+}
==== //depot/projects/davidxu_ksedbg/src/lib/libpthread/thread/thr_priority_queue.c#2 (text+ko) ====
@@ -242,6 +242,46 @@
return (pthread);
}
+/*
+ * Select a thread which is allowed to run by debugger, we probably
+ * should merge the function into _pq_first if that function is only
+ * used by scheduler to select a thread.
+ */
+pthread_t
+_pq_first_debug(pq_queue_t *pq)
+{
+ pq_list_t *pql;
+ pthread_t pthread = NULL;
+
+ /*
+ * Make some assertions when debugging is enabled:
+ */
+ PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active");
+ PQ_SET_ACTIVE(pq);
+
+ while (((pql = TAILQ_FIRST(&pq->pq_queue)) != NULL) &&
+ (pthread == NULL)) {
+ if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) {
+ /*
+ * The priority list is empty; remove the list
+ * from the queue.
+ */
+ TAILQ_REMOVE(&pq->pq_queue, pql, pl_link);
+
+ /* Mark the list as not being in the queue: */
+ pql->pl_queued = 0;
+ } else {
+ while (pthread != NULL && !THR_IN_CRITICAL(pthread) &&
+ (pthread->tcb->tcb_tmbx.tm_dflags &
+ TMDF_DONOTRUNUSER)) {
+ pthread = TAILQ_NEXT(pthread, pqe);
+ }
+ }
+ }
+
+ PQ_CLEAR_ACTIVE(pq);
+ return (pthread);
+}
static void
pq_insert_prio_list(pq_queue_t *pq, int prio)
==== //depot/projects/davidxu_ksedbg/src/lib/libpthread/thread/thr_private.h#5 (text+ko) ====
@@ -820,12 +820,14 @@
#define THR_YIELD_CHECK(thrd) \
do { \
- if (((thrd)->critical_yield != 0) && \
- !(THR_IN_CRITICAL(thrd))) \
- _thr_sched_switch(thrd); \
- else if (((thrd)->check_pending != 0) && \
- !(THR_IN_CRITICAL(thrd))) \
- _thr_sig_check_pending(thrd); \
+ if (!THR_IN_CRITICAL(thrd)) { \
+ if (__predict_false(_libkse_debug)) \
+ _thr_debug_check_yield(thrd); \
+ if ((thrd)->critical_yield != 0) \
+ _thr_sched_switch(thrd); \
+ if ((thrd)->check_pending != 0) \
+ _thr_sig_check_pending(thrd); \
+ } \
} while (0)
#define THR_LOCK_ACQUIRE(thrd, lck) \
@@ -886,8 +888,6 @@
_pq_insert_tail(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
#define THR_RUNQ_REMOVE(thrd) \
_pq_remove(&(thrd)->kseg->kg_schedq.sq_runq, thrd)
-#define THR_RUNQ_FIRST(thrd) \
- _pq_first(&(thrd)->kseg->kg_schedq.sq_runq)
/*
* Macros to insert/remove threads to the all thread list and
@@ -1086,6 +1086,7 @@
void _pq_insert_head(struct pq_queue *pq, struct pthread *);
void _pq_insert_tail(struct pq_queue *pq, struct pthread *);
struct pthread *_pq_first(struct pq_queue *pq);
+struct pthread *_pq_first_debug(struct pq_queue *pq);
void *_pthread_getspecific(pthread_key_t);
int _pthread_key_create(pthread_key_t *, void (*) (void *));
int _pthread_key_delete(pthread_key_t);
@@ -1157,6 +1158,7 @@
struct pthread *_thr_hash_find(struct pthread *);
void _thr_finish_cancellation(void *arg);
int _thr_sigonstack(void *sp);
+void _thr_debug_check_yield(struct pthread *);
/*
* Aliases for _pthread functions. Should be called instead of
More information about the p4-projects
mailing list