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

嵌入式Linux

开发平台:

C/C++

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