LECTURE 4 ¥Ö¥í¥Ã¥¯I/O

¡û ¤Ï¤¸¤á¤Ë

multiproc.c ¤Ç¤Ï¡¢read »þ¤ËÆɤ߹þ¤á¤ë¥Ç¡¼¥¿¤¬Â¸ºß¤·¤Ê¤¤¡¢¤¢¤ë¤¤¤Ï write »þ¤Ë½ñ¤­¹þ¤à¥¹¥Ú¡¼¥¹¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ë¤Ï¨ºÂ¤Ë½èÍý½ªÎ»¤·¤Æ¤¤¤Þ¤·¤¿¡£

º£²ó¤Ï¤½¤ÎÍͤʾì¹ç¤Ë¨ºÂ¤Ë½ªÎ»¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢Â¾¤Î¥×¥í¥»¥¹¤Ë¤è¤ë¥Ç¡¼¥¿¤ÎÆɤ߽ñ¤­¤¬¹Ô¤ï¤ì¤ë¤Þ¤ÇÂÔµ¡¤¹¤ë¥Ö¥í¥Ã¥¯ I/O ¤ò¼ÂÁõ¤·¤Þ¤¹¡£

¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à

¥Ö¥í¥Ã¥¯ I/O ( read / write ) ¤ËÂбþ¤·¤¿¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à block.c ¤Ç¤¹¡£ ¤Ï¤¸¤á¤Ë ¤Î¥Ú¡¼¥¸¤«¤é¡¢ Á´¤Æ¤Î¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ò ¸Ç¤á¤¿ tar ¥Ü¡¼¥ë¤ò¥À¥¦¥ó¥í¡¼¥É¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£

echo "HELLO WORLD" > /dev/chardev

¤ÎÍͤˤ·¤Æ½ñ¤­¹þ¤ß¤ò¹Ô¤Ã¤¿ºÝ¤ËÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¶õ¤­¤¬Ìµ¤¤¤È¡¢Â¾¥×¥í¥»¥¹¤Ç

cat /dev/chardev
HELLO WORLD

¤ÎÍͤˤ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤò¼è¤ê½Ð¤¹¤Þ¤Ç¡¢½ñ¤­¹þ¤ß¤ò¹Ô¤ª¤¦¤È¤·¤¿¥×¥í¥»¥¹¤ÏÂÔ¤Á¾õÂ֤ˤʤê¤Þ¤¹¡£ÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤ¬¼è¤ê½Ð¤µ¤ì¤Æ¶õ¤­¤¬½ÐÍè¤ë¤ÈƱ»þ¤Ë¡¢½ñ¤­¹þ¤ß¥×¥í¥»¥¹¤¬Æ°ºî¤·»Ï¤á¤Þ¤¹¡£

È¿ÂФˡ¢cat Åù¤ÇÆɤ߹þ¤â¤¦¤È¤·¤¿ºÝ¤ËÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¥Ç¡¼¥¿¤¬Ìµ¤¤¾ì¹ç¡¢Æɤ߹þ¤ß¥×¥í¥»¥¹¤ÏÂÔ¤Á¾õÂ֤ˤʤê¤Þ¤¹¡£ÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë¥Ç¡¼¥¿¤¬½ñ¤­¹þ¤Þ¤ì¤ë¤ÈƱ»þ¤Ë¡¢Æɤ߹þ¤ß¥×¥í¥»¥¹¤¬Æ°ºî¤·»Ï¤á¤Þ¤¹¡£

C ¸À¸ìÅù¤ÇÈó¥Ö¥í¥Ã¥¯»ØÄê¤Ç /dev/chardev ¤ò open ¤·¤¿¾ì¹ç¤Ï¡¢¾åµ­¤ÎÍͤʾì¹ç¤ËÂÔ¤Á¾õÂ֤ˤʤë¤Î¤Ç¤Ï¤Ê¤¯¡¢Â¨ºÂ¤ËÆɤ߹þ¤ß¡¢½ñ¤­¹þ¤ß½èÍý¤¬½ªÎ»¤·¤Þ¤¹¡£¤½¤ÎºÝ read / write ¥·¥¹¥Æ¥à¥³¡¼¥ë¤Ï -1 ¤òÊÖ¤·¡¢errno ¤Ë¤Ï EBUSY ¤¬ÀßÄꤵ¤ì¤Þ¤¹¡£

--- block.c ---

    1    #include <asm/semaphore.h>
    2    #include <asm/uaccess.h>   /* copy_from_user, copy_to_user */
    3    #include <linux/errno.h>
    4    #include <linux/fs.h>      /* inode, file, file_operations */
    5    #include <linux/kernel.h>  /* printk() */
    6    #include <linux/module.h> 
    7    #include <linux/wait.h>    /* wait_queue_head_t */
    8    #include <linux/sched.h>   /* wait_event_interruptible, wake_up_interruptible */
    9    
   10    
   11    MODULE_AUTHOR( "Ryo" );
   12    MODULE_DESCRIPTION( "Sample character device driver." );
   13    MODULE_LICENSE( "GPL" );
   14    
   15    
   16    static int   devmajor = 77;
   17    static char* devname  = "chardev";
   18    static char* msg      = "module [block.o]";
   19    
   20    
   21    #define MAXBUF 32
   22    static unsigned char devbuf[ MAXBUF ];
   23    static int buf_pos;
   24    
   25    static struct semaphore chardev_sem;
   26    static wait_queue_head_t write_q;
   27    static wait_queue_head_t read_q;
   28    
   29    
   30    /*
   31     * ¥í¥°½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥ÈÍÑ´Ø¿ô
   32     */
   33    static void 
   34    log_format( char* body )
   35    {
   36        if ( current != NULL ) {
   37            printk( KERN_INFO "%s : PID = %-5i cmdline = \"%-10s\" : %s\n", 
   38                msg, current->pid, current->comm, body );
   39        }
   40        else {
   41            printk( KERN_INFO "%s : %s\n", msg, body );
   42        }
   43    }
   44    
   45    
   46    /*
   47     * open()
   48     */
   49    static int 
   50    chardev_open( struct inode* inode, struct file* filp )
   51    {
   52        log_format( "open()  called" );
   53        return 0;
   54    }
   55    
   56    
   57    /*
   58     * release()
   59     */
   60    static int 
   61    chardev_release( struct inode* inode, struct file* filp )
   62    {
   63        log_format( "close() called" );
   64        return 0;
   65    }
   66    
   67    
   68    /*
   69     * read()
   70     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÂФ·¤ÆÆâÉô¥Ð¥Ã¥Õ¥¡¤ÎÆâÍƤòžÁ÷¤¹¤ë¡£
   71     * žÁ÷¤·¤¿ÆâÍƤÏÆâÉô¥Ð¥Ã¥Õ¥¡¤«¤é¾Ã¤¨¤ë¡£
   72     */
   73    static ssize_t 
   74    chardev_read( struct file* filp, char* buf, size_t count, loff_t* pos )
   75    {
   76        int copy_len;
   77        int i;
   78    
   79        log_format( "read()  called" );
   80    
   81        if ( down_interruptible( &chardev_sem ) ) {
   82            log_format( "down_interruptible for read failed" );
   83            return -ERESTARTSYS;
   84        }
   85    
   86        while ( buf_pos == 0 ) {
   87            up( &chardev_sem );
   88    
   89            if ( filp->f_flags & O_NONBLOCK ) {
   90                log_format( "read return because O_NONBLOCK is specified" );
   91                return -EAGAIN;
   92            }
   93    
   94            log_format( "read process going to sleep" );
   95    
   96            if ( wait_event_interruptible( read_q, ( buf_pos != 0 ) ) )
   97                return -ERESTARTSYS;
   98    
   99            if ( down_interruptible( &chardev_sem ) ) {
  100                log_format( "down_interruptible for read failed" );
  101                return -ERESTARTSYS;
  102            }
  103        }
  104    
  105    
  106        log_format( "read process going to read" );
  107    
  108        if ( count > buf_pos )
  109            copy_len = buf_pos;
  110        else
  111            copy_len = count;
  112    
  113        if ( copy_to_user( buf, devbuf, copy_len ) ) {
  114            up( &chardev_sem );
  115            log_format( "copy_to_user failed" );
  116            return -EFAULT;
  117        }
  118    
  119        *pos += copy_len;
  120    
  121        for ( i = copy_len; i < buf_pos; i ++ )
  122            devbuf[ i - copy_len ] = devbuf[i];
  123    
  124        buf_pos -= copy_len;
  125    
  126        up( &chardev_sem );
  127        wake_up_interruptible( &write_q );
  128    
  129        return copy_len;
  130    }
  131    
  132    
  133    /*
  134     * write()
  135     * ¥æ¡¼¥¶¥×¥í¥»¥¹¤«¤éžÁ÷¤µ¤ì¤¿ÆâÍƤòÆâÉô¥Ð¥Ã¥Õ¥¡¤Ë½ñ¤­¹þ¤à¡£
  136     */
  137    static ssize_t 
  138    chardev_write( struct file* filp, const char* buf, size_t count, loff_t* pos )
  139    {
  140        int copy_len;
  141    
  142        log_format( "write() called" );
  143    
  144        if ( down_interruptible( &chardev_sem ) ) {
  145            log_format( "down_interruptible for write failed" );
  146            return -ERESTARTSYS;
  147        }
  148    
  149        while ( buf_pos == MAXBUF ) {
  150            up( &chardev_sem );
  151    
  152            if ( filp->f_flags & O_NONBLOCK ) {
  153                log_format( "write return because O_NONBLOCK is specified" );
  154                return -EAGAIN;
  155            }
  156    
  157            log_format( "write process going to sleep" );
  158    
  159            if ( wait_event_interruptible( write_q, ( buf_pos != MAXBUF ) ) )
  160                return -ERESTARTSYS;
  161    
  162            if ( down_interruptible( &chardev_sem ) ) {
  163                log_format( "down_interruptible for write failed" );
  164                return -ERESTARTSYS;
  165            }
  166        }
  167    
  168    
  169        log_format( "write process going to write" );
  170    
  171        if ( count > ( MAXBUF - buf_pos ) )
  172            copy_len = MAXBUF - buf_pos;
  173        else
  174            copy_len = count;
  175    
  176        if ( copy_from_user( devbuf + buf_pos, buf, copy_len ) ) {
  177            up( &chardev_sem );
  178            log_format( "copy_from_user failed" );
  179            return -EFAULT;
  180        }
  181    
  182        *pos    += copy_len;
  183        buf_pos += copy_len;
  184    
  185        up( &chardev_sem );
  186        wake_up_interruptible( &read_q );
  187    
  188        return copy_len;
  189    }
  190    
  191    
  192    static struct file_operations chardev_fops = 
  193    {
  194        owner   : THIS_MODULE,
  195        read    : chardev_read,
  196        write   : chardev_write,
  197        open    : chardev_open,
  198        release : chardev_release,
  199    };
  200    
  201    
  202    /*
  203     * ¥â¥¸¥å¡¼¥ë¤Î½é´ü½èÍý
  204     * insmod »þ¤Ë¸Æ¤Ð¤ì¤ë
  205     */
  206    int 
  207    init_module( void )
  208    {
  209        if ( register_chrdev( devmajor, devname, &chardev_fops ) ) {
  210            log_format( "register_chrdev failed" );
  211            return -EBUSY;
  212        }
  213    
  214        sema_init( &chardev_sem, 1 );
  215    
  216        init_waitqueue_head( &write_q );
  217        init_waitqueue_head( &read_q );
  218    
  219        log_format( "loaded  into kernel" );
  220        return 0;
  221    }
  222    
  223    
  224    /*
  225     * ¥â¥¸¥å¡¼¥ë¤Î²òÊü½èÍý
  226     * ¥â¥¸¥å¡¼¥ë¤Î»²¾È¿ô¤¬ 0 ¤Ç¤¢¤ì¤Ð¡¢rmmod »þ¤Ë¸Æ¤Ð¤ì¤ë
  227     */
  228    void 
  229    cleanup_module( void )
  230    {
  231        if ( unregister_chrdev( devmajor, devname ) ) {
  232            log_format( "unregister_chrdev failed" );
  233            /* Âкö̵¤· ... */
  234        }
  235    
  236        log_format( "removed from kernel" );
  237    }
  238    
  239    
  240    /* End of block.c */

¡û ¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤ÎÀâÌÀ

¤Ç¤Ï¡¢¥µ¥ó¥×¥ë¥×¥í¥°¥é¥à¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤¤¤­¤Þ¤¹¡£

block.c ¤Ï¡¢Á°²ó¤Î multiproc.c ¤ò´ðËܤȤ·¤Æ¡¢¥Ö¥í¥Ã¥¯ÍѤνèÍý¤òÄɲ䷤Ƥ¤¤Þ¤¹¡£¤³¤³¤Ç¤ÏÊѹ¹ÅÀ¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Þ¤¹¡£

  • 7 ¡Á 8 ¹ÔÌÜ

    ¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ËɬÍפʥإåÀ¥Õ¥¡¥¤¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¤¤¤Þ¤¹¡£

  • 26 ¡Á 27 ¹ÔÌÜ

    ¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ÎÂÔ¤ÁÎó¤È¸Æ¤Ð¤ì¤ë¥Ç¡¼¥¿¹½Â¤ wait_queue_head_t ·¿ÊÑ¿ô¤òÀë¸À¤·¤Æ¤¤¤Þ¤¹¡£write_q ¤Ï½ñ¤­¹þ¤ß ¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ÎÂÔ¤ÁÎó¤Ç¡¢read_q ¤ÏÆɤ߹þ¤ß¥×¥í¥»¥¹ ¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤ÎÂÔ¤ÁÎó¤Ç¤¹¡£ÂÔ¤ÁÎó¤Ë¤Ä¤¤¤Æ¤Ï¸å½Ò¤·¤Þ¤¹¡£

  • 30 ¡Á 43 ¹ÔÌÜ

    ¥í¥°½ÐÎÏ¥Õ¥©¡¼¥Þ¥Ã¥È¤ò·¤¨¤ë¤¿¤á¤Ë¡¢ÀìÍѤδؿô¤òÍÑ°Õ¤·¤Þ¤·¤¿¡£ current->pid / current->comm ¤È¤¤¤¦ÊÑ¿ô¤ò»ÈÍѤ·¤Æ¤¤¤Þ¤¹¤¬¡¢current ¤Ï¸½ºß¼Â¹ÔÃæ¤Î¥æ¡¼¥¶¥×¥í¥»¥¹¤Ë´Ø¤¹¤ë¾ðÊó¤ò»²¾È¤¹¤ë¤¿¤á¤ÎÊÑ¿ô¤Ç struct task_struct ¹½Â¤ÂΤòº¹¤¹¥Ý¥¤¥ó¥¿¤Ç¤¹¡£linux/sched.h ¤ò ¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤³¤È¤Ç»²¾È¤Ç¤­¤Þ¤¹¡£

    pid ¥á¥ó¥Ð¤Ï̾Á°¤ÎÄ̤ê¥×¥í¥»¥¹ ID ¤òɽ¤¹À°¿ôÃͤǡ¢comm ¤Ï ¥³¥Þ¥ó¥É̾¤òɽ¤¹Ê¸»úÎó¤Ç¤¹¡£¤³¤ì¤é¤ò¥í¥°¤Ë½ÐÎϤ¹¤ëÍͤˤ·¤Æ¤¤¤Þ¤¹¡£

  • 68 ¡Á 130 ¹ÔÌÜ ( chardev_read )
    • 86 ¹ÔÌÜ ¡Á 103 ¹ÔÌÜ

      ¥»¥Þ¥Õ¥©¤ò¼èÆÀ¤·¤¿Ä¾¸å¤Î½èÍý¤Ç¤¹¡£¥æ¡¼¥¶¥×¥í¥»¥¹¤ËÊÖ¤»¤ë ¥Ç¡¼¥¿¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç ( buf_pos == 0 )¡¢¥Ç¥Ã¥É¥í¥Ã¥¯¤¬À¸¤¸¤Ê¤¤ÍÍ ¤Ë¤Þ¤º¥»¥Þ¥Õ¥©¤ò²òÊü¤·¤Þ¤¹¡£¤½¤Î¸å¡¢¥Ç¥Ð¥¤¥¹¤ËÂФ·¤ÆÈó¥Ö¥í¥Ã¥¯»ØÄê ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ÂÔ¤Á¾õÂ֤ˤ»¤º¤Ë¤½¤Î»þÅÀ¤Ç½ªÎ»¤·¤Þ¤¹¡£

      Èó¥Ö¥í¥Ã¥¯»ØÄꤵ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«¤Ï¡¢chardev_read ¤Ë°ú¿ô¤È¤·¤Æ ÅϤµ¤ì¤ë struct file ¹½Â¤ÂΤؤΥݥ¤¥ó¥¿ filp ¤ò»È¤¤¡¢f_flags ¥á¥ó¥Ð¤òÄ´¤Ù¤Þ¤¹¡£¤³¤Î¥Õ¥é¥°¤Ë O_NONBLOCK ¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¾ì¹ç ¤ÏÈó¥Ö¥í¥Ã¥¯»ØÄꤵ¤ì¤Æ¤¤¤Þ¤¹¡£

      ¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤Ë¡¢wait_event_interruptible ¤ò ¼Â¹Ô¤·¤Þ¤¹¡£

      #include <linux/sched.h>
      int wait_event_interruptible( wait_queue_head_t queue, int condition );
                

      wait_queue_head_t ¤Ï linux/wait.h ¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëÂÔ¤ÁÎó¤È ¸Æ¤Ð¤ì¤ë¥Ç¡¼¥¿¹½Â¤¤Ç¡¢¥¤¥Ù¥ó¥È¤ÎÄÌÃΤòÂÔ¤Ä¥×¥í¥»¥¹¤Î¥ê¥¹¥È¤ò ³ÊǼ¤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£ block.c ¤Ç¤Ï static ÊÑ¿ô¤È¤·¤Æ read / write ÍѤÎÂÔ¤ÁÎó¤¬Àë¸À¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ ¤³¤³¤Ç¤Ï¡¢Æɤ߹þ¤ß¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á read_q ¤ò»È¤Ã¤Æ ¤¤¤Þ¤¹¡£

      ¤³¤ÎÂÔ¤ÁÎó¤Ï½é´ü²½¤·¤Æ»ÈÍѤ·¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤³¤Ç¤Ï init_module Æâ¤Ç init_waitqueue_head ¤Ë¤è¤Ã¤Æ½é´ü²½¤·¤Æ¤¤¤Þ¤¹¤¬¡¢ ÀÅŪ¤ÊÊÑ¿ô¤È¤·¤ÆÍÑ°Õ¤¹¤ë¾ì¹ç¤Ï DECLARE_WAIT_QUEUE_HEAD ¥Þ¥¯¥í ¤Ë¤è¤Ã¤Æ½é´ü²½¤ò¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¹Ô¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£

      #include <linux/wait.h>
      init_waitqueue_head( wait_queue_head_t* queue_p );
      DECLARE_WAIT_QUEUE_HEAD( wait_queue_head_t queue );
                

      wait_event_interruptible ¤Ï¡¢condition ¤Ë»ØÄꤵ¤ì¤¿¼°¤¬ 0 ¤Ç¤¢¤ë¾ì¹ç¤Ï¸½ºß¤Î¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ·¤Þ¤¹¡£ÂÔ¤Á¾õÂÖ¤¬²ò½ü ¤µ¤ì¤ë¤È¤Þ¤¿ condition ¤ÎȽÄê¤ò¹Ô¤¤¡¢0 ¤Ç¤¢¤ì¤ÐºÆÅÙ¥×¥í¥»¥¹¤ò ÂÔ¤Á¾õÂ֤ˤ·¤Þ¤¹¡£condition ¤¬Èó 0 ¤¢¤ë¤¤¤Ï¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ ³ä¤ê¹þ¤Þ¤ì¤¿¾ì¹ç¤Ë¡¢wait_event_interruptible ¤Ï½ªÎ»¤·¤Þ¤¹¡£ condition ¤¬Èó 0 ¤Ç½ªÎ»¤·¤¿¾ì¹ç¤Ï 0 ¤òÊÖ¤·¤Þ¤¹¡£

      wait_event_interruptible ¤¬ 0 ¤òÊÖ¤µ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¡¢ ¥·¥°¥Ê¥ë¤Ë¤è¤Ã¤Æ³ä¤ê¹þ¤Þ¤ì¤¿¤È¤ß¤Ê¤·¤Æ -ERESTARTSYS ¤òÊÖ¤·¤Æ¤¤¤Þ¤¹¡£ 0 ¤òÊÖ¤·¤¿¾ì¹ç¤ÏºÆÅÙ¥»¥Þ¥Õ¥©¤ò¼èÆÀ¤·¡¢¥»¥Þ¥Õ¥©¼èÆÀÁ°¤ËÊÌ ¥×¥í¥»¥¹¤Ë¤è¤Ã¤Æ¥Ç¡¼¥¿¤¬¾ÃÈñ¤µ¤ì¤Æ¤¤¤Ê¤¤¤«¤É¤¦¤«¤ò³Îǧ¤¹¤ë¤¿¤á¤Ë while ¥ë¡¼¥×¤ÎºÇ½é¤ËÌá¤ê¤Þ¤¹¡£

    • 127 ¹ÔÌÜ

      Æɤ߹þ¤ß½èÍý¤¬½ª¤ï¤Ã¤¿¸å¡¢ÂÔ¤Á¾õÂ֤ˤʤäƤ¤¤ë½ñ¤­¹þ¤ß¥×¥í¥»¥¹ ¤ò¼Â¹Ô²Äǽ¾õÂ֤ˤ¹¤ë¤¿¤á¤Ë wake_up_interruptible ¤ò¼Â¹Ô¤·¤Þ¤¹¡£

      #include <linux/sched.h>
      wake_up_interruptible( wait_queue_head_t* queue );
                

      »ÈÍѤ·¤Æ¤¤¤ëÂÔ¤ÁÎó¤Ï½ñ¤­¹þ¤ß¥×¥í¥»¥¹¤ÎÂÔ¤ÁÎó write_q ¤Ç¤¹¡£ ¤³¤ì¤ò¼Â¹Ô¤·¤Ê¤¤¤È¡¢ÂÔ¤Á¾õÂ֤ˤʤäƤ¤¤ë½ñ¤­¹þ¤ß¥×¥í¥»¥¹¤Ï ±Ê±ó¤ËÂÔ¤Á¾õÂ֤ˤʤäƤ·¤Þ¤¦¤¿¤áÃí°Õ¤·¤Æ²¼¤µ¤¤¡£

  • 133 ¡Á 189 ¹ÔÌÜ ( chardev_write )

    chardev_read ƱÍÍ¡¢¥×¥í¥»¥¹¤òÂÔ¤Á¾õÂ֤ˤ¹¤ë¤¿¤á¤Î½èÍý¤ò¹Ô¤Ã¤Æ¤¤¤Þ¤¹¡£ chardev_read ¤È°Û¤Ê¤ëÅÀ¤Ï¡¢¥Ö¥í¥Ã¥¯È½ÄêÍѤξò·ïʸ¤¬°Û¤Ê¤ë / wait_event_interruptible ¤Ç»ÈÍѤ·¤Æ¤¤¤ëÂÔ¤ÁÎó¤¬ write_q ¤Ç¤¢¤ë / wake_up_interruptible ¤Ç»ÈÍѤ·¤Æ¤¤¤ëÂÔ¤ÁÎó¤¬ read_q ¤Ç¤¢¤ë¡¢ ¤È¤¤¤Ã¤¿ÅÀ¤Ç¤¹¡£

  • 202 ¡Á 221 ¹ÔÌÜ ( init_module )

    ÂÔ¤ÁÎó½é´ü²½ÍѤνèÍý init_waitqueue_head ¤¬Äɲ䵤ì¤Æ¤¤¤Þ¤¹¡£

    #include <linux/wait.h>
    init_waitqueue_head( wait_queue_head_t* queue_p );
              

°Ê¾å¤Ç block.c ¤Î²òÀâ¤Ï½ª¤ï¤ê¤Ç¤¹¡£¼¡²ó¤Ï¡¢O_NONBLOCK »ØÄê¤ò¤»¤º¤ËÈó¥Ö¥í¥Ã¥¯ I/O ¤ò¹Ô¤¤¤¿¤¤¾ì¹ç¤Ë»ÈÍѤ¹¤ë¥·¥¹¥Æ¥à¥³¡¼¥ë select ( poll ) ¤ËÂбþ¤µ¤»¤Þ¤¹¡£