More pread, syscall crud

上级 47ab9b8c
struct ipcctl { struct ipcctl {
volatile char done; volatile char done:1;
volatile char submitted:1;
off_t off;
volatile long result; volatile long result;
}; };
...@@ -59,6 +59,7 @@ sys_kernlet(int fd, size_t count, off_t off) ...@@ -59,6 +59,7 @@ sys_kernlet(int fd, size_t count, off_t off)
{ {
struct file *f; struct file *f;
struct work *w; struct work *w;
struct ipcctl *ipc = (struct ipcctl *)myproc()->vmap->kshared;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0) if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1; return -1;
...@@ -76,5 +77,7 @@ sys_kernlet(int fd, size_t count, off_t off) ...@@ -76,5 +77,7 @@ sys_kernlet(int fd, size_t count, off_t off)
freework(w); freework(w);
return -1; return -1;
} }
ipc->off = off;
ipc->submitted = 1;
return 0; return 0;
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "stat.h" #include "stat.h"
#include "fcntl.h" #include "fcntl.h"
#include "user.h" #include "user.h"
#include "lib.h"
#include "amd64.h" #include "amd64.h"
#include "ipc.h" #include "ipc.h"
...@@ -24,6 +25,31 @@ kernlet_pread(int fd, size_t count, off_t off) ...@@ -24,6 +25,31 @@ kernlet_pread(int fd, size_t count, off_t off)
die("kernlet"); die("kernlet");
} }
static ssize_t
xpread(int fd, void *buf, size_t count, off_t off)
{
if (ipcctl->submitted) {
while (ipcctl->done == 0)
nop_pause();
if (ipcctl->result == -1)
goto slow;
if (off < ipcctl->off)
goto slow;
if (off > ipcctl->off + ipcctl->result)
goto slow;
char *kbuf = (char*) (KSHARED+4096);
off_t kbufoff = off - ipcctl->off;
size_t kbufcount = MIN(count, ipcctl->result - kbufoff);
memmove(buf, kbuf+kbufoff, kbufcount);
return kbufcount;
}
slow:
return pread(fd, buf, count, off);
}
int int
main(int ac, char **av) main(int ac, char **av)
{ {
...@@ -44,7 +70,7 @@ main(int ac, char **av) ...@@ -44,7 +70,7 @@ main(int ac, char **av)
kernlet_pread(fd, PSIZE, k); kernlet_pread(fd, PSIZE, k);
for (i = k; i < k+PSIZE; i+=BSIZE) for (i = k; i < k+PSIZE; i+=BSIZE)
if (pread(fd, buf, BSIZE, i) != BSIZE) if (xpread(fd, buf, BSIZE, i) != BSIZE)
die("pread failed"); die("pread failed");
} }
t1 = rdtsc(); t1 = rdtsc();
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论