1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
#include "../context.h"
#interface "ReadSyscall.h"
#interface "KernelRet.h"
// ----
// typedef struct ReadSyscallImpl <Type, Isa> impl ReadSyscall {
// __code next(....);
// } ReadSyscallImpl;
// ----
ReadSyscall* createReadSyscallImpl(struct Context* cbc_context) {
struct ReadSyscall* read_syscall = new ReadSyscall();
struct ReadSyscallImpl* read_syscall_impl = new ReadSyscallImpl();
read_syscall->read_syscall = (union Data*)read_syscall_impl;
read_syscall->consoleread = C_consolereadReadSyscallImpl;
read_syscall->consoleread1 = C_consoleread1ReadSyscallImpl;
read_syscall->consoleread2 = C_consoleread2ReadSyscallImpl;
read_syscall->piperead = C_pipereadReadSyscallImpl;
read_syscall->piperead1 = C_piperead1ReadSyscallImpl;
read_syscall->piperead2 = C_piperead2ReadSyscallImpl;
read_syscall->piperead3 = C_piperead3ReadSyscallImpl;
read_syscall->fileread = C_filereadReadSyscallImpl;
read_syscall->fileread1 = C_fileread1ReadSyscallImpl;
return read_syscall;
}
__code consolereadReadSyscallImpl(struct ReadSyscallImpl* read_syscall, struct inode* ip, char* dst, int n, __code next(int ret, ...)) {
uint target;
iunlock(ip);
//target = n;
acquire(&input.lock);
if (n > 0) {
goto read_syscall->consoleread2(...);
}
goto read_syscall->consoleread1(...);
}
__code consoleread1ReadSyscallImpl(struct ReadSyscallImpl* read_syscall,int n, int target, char* dst, struct inode* ip, __code next(...)) {
int cont = 1;
int c = input.buf[input.r++ % INPUT_BUF];
if (c == C('D')) { // EOF
if (n < target) {
// Save ^D for next time, to make sure
// caller gets a 0-byte result.
input.r--;
}
cont = 0;
}
*dst++ = c;
--n;
if (c == '\n') {
cont = 0;
}
if (cont == 1) {
if (n > 0) {
goto cbc_sleep(&input.r, &input.lock, read_syscall->consoleread2);
}
}
release(&input.lock);
ilock(ip);
goto next(target - n);
}
__code consoleread2ReadSyscallImpl(struct ReadSyscallImpl* read_syscall,struct inode* ip, __code next(...)) {
if (input.r == input.w) {
if (proc->killed) {
release(&input.lock);
ilock(ip);
KernelRet* kernel_ret = createKernelRetImpl(cbc_context);
goto kernel_ret->cbc_return(-1);
}
goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2);
}
goto read_sycall->consoleread1();
}
__code pipereadReadSyscallImpl(struct ReadSyscallImpl* read_syscall, struct pipe* p,char* addr, int n, __code next(int ret,...)) {
goto next(ret,...);
}
__code piperead1ReadSyscallImpl(struct ReadSyscallImpl* read_syscall, struct pipe* p, __code next(int ret,...)) {
if (p->nread == p->nwrite && p->writeopen){
if(proc->killed){
release(&p->lock);
KernelRet* kernel_ret = createKernelRetImpl(cbc_context);
goto kernel_ret->cbc_return(-1);
}
goto cbc_sleep(&p->nread, &p->lock, cbc_piperead1);
}
goto read_syscall->piperead2(...);
}
__code piperead2ReadSyscallImpl(struct ReadSyscallImpl* read_syscall, int i, int n, struct pipe* p, char* addr, __code next(...)) {
if (i < n && !(p->nread == p->nwrite)) {
addr[i] = p->data[p->nread++ % PIPESIZE];
i ++;
goto read_syscall->piperead2(i,n, p, addr,next);
}
//proc->cbc_arg.cbc_console_arg.p = p;
goto cbc_wakeup(&p->nwrite, cbc_piperead3); //DOC: piperead-wakeup
}
__code piperead3ReadSyscallImpl(struct ReadSyscallImpl* read_syscall, struct pipe* p, int i, __code next(int ret,...)) {
release(&p->lock);
KernelRet* kernel_ret = createKernelRetImpl(cbc_context);
goto kernel_ret->cbc_return(-1);
}
__code filereadReadSyscallImpl(struct ReadSyscallImpl* read_syscall, struct file* f, char* addr, int n, __code next(int ret, ...)) {
if (f->readable == 0) {
ret = -1;
KernelRet* kernel_ret = createKernelRetImpl(cbc_context);
goto kernel_ret->cbc_return(ret);
}
if (f->type == FD_PIPE) {
goto read_syscall->piperead(f->pipe, addr, n, next);
}
if (f->type == FD_INODE) {
ilock(f->ip);
goto read_syscall->cbc_readi(f->ip, addr, f->off, n, readsys_call->fileread1);
}
goto cbc_panic("fileread");
}
__code fileread1ReadSyscallImpl(struct ReadSyscallImpl* read_syscall, struct file* f, int ret, __code next(ret, ...)) {
if (ret > 0)
f->off += ret;
iunlock(f->ip);
KernelRet* kernel_ret = createKernelRetImpl(cbc_context);
goto kernel_ret->cbc_return(ret);
}
|