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 <miles@gnu.org>
 
    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 <miles@gnu.org>
 
@@ -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 <miles@gnu.org>
 
@@ -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)

