提交 ab809e2d 创建 作者: Silas Boyd-Wickizer's avatar Silas Boyd-Wickizer

Code to support consoleread.

上级 9d082db1
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
#include "condvar.h" #include "condvar.h"
#include "file.h" #include "file.h"
#include "x86.h" #include "x86.h"
#include "queue.h"
#include "proc.h"
#include <stdarg.h> #include <stdarg.h>
#define BACKSPACE 0x100 #define BACKSPACE 0x100
...@@ -227,10 +228,94 @@ consolewrite(struct inode *ip, char *buf, int n) ...@@ -227,10 +228,94 @@ consolewrite(struct inode *ip, char *buf, int n)
return n; return n;
} }
#define INPUT_BUF 128
struct {
struct spinlock lock;
struct condvar cv;
char buf[INPUT_BUF];
int r; // Read index
int w; // Write index
int e; // Edit index
} input;
#define C(x) ((x)-'@') // Control-x
void
consoleintr(int (*getc)(void))
{
int c;
acquire(&input.lock);
while((c = getc()) >= 0){
switch(c){
case C('P'): // Process listing.
procdumpall();
break;
case C('U'): // Kill line.
while(input.e != input.w &&
input.buf[(input.e-1) % INPUT_BUF] != '\n'){
input.e--;
consputc(BACKSPACE);
}
break;
case C('H'): case '\x7f': // Backspace
if(input.e != input.w){
input.e--;
consputc(BACKSPACE);
}
break;
default:
if(c != 0 && input.e-input.r < INPUT_BUF){
c = (c == '\r') ? '\n' : c;
input.buf[input.e++ % INPUT_BUF] = c;
consputc(c);
if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){
input.w = input.e;
cv_wakeup(&input.cv);
}
}
break;
}
}
release(&input.lock);
}
static int static int
consoleread(struct inode *ip, char *dst, int n) consoleread(struct inode *ip, char *dst, int n)
{ {
panic("consoleread"); int target;
int c;
iunlock(ip);
target = n;
acquire(&input.lock);
while(n > 0){
while(input.r == input.w){
if(myproc()->killed){
release(&input.lock);
ilock(ip, 1);
return -1;
}
cv_sleep(&input.cv, &input.lock);
}
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--;
}
break;
}
*dst++ = c;
--n;
if(c == '\n')
break;
}
release(&input.lock);
ilock(ip, 1);
return target - n;
} }
void void
......
...@@ -572,6 +572,49 @@ kill(int pid) ...@@ -572,6 +572,49 @@ kill(int pid)
return 0; return 0;
} }
void *procdump(void *vk, void *v, void *arg)
{
struct proc *p = (struct proc *) v;
static char *states[] = {
[UNUSED] "unused",
[EMBRYO] "embryo",
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};
char *state;
if(p->state >= 0 && p->state < NELEM(states) && states[p->state])
state = states[p->state];
else
state = "???";
cprintf("%d %s %s %d, ", p->pid, state, p->name, p->cpuid);
// XXX(sbw)
#if 0
uint pc[10];
if(p->state == SLEEPING){
getcallerpcs((uint*)p->context->ebp+2, pc);
for(int i=0; i<10 && pc[i] != 0; i++)
cprintf(" %p", pc[i]);
}
#endif
cprintf("\n");
return 0;
}
//PAGEBREAK: 36
// Print a process listing to console. For debugging.
// Runs when user types ^P on console.
// No lock to avoid wedging a stuck machine further.
void
procdumpall(void)
{
ns_enumerate(nspid, procdump, 0);
}
// Create a new process copying p as the parent. // Create a new process copying p as the parent.
// Sets up stack to return as if from system call. // Sets up stack to return as if from system call.
// Caller must set state of returned proc to RUNNABLE. // Caller must set state of returned proc to RUNNABLE.
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论