FMUSER Wirless Transmit Video And Audio More Easier !

[email protected] WhatsApp +8618078869184
Language

    Linux drive technology (5) _equipment blocking / non-blocking read and write

     

    Waiting queue is a very important data structure to realize process scheduling in the kernel. Its task is to maintain a linked list. Each node in the linked list is a PCB (process control block). The kernel will schedule all processes with PCB hanging in the waiting queue to sleep until a wake-up condition occurs. I have discussed the use of blocking IO and non blocking IO in the application layer in the article of Linux I / O multiplexing. This paper mainly discusses how to realize blocking and non blocking reading and writing of device IO in the driver. Obviously, the implementation of this blocking related mechanism needs to use the waiting queue mechanism. The kernel source code in this paper uses the implementation of device blocking IO in version 3.14.0. When we read and write the IO of the device file, we will eventually call back the corresponding interfaces in the driver, and these interfaces will also appear in the process (kernel) space of the read-write device process. If the conditions are not met, the interface function will put the process into sleep, even if the user process of the read-write device enters sleep, That is, what we often call blocking. In a word, the essence of blocking reading and writing device files is that the driver blocks device files in the driver. The reading and writing process can be summarized as follows: 1. Define - initialize the waiting queue header. / / define the waiting queue header_ queue_ head_ t waitq_ h;// Initialization, waiting for queue header init_ waitqueue_ head(wait_ queue_ head_ t *q); // Or / / define and initialize the wait queue header declare_ WAIT_ QUEUE_ HEAD(waitq_ name); Among the above choices, the last one will directly define and initialize a waiting header. However, it is inconvenient to use global variables to transfer parameters in the module. The specific one depends on the requirements. We can trace the source code and see what the above lines have done: / / include / Linux / wait. H 35 struct__ wait_ queue_ head { 36 spinlock_ t lock; 37 struct list_ head task_ list; 38 }; 39 typedef struct __ wait_ queue_ head wait_ queue_ head_ t; wait_ queue_ head_ T -- 36 -- > this queue uses a spin lock -- 27 -- > to "string" the whole queue together. Then let's take a look at the initialized macro: 55 #define__ WAIT_ QUEUE_ HEAD_ INITIALIZER(name) { \ 56 .lock = __ SPIN_ LOCK_ UNLOCKED(name.lock), \ 57 .task_ list = { &(name).task_ list, &(name).task_ list } } 58 59 #define DECLARE_ WAIT_ QUEUE_ HEAD(name) \ 60 wait_ queue_ head_ t name = __ WAIT_ QUEUE_ HEAD_ INITIALIZER(name)DECLARE_ WAIT_ QUEUE_ Head() -- 60 -- > creates a waiting queue header named name based on the passed in string name -- 57 -- > initializes the above task_ The list field does not use the kernel standard initialization macro. There is no language... 2. Add the process to the waiting queue and add events to the waiting queue, that is, the process enters the sleep state and does not return until the condition is true**_ The version of interruptible indicates that sleep can be interrupted_ The timeout * * version indicates the timeout version, and the timeout will be returned. This naming convention can be seen everywhere in the kernel API. void wait_ event(wait_ queue_ head_ t *waitq_ h,int condition); void wait_ event_ interruptible(wait_ queue_ head_ t *waitq_ h,int condition); void wait_ event_ timeout(wait_ queue_ head_ t *waitq_ h,int condition); void wait_ event_ interruptible_ timeout(wait_ queue_ head_ t *waitq_ h,int condition); This is the core of the waiting queue. Let's take a look at wait_ event └── wait_ event └── _ wait_ event ├── abort_ exclusive_ wait ├── finish_ wait ├── prepare_ to_ wait_ event └── ___ wait_ is_ interruptible244 #define wait_ event(wq, condition) \245 do { \246 if (condition) \247 break; \ 248 __ wait_ event(wq, condition); \ 249 } while (0)wait_ Event -- 246 -- > if condition is true, immediately return -- 248 -- > otherwise call__ wait_ event194 #define ___ wait_ event(wq, condition, state, exclusive, ret, cmd) \ 195 ({ \206 for (;;) { \ 207 long __ int = prepare_ to_ wait_ event(&wq, &__ wait, state);\ 208 \ 209 if (condition) \ 210 break; \ 212 if (___ wait_ is_ interruptible(state) && __ int) { \213 __ ret = __ int; \ 214 if (exclusive) { \215 abort_ exclusive_ wait(&wq, &__ wait, \216 state, NULL); \ 217 goto __ out; \ 218 } \219 break; \ 220 } \222 cmd; \ 223 } \224 finish_ wait(&wq, &__ wait); \ 225 __ out: __ ret; \ 226 })___ wait_ Event -- 206 -- > polling in an endless loop -- 209 -- > if the condition is true, jump out of the loop and execute finish_ wait(); The process is awakened -- 212 -- > if the sleep mode of the process is interruptible, it will abort when the interrupt comes_ exclusive_ Wait is awakened -- 222 -- > if the above two items are not satisfied, the incoming schedule () will be called back, that is, continue to sleep template struct wait_ queue_ head_ t xj_ waitq_ h; static ssize_ t demo_ read(struct file *filp, char __ user *buf, size_ t size, loff_ t *offset){ if(! Condition) / / the condition can be set to wait in the interrupt processing function_ event_ interruptible(&xj_ waitq_ h,condition);} static file_ operations fops = { .read = demo_ read,}; static __ init demo_ init(void){ init_ waitqueue_ head(&xj_ waitq_ h);} Implementation of IO multiplexing for ordinary non blocking IO, we only need not use the blocking mechanism when registering the read / write interface in the driver. Here I want to discuss IO multiplexing, that is, how to use the kernel mechanism to support IO multiplexing in the driver when the read / write interface in the driver does not implement the blocking mechanism. Here is the apiint poll (struct file *filep, poll) we want to use_ table *wait); void poll_ wait(struct file * filp, wait_ queue_ head_ t * wait_ address, poll_ Table * P) when the application layer calls the select / poll / epoll mechanism, the kernel will actually traverse the poll interface in the driver that calls back the relevant file, and judge whether the file IO has corresponding events through the return value of the poll interface of each driver. We know that the core difference of these three IO multiplexing mechanisms lies in the way the kernel manages and monitors files, They are bits, arrays and linked lists, but for each driver, the callback interface is poll. Template struct wait_ queue_ head_ t waitq_ h; static unsigned int demo_ poll(str

     

     

     

     

    List all Question

    Nickname

    Email

    Questions

    Our other product:

    Professional FM Radio Station Equipment Package

     



     

    Hotel IPTV Solution

     


      Enter email  to get a surprise

      fmuser.org

      es.fmuser.org
      it.fmuser.org
      fr.fmuser.org
      de.fmuser.org
      af.fmuser.org ->Afrikaans
      sq.fmuser.org ->Albanian
      ar.fmuser.org ->Arabic
      hy.fmuser.org ->Armenian
      az.fmuser.org ->Azerbaijani
      eu.fmuser.org ->Basque
      be.fmuser.org ->Belarusian
      bg.fmuser.org ->Bulgarian
      ca.fmuser.org ->Catalan
      zh-CN.fmuser.org ->Chinese (Simplified)
      zh-TW.fmuser.org ->Chinese (Traditional)
      hr.fmuser.org ->Croatian
      cs.fmuser.org ->Czech
      da.fmuser.org ->Danish
      nl.fmuser.org ->Dutch
      et.fmuser.org ->Estonian
      tl.fmuser.org ->Filipino
      fi.fmuser.org ->Finnish
      fr.fmuser.org ->French
      gl.fmuser.org ->Galician
      ka.fmuser.org ->Georgian
      de.fmuser.org ->German
      el.fmuser.org ->Greek
      ht.fmuser.org ->Haitian Creole
      iw.fmuser.org ->Hebrew
      hi.fmuser.org ->Hindi
      hu.fmuser.org ->Hungarian
      is.fmuser.org ->Icelandic
      id.fmuser.org ->Indonesian
      ga.fmuser.org ->Irish
      it.fmuser.org ->Italian
      ja.fmuser.org ->Japanese
      ko.fmuser.org ->Korean
      lv.fmuser.org ->Latvian
      lt.fmuser.org ->Lithuanian
      mk.fmuser.org ->Macedonian
      ms.fmuser.org ->Malay
      mt.fmuser.org ->Maltese
      no.fmuser.org ->Norwegian
      fa.fmuser.org ->Persian
      pl.fmuser.org ->Polish
      pt.fmuser.org ->Portuguese
      ro.fmuser.org ->Romanian
      ru.fmuser.org ->Russian
      sr.fmuser.org ->Serbian
      sk.fmuser.org ->Slovak
      sl.fmuser.org ->Slovenian
      es.fmuser.org ->Spanish
      sw.fmuser.org ->Swahili
      sv.fmuser.org ->Swedish
      th.fmuser.org ->Thai
      tr.fmuser.org ->Turkish
      uk.fmuser.org ->Ukrainian
      ur.fmuser.org ->Urdu
      vi.fmuser.org ->Vietnamese
      cy.fmuser.org ->Welsh
      yi.fmuser.org ->Yiddish

       
  •  

    FMUSER Wirless Transmit Video And Audio More Easier !

  • Contact

    Address:
    No.305 Room HuiLan Building No.273 Huanpu Road Guangzhou China 510620

    E-mail:
    [email protected]

    Tel / WhatApps:
    +8618078869184

  • Categories

  • Newsletter

    FIRST OR FULL NAME

    E-mail

  • paypal solution  Western UnionBank OF China
    E-mail:[email protected]   WhatsApp:+8618078869184   Skype:sky198710021 Chat with me
    Copyright 2006-2020 Powered By www.fmuser.org

    Contact Us