Waiting queues in Linux kernel (blocked) __linux

Source: Internet
Author: User
Tags goto sleep function

Waiting queues are used in the Linux kernel to block or wake up a process, to synchronize access to system resources, and to implement latency functions



Wait Queue interface function Introduction:

#include <linux/wait.h>//header file contains 1. Define, initialize wait queue (point to wait queue list)

Define a wait queue header

wait_queue_head_t My_queue;

Initial a wait queue header

Init_waitqueue_head (&my_queue);

Define and initialize a wait queue header

Declare_wait_queue_head (My_queue); 2. The process of sleep operation--conditional sleep

Determines whether the current process is pushed into the wait queue by condition conditions

Wait_event (wait_queue_head_t wq, int condition);

Wait_event_interruptible/* Can be interrupted by system messages.

(wait_queue_head_t wq,int condition);

Wait_event_timeout (wait_queue_head_t wq, int

condition, long timeout);

Wait_event_interruptiblble_timeout (wait_queue_head_t Wq,

int condition, long timeout);

Parameter Wq: Indicates waiting queue header

Parameter condition: Blocking condition, False (0) then go to hibernation until wake_up and condition are true conditions to exit

Parameter timeout: Indicates the length of sleep specified (clock tick, eg. delay 2 seconds =2*hz), automatically into wake state

Sleep operation of a process--unconditional sleep

Pushes the current process into the wait queue to sleep, wake_up wake up

sleep_on (wait_queue_head_t *q);

interruptible_sleep_on (wait_queue_head_t *q);

Long Sleep_on_timeout (wait_queue_head_t *q, long timeout);

Long Interruptible_sleep_on_timeout (wait_queue_head_t *q, long timeout);

Parameter Wq: Indicates waiting queue header

Parameter timeout: Indicates that when the sleep specifies a long time, it automatically goes to wake State


3. Process Wake function

WAKE_UP (wait_queue_head_t *wq);

Wake_up_interruptible (wait_queue_head_t *wq);

Precautions:

1. Wake function and cause sleep function to pair use, if cause sleep function to use with interruptible, then wake function also use interruptible.

2. Assign the value of the condition variable in wait_event to True before using the WAKE_UP wakeup process, or the process will immediately re-enter the sleep wait Queue application instance once it is awakened:

Code instance: Application-Layer code:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>

int main ()
{
	char *devname = "/dev/key1_eint";
	int FD;
	unsigned char key;
	
	FD = open (Devname, O_RDWR);
	while (1) {
		read (fd, &key, sizeof (key)); 
		printf ("The key =%d\n", key);
	}
	Close (FD);
}
Drive layer:
#include <linux/device.h> #include <linux/interrupt.h> #include <linux/module.h> #include <linux /kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/delay.h> #include < linux/irq.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/io.h> #include <mach/ gpio.h> #include <mach/regs-gpio.h> #define EINT_DEVICE_ID 1 #define DRIVER_NAME "Key1_eint" #define ERR (		msg) PRINTK (kern_err "%s:" msg "\ n", driver_name) #define __DEBUG (FMT, arg ...) PRINTK (Kern_debug fmt, # #arg) #define GPH3CON (unsigned long) (s5pv210_gph3_base+ 0x00) #define GPH3DAT (unsigned		
Long) (s5pv210_gph3_base + 0x04) #define GPH2UP (unsigned long) (s5pv210_gph2_base + 0x08) static int major = 0;		
static int minor = 0;
struct class *key_class;

static struct device *key_device;
/* Defines the wait queue header, which belongs to the driver */static wait_queue_head_t wait_queue;

static unsigned char key; Irqreturn_t Buttons_interrUPT (int irq, void *dev_id) {key = (unsigned int) dev_id;			Wake_up_interruptible (&wait_queue);
Wake wait queue return irq_handled;
	
	static void Key_io_port_init (void) {unsigned long reg_val;
	Reg_val = Readl (Gph3con); Reg_val &= ~ (0x0f<<0) |
	(0x0f<<4)); Reg_val |= (0x01<<0) |
	(0x01<<4));

	Writel (Reg_val, Gph3con);
	Reg_val = Readl (Gph3dat); Reg_val &= ~ (0x01<<0) |
	(0x01<<1));

	Writel (Reg_val, Gph3dat);
	Reg_val = Readl (gph2up);
	Reg_val &= ~ (0x03<<8);
	Reg_val |= 0x02<<8;
Writel (Reg_val, gph2up);
	Static ssize_t key_read (struct file *filp, char *buf, size_t count, loff_t *f_pos) {int key_num;
	int Cpy_len;

	int retval;
	/* The function body defines the struct wait_queue struct variable and adds the current process * to the queue to sleep (wait_queue_head_t is the head of the waiting queue list, struct * wait_queue records the linked list node information).
	
	
	INTERRUPTIBLE_SLEEP_ON (&wait_queue);		Key_num = key;
	Read key value Cpy_len = min (sizeof (key_num), count);
	
	retval = Copy_to_user (buf, &key_num, Cpy_len); RetUrn (cpy_len-retval); }/* Driver Operation structure/static struct file_operations Key_fops = {. Owner = This_module,. Read = Key_read,}


;
	

	static int __init key_eint_init (void) {int retval;

	Key_io_port_init ();			Init_waitqueue_head (&wait_queue);
	Initialize Wait queue header retval = Set_irq_type (Irq_eint (), irq_type_edge_falling);
		if (retval) {err ("irq_eint20 set IRQ type failed");
	Goto error;
	} retval = Request_irq (irq_eint), Buttons_interrupt, irqf_disabled, "KEY1", (void *) eint_device_id);
		if (retval) {err ("request eint20 failed");
	Goto error;
	} major = Register_chrdev (major, Driver_name, &key_fops);
		if (Major < 0) {err ("Register char Device Fail");
		retval = major;
	Goto Error_register;
	} key_class=class_create (This_module,driver_name);
		if (Is_err (Key_class)) {ERR ("class Create failed!");
		retval = Ptr_err (Key_class);
	Goto Error_class;
	} key_device=device_create (Key_class,null, Mkdev (major, minor), null,driver_name); if (is_err(Key_device))
		{ERR ("Device Create failed!");
		retval = Ptr_err (Key_device);
	Goto Error_device; } __debug ("Register Mydriver ok!
	Major =%d\n ", Major);

return 0;
Error_device:class_destroy (Key_class);
Error_class:unregister_chrdev (Major, Driver_name);
ERROR_REGISTER:FREE_IRQ (Irq_eint), (void *) eint_device_id);
Error:return retval;

	} static void __exit key_eint_exit (void) {FREE_IRQ (irq_eint), (void *) eint_device_id);
	Unregister_chrdev (Major, Driver_name);
	Device_destroy (Key_class,mkdev (major, minor));

	Class_destroy (Key_class);
Return
} module_init (Key_eint_init);

Module_exit (Key_eint_exit);
Module_license ("GPL"); Module_author ("Eric");



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.