Mercurial > hg > Members > menikon > CbC_xv6
comparison src/pipe.c @ 0:83c23a36980d
Init
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 26 May 2017 23:11:05 +0900 |
parents | |
children | ad1d3b268e2d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:83c23a36980d |
---|---|
1 #include "types.h" | |
2 #include "defs.h" | |
3 #include "param.h" | |
4 #include "mmu.h" | |
5 #include "proc.h" | |
6 #include "fs.h" | |
7 #include "file.h" | |
8 #include "spinlock.h" | |
9 | |
10 #define PIPESIZE 512 | |
11 | |
12 struct pipe { | |
13 struct spinlock lock; | |
14 char data[PIPESIZE]; | |
15 uint nread; // number of bytes read | |
16 uint nwrite; // number of bytes written | |
17 int readopen; // read fd is still open | |
18 int writeopen; // write fd is still open | |
19 }; | |
20 | |
21 int pipealloc(struct file **f0, struct file **f1) | |
22 { | |
23 struct pipe *p; | |
24 | |
25 p = 0; | |
26 *f0 = *f1 = 0; | |
27 | |
28 if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) { | |
29 goto bad; | |
30 } | |
31 | |
32 if((p = kmalloc (get_order(sizeof(*p)))) == 0) { | |
33 goto bad; | |
34 } | |
35 | |
36 p->readopen = 1; | |
37 p->writeopen = 1; | |
38 p->nwrite = 0; | |
39 p->nread = 0; | |
40 | |
41 initlock(&p->lock, "pipe"); | |
42 | |
43 (*f0)->type = FD_PIPE; | |
44 (*f0)->readable = 1; | |
45 (*f0)->writable = 0; | |
46 (*f0)->pipe = p; | |
47 (*f1)->type = FD_PIPE; | |
48 (*f1)->readable = 0; | |
49 (*f1)->writable = 1; | |
50 (*f1)->pipe = p; | |
51 | |
52 return 0; | |
53 | |
54 //PAGEBREAK: 20 | |
55 bad: | |
56 if(p) { | |
57 kfree (p, get_order(sizeof*p)); | |
58 } | |
59 | |
60 if(*f0) { | |
61 fileclose(*f0); | |
62 } | |
63 | |
64 if(*f1) { | |
65 fileclose(*f1); | |
66 } | |
67 | |
68 return -1; | |
69 } | |
70 | |
71 void pipeclose(struct pipe *p, int writable) | |
72 { | |
73 acquire(&p->lock); | |
74 | |
75 if(writable){ | |
76 p->writeopen = 0; | |
77 wakeup(&p->nread); | |
78 | |
79 } else { | |
80 p->readopen = 0; | |
81 wakeup(&p->nwrite); | |
82 } | |
83 | |
84 if(p->readopen == 0 && p->writeopen == 0){ | |
85 release(&p->lock); | |
86 kfree (p, get_order(sizeof(*p))); | |
87 | |
88 } else { | |
89 release(&p->lock); | |
90 } | |
91 } | |
92 | |
93 //PAGEBREAK: 40 | |
94 int pipewrite(struct pipe *p, char *addr, int n) | |
95 { | |
96 int i; | |
97 | |
98 acquire(&p->lock); | |
99 | |
100 for(i = 0; i < n; i++){ | |
101 while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full | |
102 if(p->readopen == 0 /*|| proc->killed*/){ | |
103 release(&p->lock); | |
104 return -1; | |
105 } | |
106 | |
107 wakeup(&p->nread); | |
108 sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep | |
109 } | |
110 | |
111 p->data[p->nwrite++ % PIPESIZE] = addr[i]; | |
112 } | |
113 | |
114 wakeup(&p->nread); //DOC: pipewrite-wakeup1 | |
115 release(&p->lock); | |
116 return n; | |
117 } | |
118 | |
119 int piperead(struct pipe *p, char *addr, int n) | |
120 { | |
121 int i; | |
122 | |
123 acquire(&p->lock); | |
124 | |
125 while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty | |
126 if(proc->killed){ | |
127 release(&p->lock); | |
128 return -1; | |
129 } | |
130 | |
131 sleep(&p->nread, &p->lock); //DOC: piperead-sleep*/ | |
132 } | |
133 | |
134 for(i = 0; i < n; i++){ //DOC: piperead-copy | |
135 if(p->nread == p->nwrite) { | |
136 break; | |
137 } | |
138 | |
139 addr[i] = p->data[p->nread++ % PIPESIZE]; | |
140 } | |
141 | |
142 wakeup(&p->nwrite); //DOC: piperead-wakeup | |
143 release(&p->lock); | |
144 | |
145 return i; | |
146 } |