⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sched.c

📁 对linux内核编程做了详细的解析和举例
💻 C
字号:
/* sched.c - scheduale a function to be called on  * every timer interrupt. *//* Copyright (C) 1998 by Ori Pomerantz *//* The necessary header files *//* Standard in kernel modules */#include <linux/kernel.h>   /* We're doing kernel work */#include <linux/module.h>   /* Specifically, a module *//* Deal with CONFIG_MODVERSIONS */#if CONFIG_MODVERSIONS==1#define MODVERSIONS#include <linux/modversions.h>#endif        /* Necessary because we use the proc fs */#include <linux/proc_fs.h>/* We scheduale tasks here */#include <linux/tqueue.h>/* We also need the ability to put ourselves to sleep  * and wake up later */#include <linux/sched.h>/* In 2.2.3 /usr/include/linux/version.h includes a  * macro for this, but 2.0.35 doesn't - so I add it  * here if necessary. */#ifndef KERNEL_VERSION#define KERNEL_VERSION(a,b,c) ((a)*65536+(b)*256+(c))#endif/* The number of times the timer interrupt has been  * called so far */static int TimerIntrpt = 0;/* This is used by cleanup, to prevent the module from  * being unloaded while intrpt_routine is still in  * the task queue */static struct wait_queue *WaitQ = NULL;static void intrpt_routine(void *);/* The task queue structure for this task, from tqueue.h */static struct tq_struct Task = {  NULL,   /* Next item in list - queue_task will do            * this for us */  0,      /* A flag meaning we haven't been inserted            * into a task queue yet */  intrpt_routine, /* The function to run */  NULL    /* The void* parameter for that function */};/* This function will be called on every timer  * interrupt. Notice the void* pointer - task functions  * can be used for more than one purpose, each time  * getting a different parameter. */static void intrpt_routine(void *irrelevant){  /* Increment the counter */  TimerIntrpt++;  /* If cleanup wants us to die */  if (WaitQ != NULL)     wake_up(&WaitQ);   /* Now cleanup_module can return */  else    /* Put ourselves back in the task queue */    queue_task(&Task, &tq_timer);  }/* Put data into the proc fs file. */int procfile_read(char *buffer,                   char **buffer_location, off_t offset,                   int buffer_length, int zero){  int len;  /* The number of bytes actually used */  /* This is static so it will still be in memory    * when we leave this function */  static char my_buffer[80];    static int count = 1;  /* We give all of our information in one go, so if    * the anybody asks us if we have more information    * the answer should always be no.    */  if (offset > 0)    return 0;  /* Fill the buffer and get its length */  len = sprintf(my_buffer,                 "Timer was called %d times so far\n",                 TimerIntrpt);  count++;  /* Tell the function which called us where the    * buffer is */  *buffer_location = my_buffer;  /* Return the length */  return len;}struct proc_dir_entry Our_Proc_File =   {    0, /* Inode number - ignore, it will be filled by         * proc_register_dynamic */    5, /* Length of the file name */    "sched", /* The file name */    S_IFREG | S_IRUGO,     /* File mode - this is a regular file which can     * be read by its owner, its group, and everybody     * else */    1,  /* Number of links (directories where          * the file is referenced) */    0, 0,  /* The uid and gid for the file - we give             * it to root */    80, /* The size of the file reported by ls. */    NULL, /* functions which can be done on the            * inode (linking, removing, etc.) - we don't            * support any. */    procfile_read,     /* The read function for this file, the function called     * when somebody tries to read something from it. */    NULL     /* We could have here a function to fill the      * file's inode, to enable us to play with      * permissions, ownership, etc. */  }; /* Initialize the module - register the proc file */int init_module(){  /* Put the task in the tq_timer task queue, so it    * will be executed at next timer interrupt */  queue_task(&Task, &tq_timer);  /* Success if proc_register_dynamic is a success,    * failure otherwise */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,0)  return proc_register(&proc_root, &Our_Proc_File);#else  return proc_register_dynamic(&proc_root, &Our_Proc_File);#endif}/* Cleanup */void cleanup_module(){  /* Unregister our /proc file */  proc_unregister(&proc_root, Our_Proc_File.low_ino);    /* Sleep until intrpt_routine is called one last    * time. This is necessary, because otherwise we'll    * deallocate the memory holding intrpt_routine and   * Task while tq_timer still references them.    * Notice that here we don't allow signals to    * interrupt us.    *   * Since WaitQ is now not NULL, this automatically    * tells the interrupt routine it's time to die. */ sleep_on(&WaitQ);}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -