jiq.c
上传用户:wudi5211
上传日期:2010-01-21
资源大小:607k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

C/C++

  1. /*
  2.  * jiq.c -- the just-in-queue module
  3.  *
  4.  * Tested with 2.0 on the x86, Sparc
  5.  */
  6.  
  7. /* BUGS: the module is not reentrant: only one file can be read at a time
  8.  *       the module usage count is not used: you could remove the module
  9.  *           while reading it, thus asking for troubles.
  10.  */
  11. #ifndef __KERNEL__
  12. #  define __KERNEL__
  13. #endif
  14. #ifndef MODULE
  15. #  define MODULE
  16. #endif
  17. #include <linux/module.h>
  18. #define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
  19. #if LINUX_VERSION_CODE < VERSION_CODE(1,99,4)
  20. #  error "This module needs Linux 1.99.4 or newer"
  21. #else
  22. #include <linux/sched.h>
  23. #include <linux/kernel.h>
  24. #include <linux/fs.h>     /* everything... */
  25. #include <linux/proc_fs.h>
  26. #include <linux/errno.h>  /* error codes */
  27. #include <linux/tqueue.h>
  28. #include <linux/interrupt.h> /* intr_count */
  29. /*
  30.  * This module is a silly one: it only embeds short code fragments
  31.  * that show how enqueued tasks `feel' theit environment
  32.  */
  33. #define LIMIT (PAGE_SIZE-128) /* don't print any more after this size */
  34. /*
  35.  * Print information about the current environment. This is called from
  36.  * within the task queues. If the limit is reched, awake the reading
  37.  * process.
  38.  */
  39. struct wait_queue *jiq_wait;
  40. struct tq_struct jiq_task; /* global: initialized to zero */
  41. struct clientdata {
  42.     int len;
  43.     char *buf;
  44.     unsigned long jiffies;
  45.     task_queue *queue;
  46. } jiq_data;
  47. void jiq_print(void *ptr)
  48. {
  49.   struct clientdata *data = (struct clientdata *)ptr;
  50.   int len = data->len;
  51.   char *buf = data->buf;
  52.   unsigned long j = jiffies;
  53.   if (len > LIMIT) {
  54.       wake_up_interruptible(&jiq_wait);
  55.       return;
  56.   }
  57.   if (len == 0)
  58.       len = sprintf(buf,"    time  delta intr_count pid commandn");
  59.   else
  60.       len =0;
  61.   /* intr_count is only exported since 1.3.5, but 1.99.4 is needed anyways */
  62.   len += sprintf(buf+len,"%9li %3li        %li   %5i %sn",
  63.                  j, j - data->jiffies,
  64.                  intr_count, current->pid, current->comm);
  65.   data->len += len;
  66.   data->buf += len;
  67.   data->jiffies = j;
  68.   /* re-register yourself, if needed */
  69.   if (data->queue)
  70.       queue_task(&jiq_task, data->queue);
  71.   if (data->queue == &tq_immediate)
  72.       mark_bh(IMMEDIATE_BH); /* this one needs to be marked */
  73. }
  74. /*
  75.  * Use the scheduler queue  -- /proc/jiqsched
  76.  */
  77. int jiq_read_sched(char *buf, char **start, off_t offset,
  78.                    int len, int unused)
  79. {
  80.     jiq_data.len = 0;               /* nothing printed, yet */
  81.     jiq_data.buf = buf;             /* print in this place */
  82.     jiq_data.jiffies = jiffies;     /* initial time */
  83.     /* jiq_print will queue_task() again in jiq_data.queue */
  84.     jiq_data.queue = &tq_scheduler;
  85.     queue_task(&jiq_task, &tq_scheduler); /* ready to run */
  86.     interruptible_sleep_on(&jiq_wait);    /* sleep till completion */
  87.     return jiq_data.len;
  88. }
  89. struct proc_dir_entry jiq_proc_sched = {
  90.         0,                 /* low_ino: the inode -- dynamic */
  91.         8, "jiqsched",     /* len of name and name */
  92.         S_IFREG | S_IRUGO, /* mode */
  93.         1, 0, 0,           /* nlinks, owner, group */
  94.         0, NULL,           /* size - unused; operations -- use default */
  95.         &jiq_read_sched,   /* function used to read data */
  96.         /* nothing more */
  97.     };
  98. int jiq_read_timer(char *buf, char **start, off_t offset,
  99.                    int len, int unused)
  100. {
  101.     jiq_data.len = 0;            /* nothing printed, yet */
  102.     jiq_data.buf = buf;          /* print in this place */
  103.     jiq_data.jiffies = jiffies;  /* initial time */
  104.     jiq_data.queue = &tq_timer;  /* re-register yourself here */
  105.     queue_task(&jiq_task, &tq_timer);     /* ready to run */
  106.     interruptible_sleep_on(&jiq_wait);    /* sleep till completion */
  107.     return jiq_data.len;
  108. }
  109. struct proc_dir_entry jiq_proc_timer = {
  110.         0,                 /* low_ino: the inode -- dynamic */
  111.         8, "jiqtimer",     /* len of name and name */
  112.         S_IFREG | S_IRUGO, /* mode */
  113.         1, 0, 0,           /* nlinks, owner, group */
  114.         0, NULL,           /* size - unused; operations -- use default */
  115.         &jiq_read_timer,   /* function used to read data */
  116.         /* nothing more */
  117.     };
  118. int jiq_read_immed(char *buf, char **start, off_t offset,
  119.                    int len, int unused)
  120. {
  121.     jiq_data.len = 0;                /* nothing printed, yet */
  122.     jiq_data.buf = buf;              /* print in this place */
  123.     jiq_data.jiffies = jiffies;      /* initial time */
  124.     jiq_data.queue = &tq_immediate;  /* re-register yourself here */
  125.     queue_task(&jiq_task, &tq_immediate); /* ready to run */
  126.     mark_bh(IMMEDIATE_BH);
  127.     interruptible_sleep_on(&jiq_wait);    /* sleep till completion */
  128.     return jiq_data.len;
  129. }
  130. struct proc_dir_entry jiq_proc_immed = {
  131.         0,                 /* low_ino: the inode -- dynamic */
  132.         8, "jiqimmed",     /* len of name and name */
  133.         S_IFREG | S_IRUGO, /* mode */
  134.         1, 0, 0,           /* nlinks, owner, group */
  135.         0, NULL,           /* size - unused; operations -- use default */
  136.         &jiq_read_immed,   /* function used to read data */
  137.         /* nothing more */
  138.     };
  139. /*
  140.  * This one, instead, tests out the timers.
  141.  */
  142. struct timer_list jiq_timer;
  143. void jiq_timedout(unsigned long ptr)
  144. {
  145.     jiq_print((void *)ptr);            /* print a line */
  146.     wake_up_interruptible(&jiq_wait);  /* awake the process */
  147. }
  148. int jiq_read_run_timer(char *buf, char **start, off_t offset,
  149.                    int len, int unused)
  150. {
  151.     jiq_data.len = 0;           /* prepare the argument for jiq_print() */
  152.     jiq_data.buf = buf;
  153.     jiq_data.jiffies = jiffies;
  154.     jiq_data.queue = NULL;      /* don't requeue */
  155.     init_timer(&jiq_timer);              /* init the timer structure */
  156.     jiq_timer.function = jiq_timedout;
  157.     jiq_timer.data = (unsigned long)&jiq_data;
  158.     jiq_timer.expires = jiffies + HZ; /* one second */
  159.     jiq_print(&jiq_data);   /* print and go to sleep */
  160.     add_timer(&jiq_timer);
  161.     interruptible_sleep_on(&jiq_wait);
  162.     return jiq_data.len;
  163. }
  164. struct proc_dir_entry jiq_proc_run_timer = {
  165.         0,                 /* low_ino: the inode -- dynamic */
  166.         7, "jitimer",      /* len of name and name */
  167.         S_IFREG | S_IRUGO, /* mode */
  168.         1, 0, 0,           /* nlinks, owner, group */
  169.         0, NULL,           /* size - unused; operations -- use default */
  170.         &jiq_read_run_timer, /* function used to read data */
  171.         /* nothing more */
  172.     };
  173. /*
  174.  * the init/clean material
  175.  */
  176. int init_module(void)
  177. {
  178.     /* this lines are in init_module() */
  179.     jiq_task.routine = jiq_print;
  180.     jiq_task.data = (void *)&jiq_data;
  181.     proc_register_dynamic(&proc_root, &jiq_proc_sched);
  182.     proc_register_dynamic(&proc_root, &jiq_proc_timer);
  183.     proc_register_dynamic(&proc_root, &jiq_proc_immed);
  184.     proc_register_dynamic(&proc_root, &jiq_proc_run_timer);
  185. #ifndef JIT_DEBUG
  186.     register_symtab(NULL); /* hide symbols */
  187. #endif
  188.     return 0; /* succeed */
  189. }
  190. void cleanup_module(void)
  191. {
  192.     proc_unregister(&proc_root, jiq_proc_sched.low_ino);
  193.     proc_unregister(&proc_root, jiq_proc_timer.low_ino);
  194.     proc_unregister(&proc_root, jiq_proc_immed.low_ino);
  195.     proc_unregister(&proc_root, jiq_proc_run_timer.low_ino);
  196. }
  197. #endif /* version 1.99.4 or newer */