A pread system call

上级 53b19d0a
...@@ -92,7 +92,8 @@ UPROGS= \ ...@@ -92,7 +92,8 @@ UPROGS= \
_sleep \ _sleep \
_dirbench \ _dirbench \
_usertests \ _usertests \
_lockstat _lockstat \
_preadtest
UPROGS := $(addprefix $(O)/, $(UPROGS)) UPROGS := $(addprefix $(O)/, $(UPROGS))
all: $(O)/kernel all: $(O)/kernel
......
#include "types.h"
#include "stat.h"
#include "fcntl.h"
#include "user.h"
#include "amd64.h"
#define FSIZE (64 << 10)
#define BSIZE 4096
static char buf[BSIZE];
int
main(int ac, char **av)
{
u64 t0, t1;
int fd;
int i;
fd = open("preadtest.x", O_CREATE|O_RDWR);
if (fd < 0)
die("open failed");
for (i = 0; i < FSIZE/BSIZE; i++)
if (write(fd, buf, BSIZE) != BSIZE)
die("write failed");
t0 = rdtsc();
for (i = 0; i < FSIZE; i+=BSIZE)
if (pread(fd, buf, BSIZE, i) != BSIZE)
die("pread failed");
t1 = rdtsc();
printf(1, "cycles %lu\n", t1 - t0);
exit();
}
...@@ -174,6 +174,7 @@ extern long sys_socket(int, int, int); ...@@ -174,6 +174,7 @@ extern long sys_socket(int, int, int);
extern long sys_bind(int, void*, int); extern long sys_bind(int, void*, int);
extern long sys_listen(int, int); extern long sys_listen(int, int);
extern long sys_accept(int, void*, void*); extern long sys_accept(int, void*, void*);
extern long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
#define SYSCALL(name) [SYS_##name] = (void*)sys_##name #define SYSCALL(name) [SYS_##name] = (void*)sys_##name
...@@ -206,6 +207,7 @@ static long (*syscalls[])(u64, u64, u64, u64, u64, u64) = { ...@@ -206,6 +207,7 @@ static long (*syscalls[])(u64, u64, u64, u64, u64, u64) = {
SYSCALL(bind), SYSCALL(bind),
SYSCALL(listen), SYSCALL(listen),
SYSCALL(accept), SYSCALL(accept),
SYSCALL(pread),
}; };
void void
......
...@@ -27,3 +27,4 @@ ...@@ -27,3 +27,4 @@
#define SYS_bind 26 #define SYS_bind 26
#define SYS_listen 27 #define SYS_listen 27
#define SYS_accept 28 #define SYS_accept 28
#define SYS_pread 29
...@@ -72,6 +72,27 @@ sys_read(void) ...@@ -72,6 +72,27 @@ sys_read(void)
return fileread(f, p, n); return fileread(f, p, n);
} }
ssize_t
sys_pread(int fd, void *ubuf, size_t count, off_t offset)
{
struct file *f;
int r;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1;
// XXX(sbw) assuming ubuf is ok
if(f->type == FD_INODE){
ilock(f->ip, 0);
if(f->ip->type == 0)
panic("fileread");
r = readi(f->ip, ubuf, offset, count);
iunlock(f->ip);
return r;
}
return -1;
}
long long
sys_write(void) sys_write(void)
{ {
......
...@@ -12,3 +12,8 @@ typedef uptr paddr; ...@@ -12,3 +12,8 @@ typedef uptr paddr;
// Page Map Entry (refers to any entry in any level) // Page Map Entry (refers to any entry in any level)
typedef u64 pme_t; typedef u64 pme_t;
typedef pme_t pml4e_t; typedef pme_t pml4e_t;
// POSIX types
typedef s64 ssize_t;
typedef u64 size_t;
typedef u64 off_t;
...@@ -25,6 +25,7 @@ int uptime(void); ...@@ -25,6 +25,7 @@ int uptime(void);
int map(void *addr, int len); int map(void *addr, int len);
int unmap(void *addr, int len); int unmap(void *addr, int len);
void halt(void); void halt(void);
ssize_t pread(int, void*, size_t, off_t);
// ulib.c // ulib.c
int stat(char*, struct stat*); int stat(char*, struct stat*);
......
...@@ -36,3 +36,4 @@ SYSCALL(socket) ...@@ -36,3 +36,4 @@ SYSCALL(socket)
SYSCALL(bind) SYSCALL(bind)
SYSCALL(listen) SYSCALL(listen)
SYSCALL(accept) SYSCALL(accept)
SYSCALL(pread)
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论