1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

add support of remote read and lseek system calls

- reduce latency by disabling the Nagl algorithm
This commit is contained in:
Stefan Lankes 2015-10-05 10:12:34 +02:00
parent ba755badb5
commit 18727027cc
2 changed files with 241 additions and 51 deletions

View file

@ -61,17 +61,21 @@ static void sys_yield(void)
void NORETURN do_exit(int arg);
typedef struct {
int sysnr;
int arg;
} __attribute__((packed)) sys_exit_t;
/** @brief To be called by the systemcall to exit tasks */
void NORETURN sys_exit(int arg)
{
task_t* task = per_core(current_task);
int sysnr = __NR_exit;
sys_exit_t sysargs = {__NR_exit, arg};
if (task->sd >= 0)
{
spinlock_lock(&lwip_lock);
write(task->sd, &sysnr, sizeof(int));
write(task->sd, &arg, sizeof(int));
write(task->sd, &sysargs, sizeof(sysargs));
spinlock_unlock(&lwip_lock);
closesocket(task->sd);
@ -81,11 +85,58 @@ void NORETURN sys_exit(int arg)
do_exit(arg);
}
static int sys_write(int fd, const char* buf, size_t len)
typedef struct {
int sysnr;
int fd;
size_t len;
} __attribute__((packed)) sys_read_t;
static ssize_t sys_read(int fd, char* buf, size_t len)
{
task_t* task = per_core(current_task);
int ret, sysnr = __NR_write;
size_t i;
sys_read_t sysargs = {__NR_read, fd, len};
ssize_t j, ret;
if (task->sd < 0)
return -ENOSYS;
spinlock_lock(&lwip_lock);
write(task->sd, &sysargs, sizeof(sysargs));
read(task->sd, &j, sizeof(j));
if (j > 0)
{
ssize_t i = 0;
while(i < j)
{
ret = read(task->sd, buf+i, j-i);
if (ret < 0) {
spinlock_unlock(&lwip_lock);
return ret;
}
i += ret;
}
}
spinlock_unlock(&lwip_lock);
return j;
}
typedef struct {
int sysnr;
int fd;
size_t len;
} __attribute__((packed)) sys_write_t;
static ssize_t sys_write(int fd, const char* buf, size_t len)
{
task_t* task = per_core(current_task);
ssize_t i, ret;
int flag;
sys_write_t sysargs = {__NR_write, fd, len};
if (BUILTIN_EXPECT(!buf, 0))
return -1;
@ -100,33 +151,35 @@ static int sys_write(int fd, const char* buf, size_t len)
spinlock_lock(&lwip_lock);
ret = write(task->sd, &sysnr, sizeof(int));
if (ret < 0)
goto out;
flag = 0;
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
ret = write(task->sd, &fd, sizeof(int));
if (ret < 0)
goto out;
ret = write(task->sd, &len, sizeof(size_t));
if (ret < 0)
goto out;
write(task->sd, &sysargs, sizeof(sysargs));
i=0;
while(i<len)
while(i < len)
{
ret = write(task->sd, (char*)buf+i, len-i);
if (ret < 0)
goto out;
if (ret < 0) {
spinlock_unlock(&lwip_lock);
return ret;
}
i += ret;
}
ret = len;
flag = 1;
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(flag));
if (fd > 2) {
ret = read(task->sd, &i, sizeof(i));
if (ret < 0)
i = ret;
} else i = len;
out:
spinlock_unlock(&lwip_lock);
return ret;
return i;
}
static ssize_t sys_sbrk(int incr)
@ -159,20 +212,23 @@ static int sys_open(const char* name, int flags, int mode)
{
task_t* task = per_core(current_task);
int i, ret, sysnr = __NR_open;
size_t len = strlen(name+1);
size_t len;
if (task->sd < 0)
return 0;
len = strlen(name+1);
len = strlen(name)+1;
spinlock_lock(&lwip_lock);
ret = write(task->sd, &sysnr, sizeof(int));
i = 0;
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
ret = write(task->sd, &sysnr, sizeof(sysnr));
if (ret < 0)
goto out;
ret = write(task->sd, &len, sizeof(size_t));
ret = write(task->sd, &len, sizeof(len));
if (ret < 0)
goto out;
@ -185,15 +241,18 @@ static int sys_open(const char* name, int flags, int mode)
i += ret;
}
ret = write(task->sd, &flags, sizeof(int));
ret = write(task->sd, &flags, sizeof(flags));
if (ret < 0)
goto out;
ret = write(task->sd, &mode, sizeof(int));
ret = write(task->sd, &mode, sizeof(mode));
if (ret < 0)
goto out;
read(task->sd, &ret, sizeof(int));
i = 1;
setsockopt(task->sd, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
read(task->sd, &ret, sizeof(ret));
out:
spinlock_unlock(&lwip_lock);
@ -201,23 +260,26 @@ out:
return ret;
}
typedef struct {
int sysnr;
int fd;
} __attribute__((packed)) sys_close_t;
static int sys_close(int fd)
{
int ret;
task_t* task = per_core(current_task);
int ret, sysnr = __NR_close;
sys_close_t sysargs = {__NR_close, fd};
if (task->sd < 0)
return 0;
spinlock_lock(&lwip_lock);
ret = write(task->sd, &sysnr, sizeof(int));
if (ret < 0)
ret = write(task->sd, &sysargs, sizeof(sysargs));
if (ret != sizeof(sysargs))
goto out;
ret = write(task->sd, &fd, sizeof(int));
if (ret < 0)
goto out;
read(task->sd, &ret, sizeof(int));
read(task->sd, &ret, sizeof(ret));
out:
spinlock_unlock(&lwip_lock);
@ -295,10 +357,42 @@ static int sys_clone(tid_t* id, void* ep, void* argv)
return clone_task(id, ep, argv, per_core(current_task)->prio);
}
typedef struct {
int sysnr;
int fd;
off_t offset;
int whence;
} __attribute__((packed)) sys_lseek_t;
static off_t sys_lseek(int fd, off_t offset, int whence)
{
off_t off;
task_t* task = per_core(current_task);
sys_lseek_t sysargs = {__NR_lseek, fd, offset, whence};
if (task->sd < 0)
return -ENOSYS;
spinlock_lock(&lwip_lock);
write(task->sd, &sysargs, sizeof(sysargs));
read(task->sd, &off, sizeof(off));
spinlock_unlock(&lwip_lock);
return off;
}
static int default_handler(void)
{
#if 0
kprintf("Invalid system call\n");
#else
uint64_t rax;
asm volatile ("mov %%rax, %0" : "=m"(rax) :: "memory");
kprintf("Invalid system call: %zd\n", rax);
#endif
return -ENOSYS;
}
@ -307,8 +401,8 @@ size_t syscall_table[] = {
(size_t) sys_write, /* __NR_write */
(size_t) sys_open, /* __NR_open */
(size_t) sys_close, /* __NR_close */
(size_t) default_handler, /* __NR_read */
(size_t) default_handler, /* __NR_lseek */
(size_t) sys_read, /* __NR_read */
(size_t) sys_lseek, /* __NR_lseek */
(size_t) default_handler, /* __NR_unlink */
(size_t) sys_getpid, /* __NR_getpid */
(size_t) default_handler, /* __NR_kill */

View file

@ -35,6 +35,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/tcp.h>
#define HERMIT_PORT 0x494F
#define HERMIT_MAGIC 0x7E317
@ -44,6 +45,7 @@
#define __HERMIT_open 2
#define __HERMIT_close 3
#define __HERMIT_read 4
#define __HERMIT_lseek 5
static char saddr[16] = "192.168.28.2";
static int sobufsize = 131072;
@ -69,7 +71,7 @@ int handle_syscalls(int s)
switch(sysnr)
{
case __HERMIT_exit: {
int arg;
int arg = 0;
ret = read(s, &arg, sizeof(arg));
if (ret < 0)
@ -80,7 +82,8 @@ int handle_syscalls(int s)
}
case __HERMIT_write: {
int fd;
size_t j, len;
ssize_t j;
size_t len;
char* buff;
ret = read(s, &fd, sizeof(fd));
@ -105,18 +108,52 @@ int handle_syscalls(int s)
j += len;
}
j=0;
while(j < len)
{
ret = write(fd, buff+j, len-j);
if (ret < 0)
goto out;
j += len;
}
j = write(fd, buff, len);
if (fd > 2)
write(s, &j, sizeof(j));
free(buff);
break;
}
case __HERMIT_open: {
size_t j, len;
char* fname;
int flags, mode;
ret = read(s, &len, sizeof(len));
if (ret < 0)
goto out;
fname = malloc(len);
if (!fname)
goto out;
j = 0;
while(j < len)
{
ret = read(s, fname+j, len-j);
if (ret < 0)
goto out;
j += ret;
}
ret = read(s, &flags, sizeof(flags));
if (ret < 0)
goto out;
ret = read(s, &mode, sizeof(mode));
if (ret < 0)
goto out;
//printf("flags 0x%x, mode 0x%x\n", flags, mode);
ret = open(fname, flags, mode);
write(s, &ret, sizeof(ret));
free(fname);
break;
}
case __HERMIT_close: {
int fd;
@ -134,6 +171,63 @@ int handle_syscalls(int s)
goto out;
break;
}
case __HERMIT_read: {
int fd, flag;
size_t len;
ssize_t j;
char* buff;
ret = read(s, &fd, sizeof(fd));
if (ret < 0)
goto out;
ret = read(s, &len, sizeof(len));
if (ret < 0)
goto out;
buff = malloc(len);
if (!buff)
goto out;
j = read(fd, buff, len);
flag = 0;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
write(s, &j, sizeof(j));
if (j > 0)
{
ssize_t i = 0;
while(i < j)
{
ret = write(s, buff+i, j-i);
if (ret < 0)
break;
i += ret;
}
}
flag = 1;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
free(buff);
break;
}
case __HERMIT_lseek: {
int fd, whence;
off_t offset;
read(s, &fd, sizeof(fd));
read(s, &offset, sizeof(offset));
read(s, &whence, sizeof(whence));
offset = lseek(fd, offset, whence);
write(s, &offset, sizeof(offset));
break;
}
default:
fprintf(stderr, "Proxy: invalid syscall number %d\n", sysnr);
break;
@ -141,7 +235,7 @@ int handle_syscalls(int s)
}
out:
perror("Proxy: communication error");
perror("Proxy -- communication error");
return 1;
}
@ -162,6 +256,8 @@ int main(int argc, char **argv)
setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
i = 1;
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i));
/* server address */
memset((char *) &serv_name, 0x00, sizeof(serv_name));
@ -172,7 +268,7 @@ int main(int argc, char **argv)
ret = connect(s, (struct sockaddr*)&serv_name, sizeof(serv_name));
if (ret < 0)
{
perror("Proxy: connection error");
perror("Proxy -- connection error");
close(s);
exit(1);
}
@ -226,7 +322,7 @@ int main(int argc, char **argv)
return ret;
out:
perror("Proxy: communication error");
perror("Proxy -- communication error");
close(s);
return 1;
}