comparison src/pipe.cbc @ 52:214d21c891c7

rename to cbc __ncode is not handled as interfaces
author kono
date Mon, 03 Jun 2019 18:12:44 +0900
parents src/pipe.c@fb3e5a2f76c1
children
comparison
equal deleted inserted replaced
51:fadfd62d6b14 52:214d21c891c7
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 #define __ncode __code
13 #
14 struct pipe {
15 struct spinlock lock;
16 char data[PIPESIZE];
17 uint nread; // number of bytes read
18 uint nwrite; // number of bytes written
19 int readopen; // read fd is still open
20 int writeopen; // write fd is still open
21 };
22
23 int pipealloc(struct file **f0, struct file **f1)
24 {
25 struct pipe *p;
26
27 p = 0;
28 *f0 = *f1 = 0;
29
30 if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0) {
31 goto bad;
32 }
33
34 if((p = kmalloc (get_order(sizeof(*p)))) == 0) {
35 goto bad;
36 }
37
38 p->readopen = 1;
39 p->writeopen = 1;
40 p->nwrite = 0;
41 p->nread = 0;
42
43 initlock(&p->lock, "pipe");
44
45 (*f0)->type = FD_PIPE;
46 (*f0)->readable = 1;
47 (*f0)->writable = 0;
48 (*f0)->pipe = p;
49 (*f1)->type = FD_PIPE;
50 (*f1)->readable = 0;
51 (*f1)->writable = 1;
52 (*f1)->pipe = p;
53
54 return 0;
55
56 //PAGEBREAK: 20
57 bad:
58 if(p) {
59 kfree (p, get_order(sizeof*p));
60 }
61
62 if(*f0) {
63 fileclose(*f0);
64 }
65
66 if(*f1) {
67 fileclose(*f1);
68 }
69
70 return -1;
71 }
72
73 void pipeclose(struct pipe *p, int writable)
74 {
75 acquire(&p->lock);
76
77 if(writable){
78 p->writeopen = 0;
79 wakeup(&p->nread);
80
81 } else {
82 p->readopen = 0;
83 wakeup(&p->nwrite);
84 }
85
86 if(p->readopen == 0 && p->writeopen == 0){
87 release(&p->lock);
88 kfree (p, get_order(sizeof(*p)));
89
90 } else {
91 release(&p->lock);
92 }
93 }
94
95 //PAGEBREAK: 40
96 int pipewrite(struct pipe *p, char *addr, int n)
97 {
98 int i;
99
100 acquire(&p->lock);
101
102 for(i = 0; i < n; i++){
103 while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full
104 if(p->readopen == 0 /*|| proc->killed*/){
105 release(&p->lock);
106 return -1;
107 }
108
109 wakeup(&p->nread);
110 sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep
111 }
112
113 p->data[p->nwrite++ % PIPESIZE] = addr[i];
114 }
115
116 wakeup(&p->nread); //DOC: pipewrite-wakeup1
117 release(&p->lock);
118 return n;
119 }
120
121 __ncode cbc_piperead3(){
122 struct pipe *p = proc->cbc_arg.cbc_console_arg.p;
123 int i = proc->cbc_arg.cbc_console_arg.i;
124 __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next;
125 release(&p->lock);
126
127 goto next(i);
128 }
129
130 __ncode cbc_piperead2(){
131 int i = proc->cbc_arg.cbc_console_arg.i;
132 int n = proc->cbc_arg.cbc_console_arg.n;
133 struct pipe *p = proc->cbc_arg.cbc_console_arg.p;
134 char *addr = proc->cbc_arg.cbc_console_arg.addr;
135 if (i < n && !(p->nread == p->nwrite)) {
136 addr[i] = p->data[p->nread++ % PIPESIZE];
137 i ++;
138 proc->cbc_arg.cbc_console_arg.i = i;
139 proc->cbc_arg.cbc_console_arg.p = p;
140 proc->cbc_arg.cbc_console_arg.addr = addr;
141 goto cbc_piperead2();
142 }
143 proc->cbc_arg.cbc_console_arg.p = p;
144 goto cbc_wakeup(&p->nwrite, cbc_piperead3); //DOC: piperead-wakeup
145 }
146
147 __ncode cbc_piperead1(){
148 struct pipe *p = proc->cbc_arg.cbc_console_arg.p;
149 __code(*next)(int ret) = proc->cbc_arg.cbc_console_arg.next;
150 if (p->nread == p->nwrite && p->writeopen){
151 if(proc->killed){
152 release(&p->lock);
153 goto next(-1);
154 }
155 proc->cbc_arg.cbc_console_arg.p = p;
156 goto cbc_sleep(&p->nread, &p->lock, cbc_piperead1);
157 }
158 int i = 0;
159 proc->cbc_arg.cbc_console_arg.i = i;
160 proc->cbc_arg.cbc_console_arg.p = p;
161 goto cbc_piperead2();
162 }
163
164 __ncode cbc_piperead(struct pipe *p, char *addr, int n, __code (*next)(int ret))
165 {
166 acquire(&p->lock);
167 proc->cbc_arg.cbc_console_arg.n = n;
168 proc->cbc_arg.cbc_console_arg.p = p;
169 proc->cbc_arg.cbc_console_arg.addr = addr;
170 proc->cbc_arg.cbc_console_arg.next = next;
171 goto cbc_piperead1();
172 }
173
174 int piperead(struct pipe *p, char *addr, int n)
175 {
176 int i;
177
178 acquire(&p->lock);
179
180 while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty
181 if(proc->killed){
182 release(&p->lock);
183 return -1;
184 }
185
186 sleep(&p->nread, &p->lock); //DOC: piperead-sleep*/
187 }
188
189 for(i = 0; i < n; i++){ //DOC: piperead-copy
190 if(p->nread == p->nwrite) {
191 break;
192 }
193
194 addr[i] = p->data[p->nread++ % PIPESIZE];
195 }
196
197 wakeup(&p->nwrite); //DOC: piperead-wakeup
198 release(&p->lock);
199
200 return i;
201 }