presentation notes for inter process communication
play

Presentation notes for Inter Process Communication Pipes 1. - PDF document

Presentation notes for Inter Process Communication Pipes 1. Structure pipe_inode_info (/usr/src/linux-2.4/include/linux/pipe_fs_i.h ) 5 struct pipe_inode_info { 6 wait_queue_head_t wait; // Pipe/FIFO wait queue 7 char *base; //


  1. Presentation notes for Inter Process Communication Pipes 1. Structure pipe_inode_info (/usr/src/linux-2.4/include/linux/pipe_fs_i.h ) 5 struct pipe_inode_info { 6 wait_queue_head_t wait; // Pipe/FIFO wait queue 7 char *base; // address of buffer 8 unsigned int len; // # bytes written to buffer yet to be read 9 unsigned int start; // offset of next byte to be read 10 unsigned int readers; // # readers 11 unsigned int writers; // # writers 12 unsigned int waiting_readers; // # reading processes in queue 13 unsigned int waiting_writers; // # writing processes in queue 14 unsigned int r_counter; 15 unsigned int w_counter; 16 }; 2. Mounting of pipefs special file system (/usr/src/linux-2.4/fs/pipe.c ) 630 static int __init init_pipe_fs(void) 631 { 632 int err = register_filesystem(&pipe_fs_type); 633 if (!err) { 634 pipe_mnt = kern_mount(&pipe_fs_type); 635 err = PTR_ERR(pipe_mnt); 636 if (IS_ERR(pipe_mnt)) 637 unregister_filesystem(&pipe_fs_type); 638 else 639 err = 0; 640 } 641 return err; 642 }

  2. 3. Creation of a pipe sys_pipe () function (/usr/src/linux-2.4/arch/i386/kernel/sys_i386.c) 29 asmlinkage int sys_pipe(unsigned long * fildes) 30 { 31 int fd[2]; 32 int error; 33 34 error = do_pipe(fd); 35 if (!error) { 36 if (copy_to_user(fildes, fd, 2*sizeof(int))) 37 error = -EFAULT; 38 } 39 return error; 40 } do_pipe () function (/usr/src/linux-2.4/fs/pipe.c ) 505 int do_pipe(int *fd) 506 { 507 struct qstr this; 508 char name[32]; 509 struct dentry *dentry; 510 struct inode * inode; 511 struct file *f1, *f2; 512 int error; 513 int i,j; 514 515 error = -ENFILE; 516 f1 = get_empty_filp(); 517 if (!f1) 518 goto no_files; 519 520 f2 = get_empty_filp(); 521 if (!f2) 522 goto close_f1; 523 524 inode = get_pipe_inode(); . . . . 585 }

  3. get_pipe_inode () function (/usr/src/linux-2.4/fs/pipe.c ) 473 static struct inode * get_pipe_inode(void) 474 { 475 struct inode *inode = new_inode(pipe_mnt->mnt_sb); 476 477 if (!inode) 478 goto fail_inode; 479 480 if(!pipe_new(inode)) 481 goto fail_iput; 482 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; . . . . 503 } pipe_new() function (/usr/src/linux-2.4/fs/pipe.c ) 439 struct inode* pipe_new(struct inode* inode) 440 { 441 unsigned long page; 442 443 page = __get_free_page(GFP_USER); 444 if (!page) 445 return NULL; 446 447 inode->i_pipe = kmalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); 448 if (!inode->i_pipe) 449 goto fail_page; 450 451 init_waitqueue_head(PIPE_WAIT(*inode)); 452 PIPE_BASE(*inode) = (char*) page; 453 PIPE_START(*inode) = PIPE_LEN(*inode) = 0; 454 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; 455 PIPE_WAITING_READERS(*inode) = PIPE_WAITING_WRITERS(*inode)=0; 456 PIPE_RCOUNTER(*inode) = PIPE_WCOUNTER(*inode) = 1; . . . . 462 }

  4. 4. Reading from a pipe pipe_read () function (/usr/src/linux-2.4/fs/pipe.c ) 39 static ssize_t 40 pipe_read(struct file *filp, char *buf, size_t count, loff_t *ppos) 41 { 42 struct inode *inode = filp->f_dentry->d_inode; 43 ssize_t size, read, ret; 44 45 /* Seeks are not allowed on pipes. */ 46 ret = -ESPIPE; 47 read = 0; 48 if (ppos != &filp->f_pos) 49 goto out_nolock; 50 51 /* Always return 0 on null read. */ 52 ret = 0; 53 if (count == 0) 54 goto out_nolock; 55 56 /* Get the pipe semaphore */ 57 ret = -ERESTARTSYS; 58 if (down_interruptible(PIPE_SEM(*inode))) 59 goto out_nolock; 60 61 if (PIPE_EMPTY(*inode)) { 62 do_more_read: 63 ret = 0; 64 if (!PIPE_WRITERS(*inode)) 65 goto out; 66 67 ret = -EAGAIN; 68 if (filp->f_flags & O_NONBLOCK) 69 goto out; 70 71 for (;;) { 72 PIPE_WAITING_READERS(*inode)++; 73 pipe_wait(inode); 74 PIPE_WAITING_READERS(*inode)--; . . . . 84 } 85 86 out: /* Read what data is available. */ 87 ret = -EFAULT; 88 while (count > 0 && (size = PIPE_LEN(*inode))) { 89 char *pipebuf = PIPE_BASE(*inode) + PIPE_START(*inode); 90 ssize_t chars = PIPE_MAX_RCHUNK(*inode); 91 92 if (chars > count) 93 chars = count; 94 if (chars > size)

  5. 95 chars = size; 96 97 if (copy_to_user(buf, pipebuf, chars)) 98 goto out; 99 100 read += chars; 101 PIPE_START(*inode) += chars; 102 PIPE_START(*inode) &= (PIPE_SIZE - 1); 103 PIPE_LEN(*inode) -= chars; 104 count -= chars; 105 buf += chars; 106 } . . . . 112 if (count && PIPE_WAITING_WRITERS(*inode) && !(filp- >f_flags & O_NONBLOCK)) { 113 /* 114 * We know that we are going to sleep: signal 115 * writers synchronously that there is more 116 * room. 117 */ 118 wake_up_interruptible_sync(PIPE_WAIT(*inode)); 119 if (!PIPE_EMPTY(*inode)) 120 BUG(); 121 goto do_more_read; 122 } 123 /* Signal writers asynchronously that there is more room. */ 124 wake_up_interruptible(PIPE_WAIT(*inode)); 125 126 ret = read; 127 out: 128 up(PIPE_SEM(*inode)); 129 out_nolock: 130 if (read) 131 ret = read; 132 133 UPDATE_ATIME(inode); 134 return ret; 135 }

  6. 5. pipe_wait() function (/usr/src/linux-2.4/fs/pipe.c) 27 void pipe_wait(struct inode * inode) 28 { 29 DECLARE_WAITQUEUE(wait, current); 30 current->state = TASK_INTERRUPTIBLE; 31 add_wait_queue(PIPE_WAIT(*inode), &wait); 32 up(PIPE_SEM(*inode)); 33 schedule(); 34 remove_wait_queue(PIPE_WAIT(*inode), &wait); 35 current->state = TASK_RUNNING; 36 down(PIPE_SEM(*inode)); 37 } 6. Writing to a pipe pipe_write () function (/usr/src/linux-2.4/fs/pipe.c ) 137 static ssize_t 138 pipe_write(struct file *filp, const char *buf, size_t count, loff_t *ppos) 139 { 140 struct inode *inode = filp->f_dentry->d_inode; . . . . 153 /* Acquire the semaphore. */ 154 ret = -ERESTARTSYS; 155 if (down_interruptible(PIPE_SEM(*inode))) 156 goto out_nolock; 157 158 /* No readers yields SIGPIPE. */ 159 if (!PIPE_READERS(*inode)) 160 goto sigpipe; 161 162 /* If count <= PIPE_BUF, we have to make it atomic. */ 163 free = (count <= PIPE_BUF ? count : 1); 164 165 /* Wait, or check for, available space. */ 166 if (filp->f_flags & O_NONBLOCK) { 167 ret = -EAGAIN; 168 if (PIPE_FREE(*inode) < free) 169 goto out; 170 } else { 171 while (PIPE_FREE(*inode) < free) { 172 PIPE_WAITING_WRITERS(*inode)++; 173 pipe_wait(inode); 174 PIPE_WAITING_WRITERS(*inode)--; 175 ret = -ERESTARTSYS; 176 if (signal_pending(current)) 177 goto out; 178 179 if (!PIPE_READERS(*inode))

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend