[Linux driver] Chapter 7 time delay and operation delay (Example 2)

Source: Internet
Author: User

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







Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.