summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-10-30 21:36:45 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-10-30 21:36:45 +0000
commit49f10e7c9f1af3f20fe3975e116299c606439cdc (patch)
treeafb0c98cb0cfff5bd8fdef65694c1c6c804f3d62
parent86fd17e65ed94fbc4b5abb47a169114fd06b3940 (diff)
(S_proc_getprocinfo): Support new FETCH flags; support new
msg_report_wait call; improve organization.
-rw-r--r--proc/info.c100
1 files changed, 54 insertions, 46 deletions
diff --git a/proc/info.c b/proc/info.c
index 56e462a6..85b398f6 100644
--- a/proc/info.c
+++ b/proc/info.c
@@ -302,6 +302,7 @@ S_proc_getprocenv (struct proc *callerp,
kern_return_t
S_proc_getprocinfo (struct proc *callerp,
pid_t pid,
+ int flags,
int **piarray,
u_int *piarraylen)
{
@@ -311,7 +312,7 @@ S_proc_getprocinfo (struct proc *callerp,
thread_t *thds;
error_t err;
size_t structsize;
- int i, j;
+ int i;
int didalloc = 0;
u_int tkcount, thcount;
struct proc *tp;
@@ -319,11 +320,20 @@ S_proc_getprocinfo (struct proc *callerp,
if (!p)
return ESRCH;
- err = task_threads (p->p_task, &thds, &nthreads);
- if (err == MACH_SEND_INVALID_DEST)
- err = ESRCH;
- if (err)
- return err;
+ if (flags & (PI_FETCH_THREAD_SCHED | PI_FETCH_THREAD_BASIC
+ | PI_FETCH_THREAD_WAITS))
+ flags |= PI_FETCH_THREADS;
+
+ if (flags & PI_FETCH_THREADS)
+ {
+ err = task_threads (p->p_task, &thds, &nthreads);
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
+ if (err)
+ return err;
+ }
+ else
+ nthreads = 0;
structsize = (sizeof (struct procinfo)
+ nthreads * sizeof (struct thread_basic_info)
@@ -354,65 +364,63 @@ S_proc_getprocinfo (struct proc *callerp,
pi->nthreads = nthreads;
- tkcount = TASK_BASIC_INFO_COUNT;
- err = task_info (p->p_task, TASK_BASIC_INFO, (int *)&pi->taskinfo,
- &tkcount);
+ if (flags & PI_FETCH_TASKINFO)
+ {
+ tkcount = TASK_BASIC_INFO_COUNT;
+ err = task_info (p->p_task, TASK_BASIC_INFO, (int *)&pi->taskinfo,
+ &tkcount);
- if (err == MACH_SEND_INVALID_DEST)
- err = ESRCH;
- if (err)
- for (i = 0; i < nthreads; i++)
- mach_port_deallocate (mach_task_self (), thds[i]);
- else
+ if (err == MACH_SEND_INVALID_DEST)
+ err = ESRCH;
+ }
+
+ for (i = 0; i < nthreads; i++)
{
- j = 0;
- for (i = 0; i < nthreads; i++)
+ pi->threadinfos[i].dead = 0;
+ if (flags & PI_FETCH_THREAD_BASIC)
{
thcount = THREAD_BASIC_INFO_COUNT;
err = thread_info (thds[i], THREAD_BASIC_INFO,
- (int *)&pi->threadinfos[j].pis_bi,
+ (int *)&pi->threadinfos[i].pis_bi,
&thcount);
if (err == MACH_SEND_INVALID_DEST)
- err = ESRCH;
- if (err && err != ESRCH)
+ {
+ pi->threadinfos[i].dead = 1;
+ continue;
+ }
+ if (err && err != MACH_SEND_INVALID_DEST)
break;
+ }
+ if (flags & PI_FETCH_THREAD_SCHED)
+ {
thcount = THREAD_SCHED_INFO_COUNT;
if (!err)
err = thread_info (thds[i], THREAD_SCHED_INFO,
- (int *)&pi->threadinfos[j].pis_si,
+ (int *)&pi->threadinfos[i].pis_si,
&thcount);
if (err == MACH_SEND_INVALID_DEST)
- err = ESRCH;
- if (err && err != ESRCH)
- break;
-
- if (!err)
- j++;
- else
{
- /* Don't count this one */
- /* XXX This is buggy if *piarraylen drops enough to
- reduce the number of pages in structsize, because
- the message send won't deallocate all that we allocated. */
- *piarraylen -= sizeof pi->threadinfos[j] / sizeof (int);
- pi->nthreads--;
+ pi->threadinfos[i].dead = 1;
+ continue;
}
-
- /* XXX If a thread has died, then its stats are now in
- the TASK_BASIC_INFO struct, but our copy might have been fetched
- from before the thread's death. */
-
- mach_port_deallocate (mach_task_self (), thds[i]);
+ if (err && err != ESRCH)
+ break;
}
- /* If we got an error (other than ESRCH); clean the rest
- of the thds */
- for (; i < nthreads; i++)
- mach_port_deallocate (mach_task_self (), thds[i]);
+
+ if (flags & PI_FETCH_THREAD_WAITS)
+ /* Errors are not significant here. */
+ msg_report_wait (p->p_msgport, thds[i],
+ &pi->threadinfos[i].rpc_block);
+
+ mach_port_deallocate (mach_task_self (), thds[i]);
}
- vm_deallocate (mach_task_self (), (u_int )thds,
- nthreads * sizeof (thread_t));
+ if (flags & PI_FETCH_THREADS)
+ {
+ vm_deallocate (mach_task_self (), (u_int )thds,
+ nthreads * sizeof (thread_t));
+ }
if (err && didalloc)
vm_deallocate (mach_task_self (), (u_int) *piarray, structsize);