diff options
author | davidxu <davidxu@FreeBSD.org> | 2004-07-13 22:49:58 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2004-07-13 22:49:58 +0000 |
commit | 2e3100b5472a1681f180c58f1b10e6af461d6176 (patch) | |
tree | fb610eb65d694e498ffb6de577dfc89b9d9f9f4e /lib/libpthread/thread/thr_priority_queue.c | |
parent | 512283ce25f97070fe9a81cb0695d87c31622254 (diff) | |
download | FreeBSD-src-2e3100b5472a1681f180c58f1b10e6af461d6176.zip FreeBSD-src-2e3100b5472a1681f180c58f1b10e6af461d6176.tar.gz |
Add code to support thread debugging.
1. Add global varible _libkse_debug, debugger uses the varible to identify
libpthread. when the varible is written to non-zero by debugger, libpthread
will take some special action at context switch time, it will check
TMDF_DOTRUNUSER flags, if a thread has the flags set by debugger, it won't
be scheduled, when a thread leaves KSE critical region, thread checks
the flag, if it was set, the thread relinquish CPU.
2. Add pq_first_debug to select a thread allowd to run by debugger.
3. Some names prefixed with _thr are renamed to _thread prefix.
which is allowed to run by debugger.
Diffstat (limited to 'lib/libpthread/thread/thr_priority_queue.c')
-rw-r--r-- | lib/libpthread/thread/thr_priority_queue.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/libpthread/thread/thr_priority_queue.c b/lib/libpthread/thread/thr_priority_queue.c index 2822aa8..83187ff 100644 --- a/lib/libpthread/thread/thr_priority_queue.c +++ b/lib/libpthread/thread/thr_priority_queue.c @@ -242,6 +242,57 @@ _pq_first(pq_queue_t *pq) 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, *pqlnext = NULL; + pthread_t pthread = NULL; + + /* + * Make some assertions when debugging is enabled: + */ + PQ_ASSERT_INACTIVE(pq, "_pq_first: pq_active"); + PQ_SET_ACTIVE(pq); + + for (pql = TAILQ_FIRST(&pq->pq_queue); + pql != NULL && pthread == NULL; pql = pqlnext) { + if ((pthread = TAILQ_FIRST(&pql->pl_head)) == NULL) { + /* + * The priority list is empty; remove the list + * from the queue. + */ + pqlnext = TAILQ_NEXT(pql, pl_link); + TAILQ_REMOVE(&pq->pq_queue, pql, pl_link); + + /* Mark the list as not being in the queue: */ + pql->pl_queued = 0; + } else { + /* + * note there may be a suspension event during this + * test, If TMDF_DONOTRUNUSER is set after we tested it, + * we will run the thread, this seems be a problem, + * fortunatly, when we are being debugged, all context + * switch will be done by kse_switchin, that is a + * syscall, kse_switchin will check the flag again, + * the thread will be returned via upcall, so next + * time, UTS won't run the thread. + */ + while (pthread != NULL && !DBG_CAN_RUN(pthread)) { + pthread = TAILQ_NEXT(pthread, pqe); + } + if (pthread == NULL) + pqlnext = TAILQ_NEXT(pql, pl_link); + } + } + + PQ_CLEAR_ACTIVE(pq); + return (pthread); +} static void pq_insert_prio_list(pq_queue_t *pq, int prio) |