The experiments involved in this article are blog http://blog.csdn.net/tianshuai11/article/details/7465587For example, read the above blog and digest the following example.
I. Module Method
Jiq. c
# Include <Linux/module. h> # include <Linux/moduleparam. h> # include <Linux/init. h> # include <Linux/sched. h> # include <Linux/kernel. h> # include <Linux/Fs. h>/* everything... */# include <Linux/proc_fs.h> # include <Linux/errno. h>/* error codes */# include <Linux/workqueue. h> # include <Linux/preempt. h> # include <Linux/interrupt. h>/* tasklets * // ** the delay for the delayed workqueue timer file. */static long d Elay = 1; module_param (delay, long, 0); // pass the parameter/** this module is a silly one: it only embeds short code fragments * that show how enqueued tasks 'feel' the Environment */# define limit (512) /* don't print any more after this size * // ** print information about the current environment. this is called from * within the task queues. if the limit is reched, awake the Reading * process. */static declare_w Ait_queue_head (jiq_wait); static struct work_struct jiq_work; static struct delayed_work jiq_work_delay;/** keep track of info we need between task queue runs. */static struct clientdata {int Len; char * Buf; unsigned long jiffies; unsigned long delay;} jiq_data; # define scheduler_queue (task_queue *) 1) static void jiq_print_tasklet (unsigned long); static declare_tasklet (jiq_tasklet, jiq_print_tasklet, (Unsigned long) & jiq_data);/** do the printing; return non-zero if the task shoshould be rescheduled. */static int jiq_print (void * PTR) {struct clientdata * Data = PTR; int Len = data-> Len; char * Buf = data-> Buf; unsigned long J = jiffies; If (LEN> limit) {wake_up_interruptible (& jiq_wait); Return 0;} If (LEN = 0) Len = sprintf (BUF, "Time Delta preempt pid cpu command \ n"); elselen = 0;/* intr_count is only Exported since 1.3.5, but 1.99.4 is needed anyways */Len + = sprintf (BUF + Len, "% 9li % 4li % 3I % 5I % 3I % s \ n", J, j-data-> jiffies, preempt_count (), current-> PID, smp_processor_id (), current-> comm); data-> Len + = Len; data-> BUF + = Len; data-> jiffies = J; return 1;}/** call jiq_print from a work queue */static void jiq_print_wq (struct work_struct * PTR) /* warning: assignment from incompatible pointer type */{ Struct clientdata * Data = & jiq_data; If (! Jiq_print (data) return; If (data-> delay) values (& jiq_work_delay, data-> delay); elseschedule_work (& jiq_work);} static int jiq_read_wq (char * Buf, char ** start, off_t offset, int Len, int * EOF, void * Data) {define_wait (wait); jiq_data.len = 0;/* nothing printed, yet */queues = Buf;/* print in this place */queues = jiffies;/* initial time */jiq_data.delay = 0; prepare_to_wait (& jiq_wait, & wait, task_interruptible ); schedule_work (& jiq_work); schedule (); finish_wait (& jiq_wait, & wait); * EOF = 1; return jiq_data.len;} static int evaluate (char * Buf, char ** start, off_t offset, int Len, int * EOF, void * Data) {define_wait (wait); jiq_data.len = 0;/* nothing printed, yet */queues = Buf;/* print in this place */queues = jiffies;/* initial time */jiq_data.delay = delay; prepare_to_wait (& jiq_wait, & wait, task_interruptible ); schedule_delayed_work (& jiq_work_delay, delay); schedule (); finish_wait (& jiq_wait, & wait); * EOF = 1; return jiq_data.len ;} /** call jiq_print from a tasklet */static void jiq_print_tasklet (unsigned long PTR) {If (jiq_print (void *) PTR) tasklet_schedule (& jiq_tasklet );} static int jiq_read_tasklet (char * Buf, char ** start, off_t offset, int Len, int * EOF, void * Data) {jiq_data.len = 0;/* nothing printed, yet */jiq_data.buf = Buf;/* print in this place */jiq_data.jiffies = jiffies;/* initial time */tasklet_schedule (& jiq_tasklet); cancel (& jiq_wait ); /* sleep till completion */* EOF = 1; return jiq_data.len;}/** this one, instead, tests out the timers. */static struct timer_list jiq_timer; static void jiq_timedout (unsigned long PTR) {jiq_print (void *) PTR);/* print a line */wake_up_interruptible (& jiq_wait ); /* awake the process */} static int jiq_read_run_timer (char * Buf, char ** start, off_t offset, int Len, int * EOF, void * Data) {jiq_data.len = 0; /* prepare the argument for jiq_print () */parameters = Buf; Parameters = jiffies; init_timer (& jiq_timer);/* init the timer structure */jiq_timer.function = jiq_timedout; jiq_timer.data = (unsigned long) & jiq_data; jiq_timer.expires = jiffies + Hz;/* One second */jiq_print (& jiq_data ); /* print and go to sleep */add_timer (& jiq_timer); interruptible_sleep_on (& jiq_wait);/* race */del_timer_sync (& jiq_timer ); /* In case a signal woke us up */* EOF = 1; return jiq_data.len;}/** the init/clean material */static int jiq_init (void) {/* this line is in jiq_init () */init_work (& jiq_work, jiq_print_wq); Activities (& jiq_work_delay, activities); create_proc_read_entry ("jiqwq", 0, null, internal, null); create_proc_read_entry ("jiqwqdelay", 0, null, delimiter, null); create_proc_read_entry ("jiqtimer", 0, null, delimiter, null); create_proc_read_entry ("jiqtasklet ", 0, null, random, null); Return 0;/* succeed */} static void jiq_cleanup (void) {remove_proc_entry ("jiqwq", null); remove_proc_entry ("jiqwqdelay ", null); remove_proc_entry ("jiqtimer", null); remove_proc_entry ("jiqtasklet", null);} module_init (jiq_init); module_exit (jiq_cleanup ); module_license ("dual BSD/GPL ");
Makefile
KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd)obj-m := jiq.o modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesclean:rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions.PHONY: modules modules_install clean
Test:
Root @ Ubuntu :~ /Desktop/jiq # Make
Root @ Ubuntu :~ /Desktop/jiq # insmod jiq. Ko
Root @ Ubuntu :~ /Desktop/jiq # lsmod // check whether the installation is successful
Root @ Ubuntu :~ /Desktop/jiq # Cat/proc/jiqwq
Time Delta preempt pid cpu command
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
6292513 0 0 235 2 kworker/
Root @ Ubuntu :~ /Desktop/jiq # Cat/proc/jiqwqdelay
Time Delta preempt pid cpu command
6297985 1 0 235 2 kworker/
6297986 1 0 235 2 kworker/
6297987 1 0 235 2 kworker/
6297988 1 0 235 2 kworker/
6297989 1 0 235 2 kworker/
6297990 1 0 235 2 kworker/
6297991 1 0 235 2 kworker/
6297992 1 0 235 2 kworker/
6297993 1 0 235 2 kworker/
6297994 1 0 235 2 kworker/
6297995 1 0 235 2 kworker/
Root @ Ubuntu :~ /Desktop/jiq # Cat/proc/jiqtimer
Time Delta preempt pid cpu command
6304215 0 0 5019 2 cat
6304465 250 256 0 2 kworker/
Root @ Ubuntu :~ /Desktop/jiq # Cat/proc/jiqtasklet
Time Delta preempt pid cpu command
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0
6323656 0 256 3 0 ksoftirqd/0