Index: libps/procstat.c =================================================================== RCS file: /cvsroot/hurd/hurd/libps/procstat.c,v retrieving revision 1.45 diff -u -r1.45 procstat.c --- libps/procstat.c 5 Jun 2002 23:29:10 -0000 1.45 +++ libps/procstat.c 8 Aug 2003 18:39:18 -0000 @@ -1,6 +1,6 @@ /* The proc_stat type, which holds information about a hurd process. - Copyright (C) 1995,96,97,98,99,2002 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2002,03 Free Software Foundation, Inc. Written by Miles Bader This program is free software; you can redistribute it and/or @@ -42,8 +42,13 @@ /* Return the PSTAT_STATE_ bits describing the state of an individual thread, from that thread's thread_basic_info_t struct */ +#ifdef POLICY_TIMESHARE +static int +thread_state (thread_basic_info_t bi, struct policy_infos *pi) +#else static int thread_state (thread_basic_info_t bi) +#endif { int state = 0; @@ -68,10 +73,17 @@ break; } +#ifdef POLICY_TIMESHARE + if (pi->ts.base_priority < 12) + state |= PSTAT_STATE_T_NASTY; + else if (pi->ts.base_priority > 12) + state |= PSTAT_STATE_T_NICE; +#else if (bi->base_priority < 12) state |= PSTAT_STATE_T_NASTY; else if (bi->base_priority > 12) state |= PSTAT_STATE_T_NICE; +#endif return state; } @@ -354,8 +366,12 @@ int i; unsigned num_threads = 0, num_run_threads = 0; thread_basic_info_t tbi = malloc (sizeof (struct thread_basic_info)); + /* Mach versions with different kinds of policies (OSF Mach) don't + have the priority information in struct thread_basic_info. */ +#ifndef POLICY_TIMESHARE int run_base_priority = 0, run_cur_priority = 0; int total_base_priority = 0, total_cur_priority = 0; +#endif if (!tbi) return 0; @@ -397,6 +413,7 @@ tbi->system_time.seconds += bi->system_time.seconds; tbi->system_time.microseconds += bi->system_time.microseconds; +#ifndef POLICY_TIMESHARE if (tbi->run_state == TH_STATE_RUNNING) { run_base_priority += bi->base_priority; @@ -408,6 +425,7 @@ total_base_priority += bi->base_priority; total_cur_priority += bi->base_priority; } +#endif num_threads++; } @@ -415,6 +433,7 @@ if (num_threads > 0) { tbi->sleep_time /= num_threads; +#ifndef POLICY_TIMESHARE if (num_run_threads > 0) { tbi->base_priority = run_base_priority / num_run_threads; @@ -425,6 +444,7 @@ tbi->base_priority = total_base_priority / num_threads; tbi->cur_priority = total_cur_priority / num_threads; } +#endif } tbi->user_time.seconds += tbi->user_time.microseconds / 1000000; @@ -435,6 +455,45 @@ return tbi; } +#ifdef POLICY_TIMESHARE +/* Returns a new malloced struct policy_infos containing a summary of + all the thread scheduling info in PI. The priorities are an average of the + thread priorities. */ +static struct policy_infos * +summarize_thread_policy_info (struct procinfo *pi) +{ + int i; + unsigned num_threads = 0; + policy_info_data_t *tsi = malloc (sizeof (struct policy_infos)); + + if (!tsi) + return 0; + + bzero (tsi, sizeof *tsi); + + for (i = 0; i < pi->nthreads; i++) + if (! pi->threadinfos[i].died + && ! (pi->threadinfos[i].pis_bi.flags & TH_FLAGS_IDLE)) + { + policy_info_data_t *ti = &pi->threadinfos[i].pis_pi; + tsi->ts.base_priority += ti->ts.base_priority; + tsi->ts.cur_priority += ti->ts.cur_priority; + tsi->ts.max_priority += ti->ts.max_priority; + tsi->ts.depress_priority += ti->ts.depress_priority; + num_threads++; + } + + if (num_threads > 0) + { + tsi->ts.base_priority /= num_threads; + tsi->ts.cur_priority /= num_threads; + tsi->ts.max_priority /= num_threads; + tsi->ts.depress_priority /= num_threads; + } + + return tsi; +} +#else /* Returns a new malloced struct thread_sched_info containing a summary of all the thread scheduling info in PI. The prioritys are an average of the thread priorities. */ @@ -472,6 +531,7 @@ return tsi; } +#endif /* Returns the union of the state bits for all the threads in PI. */ static int @@ -484,7 +544,12 @@ for (i = 0; i < pi->nthreads; i++) if (! pi->threadinfos[i].died && ! (pi->threadinfos[i].pis_bi.flags & TH_FLAGS_IDLE)) +#ifdef POLICY_TIMESHARE + state |= thread_state (&pi->threadinfos[i].pis_bi, + &pi->threadinfos[i].pis_pi); +#else state |= thread_state (&pi->threadinfos[i].pis_bi); +#endif return state; } @@ -648,10 +713,17 @@ free (ps->thread_basic_info); if (have & PSTAT_THREAD_BASIC) ps->thread_basic_info = summarize_thread_basic_info (pi); +#ifdef POLICY_TIMESHARE + if (had & PSTAT_THREAD_SCHED) + free (ps->thread_policy_info); + if (have & PSTAT_THREAD_SCHED) + ps->thread_policy_info = summarize_thread_policy_info (pi); +#else if (had & PSTAT_THREAD_SCHED) free (ps->thread_sched_info); if (have & PSTAT_THREAD_SCHED) ps->thread_sched_info = summarize_thread_sched_info (pi); +#endif if (have & PSTAT_THREAD_WAITS) /* Thread-waits info can be used to generate thread-wait info. */ { @@ -701,10 +773,17 @@ clone (&ti->pis_bi, sizeof (struct thread_basic_info)))) have |= PSTAT_THREAD_BASIC; +#ifdef POLICY_TIMESHARE + if ((need & PSTAT_THREAD_SCHED) && (oflags & PSTAT_THREAD_SCHED) + && (ps->thread_policy_info = + clone (&ti->pis_pi, sizeof (struct policy_infos)))) + have |= PSTAT_THREAD_SCHED; +#else if ((need & PSTAT_THREAD_SCHED) && (oflags & PSTAT_THREAD_SCHED) && (ps->thread_sched_info = clone (&ti->pis_si, sizeof (struct thread_sched_info)))) have |= PSTAT_THREAD_SCHED; +#endif if ((need & PSTAT_THREAD_WAIT) && (oflags & PSTAT_THREAD_WAITS)) { @@ -866,7 +945,12 @@ { /* Thread states. */ if (have & PSTAT_THREAD) +#ifdef POLICY_TIMESHARE + ps->state |= thread_state (ps->thread_basic_info, + ps->thread_policy_info); +#else ps->state |= thread_state (ps->thread_basic_info); +#endif else /* For a process, we use the thread list instead of PS->thread_basic_info because it contains more information. */ @@ -1053,7 +1137,11 @@ MFREEMEM (PSTAT_PROCINFO, proc_info, ps->proc_info_size, ps->proc_info_vm_alloced, 0, char); MFREEMEM (PSTAT_THREAD_BASIC, thread_basic_info, 0, 0, 0, 0); +#ifdef POLICY_TIMESHARE + MFREEMEM (PSTAT_THREAD_SCHED, thread_policy_info, 0, 0, 0, 0); +#else MFREEMEM (PSTAT_THREAD_SCHED, thread_sched_info, 0, 0, 0, 0); +#endif MFREEMEM (PSTAT_ARGS, args, ps->args_len, ps->args_vm_alloced, 0, char); MFREEMEM (PSTAT_ENV, env, ps->env_len, ps->env_vm_alloced, 0, char); MFREEMEM (PSTAT_TASK_EVENTS, task_events_info, ps->task_events_info_size, Index: libps/ps.h =================================================================== RCS file: /cvsroot/hurd/hurd/libps/ps.h,v retrieving revision 1.35 diff -u -r1.35 ps.h --- libps/ps.h 13 May 2002 22:23:15 -0000 1.35 +++ libps/ps.h 8 Aug 2003 18:39:19 -0000 @@ -1,6 +1,6 @@ /* Routines to gather and print process information. - Copyright (C) 1995,96,99,2001,02 Free Software Foundation, Inc. + Copyright (C) 1995,96,99,2001,02,03 Free Software Foundation, Inc. Written by Miles Bader @@ -225,7 +225,11 @@ waiting ones, and if there are any other incompatible states, simply using a bogus value of -1. Malloced. */ thread_basic_info_t thread_basic_info; +#ifdef POLICY_TIMESHARE + struct policy_infos *thread_policy_info; +#else thread_sched_info_t thread_sched_info; +#endif /* For a blocked thread, these next fields describe how it's blocked. */ @@ -424,7 +428,11 @@ #define proc_stat_num_threads(ps) ((ps)->num_threads) #define proc_stat_task_basic_info(ps) ((ps)->task_basic_info) #define proc_stat_thread_basic_info(ps) ((ps)->thread_basic_info) +#ifdef POLICY_TIMESHARE +#define proc_stat_thread_policy_info(ps) ((ps)->thread_policy_info) +#else #define proc_stat_thread_sched_info(ps) ((ps)->thread_sched_info) +#endif #define proc_stat_thread_rpc(ps) ((ps)->thread_rpc) #define proc_stat_thread_wait(ps) ((ps)->thread_rpc) #define proc_stat_suspend_count(ps) ((ps)->suspend_count) Index: libps/spec.c =================================================================== RCS file: /cvsroot/hurd/hurd/libps/spec.c,v retrieving revision 1.34 diff -u -r1.34 spec.c --- libps/spec.c 5 Jun 2002 01:40:49 -0000 1.34 +++ libps/spec.c 8 Aug 2003 18:39:20 -0000 @@ -1,6 +1,6 @@ /* Access, formatting, & comparison routines for printing process info. - Copyright (C) 1995,96,97,99,2001,02 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,99,2001,02,03 Free Software Foundation, Inc. Written by Miles Bader @@ -137,7 +137,12 @@ return proc_stat_state (ps); } const struct ps_getter ps_state_getter = -{"state", PSTAT_STATE, (vf) ps_get_state}; +{"state", +#ifdef POLICY_TIMESHARE + /* We need the scheduling info for the nice/nasty flags. */ + PSTAT_THREAD_SCHED | +#endif + PSTAT_STATE, (vf) ps_get_state}; static void ps_get_wait (struct proc_stat *ps, char **wait, int *rpc) @@ -167,23 +172,48 @@ static int ps_get_cur_priority (struct proc_stat *ps) { +#ifdef POLICY_TIMESHARE + return proc_stat_thread_policy_info (ps)->ts.cur_priority; +#else return proc_stat_thread_basic_info (ps)->cur_priority; +#endif } const struct ps_getter ps_cur_priority_getter = -{"cur_priority", PSTAT_THREAD_BASIC, (vf) ps_get_cur_priority}; +{"cur_priority", +#ifdef POLICY_TIMESHARE + /* The priorities are in thread_policy_info. */ + PSTAT_THREAD_SCHED, +#else + PSTAT_THREAD_BASIC, +#endif + (vf) ps_get_cur_priority}; static int ps_get_base_priority (struct proc_stat *ps) { +#ifdef POLICY_TIMESHARE + return proc_stat_thread_policy_info (ps)->ts.base_priority; +#else return proc_stat_thread_basic_info (ps)->base_priority; +#endif } const struct ps_getter ps_base_priority_getter = -{"base_priority", PSTAT_THREAD_BASIC, (vf) ps_get_base_priority}; +{"base_priority", +#ifdef POLICY_TIMESHARE + PSTAT_THREAD_SCHED, +#else + PSTAT_THREAD_BASIC, +#endif + (vf) ps_get_base_priority}; static int ps_get_max_priority (struct proc_stat *ps) { +#ifdef POLICY_TIMESHARE + return proc_stat_thread_policy_info (ps)->ts.max_priority; +#else return proc_stat_thread_sched_info (ps)->max_priority; +#endif } const struct ps_getter ps_max_priority_getter = {"max_priority", PSTAT_THREAD_SCHED, (vf) ps_get_max_priority}; @@ -222,12 +252,24 @@ static void ps_get_start_time (struct proc_stat *ps, struct timeval *tv) { +#ifdef NO_CREATION_TIME + struct timeval *const t = &proc_stat_proc_info (ps)->creation_time; + tv->tv_sec = t->tv_sec; + tv->tv_usec = t->tv_usec; +#else time_value_t *const tvt = &proc_stat_task_basic_info (ps)->creation_time; tv->tv_sec = tvt->seconds; tv->tv_usec = tvt->microseconds; +#endif } const struct ps_getter ps_start_time_getter = -{"start_time", PSTAT_TASK_BASIC, ps_get_start_time}; +{"start_time", +#ifdef NO_CREATION_TIME + PSTAT_PROC_INFO, +#else + PSTAT_TASK_BASIC, +#endif + ps_get_start_time}; static float ps_get_rmem_frac (struct proc_stat *ps)