next up previous
Next: proc_ifconfig.c Up: /proc/top a comparison Previous: Comparing resources

proc_top.c

/proc/top
simply run through the task list of linux for a light weight "top" cat /proc/top to get a list of PID, NICE, UserTime, SYStemTime and Command, this should be enough for most embedded systems . /proc/ifconfig
display network information in the form you would expect from ifconfig.

 
#include <linux/kernel.h>  /* printk level */
#include <linux/module.h>  /* kernel version etc. */
#include <linux/proc_fs.h> /* all the proc stuff */
#include <linux/fs.h>
#include <linux/errno.h>

/* don't forget to make it GPL...*/
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Der Herr Hofrat");
MODULE_DESCRIPTION("Embedded top");

struct proc_dir_entry *proc_top;

int 
list_tasks(char *page, 
   char **start, 
   off_t  off, 
   int    count,
   int   *eof, 
   void  *data)
{
   int size = 0;
   struct task_struct *p;
   char state;
   size+=sprintf(page+size,
      "%5s%7s%7s%7s%7s%7s%7s  %s\n\n",
      "PID","UID","PRIO","NICE",
      "STATE","USERt","SYSt","COMMAND");
}

Admittedly, this is not very elegant code, but the issue is too simple to allow for elegant solutions. Therefore simply the tasklist_lock is grabbed and the task list walked through, printing data of interest. The only datum that needs some interpretation is task-state as the numeric values would not tell anybody anything. Basically the goal is to have output that will be close enough to the output of top to allow administrators to interpret it properly.


   read_lock(&tasklist_lock);
   for_each_task(p){
      switch((int)p->state){
         case -1: state='Z'; break;
         case 0: state='R'; break;
         default: state='S'; break;
      }
      size+=sprintf(page+size,
         "%5d%7d%7d%7d%7c%7d%7d  %s\n",
         (int)p->pid,
         (int)p->uid,
         (int)p->rt_priority,
         (int)p->nice,
         state,
         (int)p->times.tms_utime,
         (int)p->times.tms_stime,
         p->comm);
   }
   read_unlock(&tasklist_lock);
   return (size);
}

init_module and cleanup_module just need to take care of setting up and deleting the proc file system entry.


int 
init_module(void) 
{
   proc_top = create_proc_entry("top",
      S_IFREG | S_IWUSR, 
      &proc_root);
   proc_top->read_proc = list_tasks;
   return 0;
}

void 
cleanup_module(void) 
{
   remove_proc_entry("top", &proc_root);
   printk("out of here\n");
}

By invoking cat /proc/top the typical output would be something like:


  PID    UID   PRIO   NICE  STATE  USERt   SYSt  COMMAND

    1      0      0      0      S      1   5848  init
    2      0      0      0      S      0      0  keventd
    3      0      0     19      S      0      3  ksoftirqd_CPU0
    4      0      0      0      S      0      0  kswapd
    5      0      0      0      S      0      0  bdflush
  ....
  661      0      0      0      S     18      7  sshd
  662      0      0      0      S     24     12  bash
  671      0      0      0      R      0      2  cat
Fig.1 output of cat /proc/top


next up previous
Next: proc_ifconfig.c Up: /proc/top a comparison Previous: Comparing resources
Der Herr Hofrat
2003-03-26