mirror of
https://github.com/hermitcore/libhermit.git
synced 2025-03-09 00:00:03 +01:00
add support of proxy processes
This commit is contained in:
parent
dc4e376f94
commit
e7cddc3e7e
8 changed files with 375 additions and 51 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Stefan Lankes, RWTH Aachen University
|
||||
* Copyright (c) 2010-2015, Stefan Lankes, RWTH Aachen University
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -38,6 +38,10 @@
|
|||
#include <asm/elf.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/stats.h>
|
||||
|
||||
#define START_ADDRESS 0x40200000
|
||||
|
||||
/*
|
||||
|
@ -142,7 +146,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
|
|||
size_t state_size;
|
||||
|
||||
if (BUILTIN_EXPECT(!task, 0))
|
||||
return -EINVAL;
|
||||
return -EINVAL;
|
||||
|
||||
if (BUILTIN_EXPECT(!task->stack, 0))
|
||||
return -EINVAL;
|
||||
|
@ -162,7 +166,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
|
|||
* This procedure cleans the task after exit. */
|
||||
*stack = (size_t) leave_kernel_task;
|
||||
|
||||
/* Next bunch on the stack is the initial register state.
|
||||
/* Next bunch on the stack is the initial register state.
|
||||
* The stack must look like the stack of a task which was
|
||||
* scheduled away previously. */
|
||||
state_size = sizeof(struct state);
|
||||
|
@ -186,7 +190,7 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
|
|||
}
|
||||
stptr->cs = 0x08;
|
||||
stptr->ss = 0x10;
|
||||
stptr->gs = core_id * ((size_t) &percore_end0 - (size_t) &percore_start);
|
||||
stptr->gs = core_id * ((size_t) &percore_end0 - (size_t) &percore_start);
|
||||
stptr->rflags = 0x1202;
|
||||
stptr->userrsp = stptr->rsp;
|
||||
|
||||
|
@ -203,6 +207,10 @@ int create_default_frame(task_t* task, entry_point_t ep, void* arg, uint32_t cor
|
|||
typedef struct {
|
||||
/// Points to the node with the executable in the file system
|
||||
vfs_node_t* node;
|
||||
/// Points to a copy of the executable
|
||||
char* executable;
|
||||
/// Socket descriptor if have no file node
|
||||
int sd;
|
||||
/// Argument count
|
||||
int argc;
|
||||
/// Environment var count
|
||||
|
@ -226,27 +234,29 @@ static int load_task(load_args_t* largs)
|
|||
elf_header_t header;
|
||||
elf_program_header_t prog_header;
|
||||
//elf_section_header_t sec_header;
|
||||
///!!! kfree is missing!
|
||||
fildes_t *file = kmalloc(sizeof(fildes_t));
|
||||
file->offset = 0;
|
||||
file->flags = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
//TODO: init the hole fildes_t struct!
|
||||
fildes_t file;
|
||||
task_t* curr_task = per_core(current_task);
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!largs)
|
||||
return -EINVAL;
|
||||
|
||||
file->node = largs->node;
|
||||
if (!file->node)
|
||||
if (largs->node) {
|
||||
file.node = largs->node;
|
||||
file.offset = 0;
|
||||
file.flags = 0;
|
||||
} else if (!largs->executable || (largs->sd < 0))
|
||||
return -EINVAL;
|
||||
|
||||
ret = read_fs(file, (uint8_t*)&header, sizeof(elf_header_t));
|
||||
if (ret < 0) {
|
||||
kprintf("read_fs failed: %d\n", ret);
|
||||
goto Lerr;
|
||||
}
|
||||
curr_task->sd = largs->sd;
|
||||
|
||||
if (largs->node) {
|
||||
ret = read_fs(&file, (uint8_t*)&header, sizeof(elf_header_t));
|
||||
if (ret < 0) {
|
||||
kprintf("read_fs failed: %d\n", ret);
|
||||
goto Lerr;
|
||||
}
|
||||
} else memcpy(&header, largs->executable, sizeof(elf_header_t));
|
||||
|
||||
if (BUILTIN_EXPECT(header.ident.magic != ELF_MAGIC, 0))
|
||||
goto Linvalid;
|
||||
|
@ -268,11 +278,13 @@ static int load_task(load_args_t* largs)
|
|||
|
||||
// interpret program header table
|
||||
for (i=0; i<header.ph_entry_count; i++) {
|
||||
file->offset = header.ph_offset+i*header.ph_entry_size;
|
||||
if (read_fs(file, (uint8_t*)&prog_header, sizeof(elf_program_header_t)) == 0) {
|
||||
kprintf("Could not read programm header!\n");
|
||||
continue;
|
||||
}
|
||||
if (largs->node) {
|
||||
file.offset = header.ph_offset+i*header.ph_entry_size;
|
||||
if (read_fs(&file, (uint8_t*)&prog_header, sizeof(elf_program_header_t)) == 0) {
|
||||
kprintf("Could not read programm header!\n");
|
||||
continue;
|
||||
}
|
||||
} else memcpy(&prog_header, largs->executable + header.ph_offset+i*header.ph_entry_size, sizeof(elf_program_header_t));
|
||||
|
||||
switch(prog_header.type)
|
||||
{
|
||||
|
@ -313,9 +325,12 @@ static int load_task(load_args_t* largs)
|
|||
heap = prog_header.virt_addr + prog_header.mem_size;
|
||||
|
||||
// load program
|
||||
file->offset = prog_header.offset;
|
||||
//kprintf("read programm 0x%zx - 0x%zx\n", prog_header.virt_addr, prog_header.virt_addr + prog_header.file_size);
|
||||
read_fs(file, (uint8_t*)prog_header.virt_addr, prog_header.file_size);
|
||||
if (largs->node) {
|
||||
file.offset = prog_header.offset;
|
||||
read_fs(&file, (uint8_t*)prog_header.virt_addr, prog_header.file_size);
|
||||
} else
|
||||
memcpy((uint8_t*)prog_header.virt_addr, largs->executable + prog_header.offset, prog_header.file_size);
|
||||
|
||||
if (!(prog_header.flags & PF_W))
|
||||
page_set_flags(prog_header.virt_addr, npages, flags);
|
||||
|
@ -463,6 +478,8 @@ static int load_task(load_args_t* largs)
|
|||
offset -= sizeof(ssize_t);
|
||||
*((ssize_t*) (stack+offset)) = (ssize_t) largs->argc;
|
||||
|
||||
if (largs->executable)
|
||||
kfree(largs->executable);
|
||||
kfree(largs);
|
||||
|
||||
// clear fpu state => currently not supported
|
||||
|
@ -492,6 +509,10 @@ Linvalid:
|
|||
kprintf("program entry point 0x%lx\n", (size_t) header.entry);
|
||||
|
||||
Lerr:
|
||||
if (largs->executable)
|
||||
kfree(largs->executable);
|
||||
kfree(largs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -499,6 +520,8 @@ Lerr:
|
|||
* which want to have a start function and argument list */
|
||||
static int user_entry(void* arg)
|
||||
{
|
||||
load_args_t* largs = (load_args_t*) arg;
|
||||
|
||||
int ret;
|
||||
|
||||
finish_task_switch();
|
||||
|
@ -506,12 +529,10 @@ static int user_entry(void* arg)
|
|||
if (BUILTIN_EXPECT(!arg, 0))
|
||||
return -EINVAL;
|
||||
|
||||
ret = load_task((load_args_t*) arg);
|
||||
ret = load_task(largs);
|
||||
if (ret)
|
||||
kprintf("Load task failed: %d\n", ret);
|
||||
|
||||
kfree(arg);
|
||||
|
||||
sys_exit(ret);
|
||||
|
||||
while(1) {
|
||||
|
@ -558,6 +579,8 @@ int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint8_t
|
|||
return -ENOMEM;
|
||||
load_args->node = node;
|
||||
load_args->argc = argc;
|
||||
load_args->sd = -1;
|
||||
load_args->executable = NULL;
|
||||
load_args->envc = 0;
|
||||
dest = load_args->buffer;
|
||||
for (i=0; i<argc; i++) {
|
||||
|
@ -568,3 +591,91 @@ int create_user_task_on_core(tid_t* id, const char* fname, char** argv, uint8_t
|
|||
/* create new task */
|
||||
return create_task(id, user_entry, load_args, prio, core_id);
|
||||
}
|
||||
|
||||
int create_user_task_form_socket(tid_t* id, int sd, uint8_t prio)
|
||||
{
|
||||
int argc;
|
||||
int ret, err = -EINVAL;
|
||||
int len, total_len, i, j;
|
||||
load_args_t* load_args = NULL;
|
||||
char *dest;
|
||||
uint32_t core_id = CORE_ID;
|
||||
uint32_t counter = 0;
|
||||
|
||||
ret = read(sd, &argc, sizeof(int));
|
||||
if ((ret != sizeof(int)) || (argc <= 0))
|
||||
goto out;
|
||||
|
||||
load_args = kmalloc(sizeof(load_args_t));
|
||||
if (BUILTIN_EXPECT(!load_args, 0)) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
load_args->node = NULL;
|
||||
load_args->executable = NULL;
|
||||
load_args->sd = sd;
|
||||
load_args->argc = argc;
|
||||
load_args->envc = 0;
|
||||
dest = load_args->buffer;
|
||||
|
||||
for(i=0, total_len=0; i<argc; i++)
|
||||
{
|
||||
ret = read(sd, &len, sizeof(int));
|
||||
if ((ret != sizeof(int)) || (len <= 0))
|
||||
goto out;
|
||||
|
||||
total_len += len;
|
||||
if (total_len >= MAX_ARGS)
|
||||
goto out;
|
||||
|
||||
j=0;
|
||||
while(j < len)
|
||||
{
|
||||
ret = read(sd, dest, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
dest += ret;
|
||||
j += ret;
|
||||
}
|
||||
}
|
||||
|
||||
// terminate array with a NULL pointer
|
||||
*dest = 0;
|
||||
|
||||
ret = read(sd, &len, sizeof(int));
|
||||
if ((ret != sizeof(int)) || (len <= 0))
|
||||
goto out;
|
||||
kprintf("length of the executable: %d\n", len);
|
||||
|
||||
load_args->executable = kmalloc(len);
|
||||
if (!load_args->executable) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
j=0;
|
||||
while(j < len)
|
||||
{
|
||||
ret = read(sd, load_args->executable+j, len-j);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
j += ret;
|
||||
}
|
||||
|
||||
/* create new task */
|
||||
return create_task(id, user_entry, load_args, prio, core_id);
|
||||
|
||||
out:
|
||||
kprintf("Unable to load task: %d\n", err);
|
||||
|
||||
if (load_args && load_args->executable)
|
||||
kfree(load_args->executable);
|
||||
if (load_args)
|
||||
kfree(load_args);
|
||||
|
||||
closesocket(sd);
|
||||
counter++;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ int create_kernel_task_on_core(tid_t* id, entry_point_t ep, void* args, uint8_t
|
|||
* @param id The value behind this pointer will be set to the new task's id
|
||||
* @param fname Filename of the executable to start the task with
|
||||
* @param argv Pointer to arguments array
|
||||
* @param prio Desired priority of the new kernel task
|
||||
*
|
||||
* @return
|
||||
* - 0 on success
|
||||
|
@ -139,11 +140,24 @@ int create_kernel_task_on_core(tid_t* id, entry_point_t ep, void* args, uint8_t
|
|||
*/
|
||||
int create_user_task(tid_t* id, const char* fame, char** argv, uint8_t prio);
|
||||
|
||||
/** @brief Create a user level task on the current core.
|
||||
*
|
||||
* @param id The value behind this pointer will be set to the new task's id
|
||||
* @param sd Socket descriptor to load and to start the executable
|
||||
* @param prio Desired priority of the new kernel task
|
||||
*
|
||||
* @return
|
||||
* - 0 on success
|
||||
* - -EINVAL (-22) or -ENOMEM (-12)on failure
|
||||
*/
|
||||
int create_user_task_form_socket(tid_t* id, int sd, uint8_t prio);
|
||||
|
||||
/** @brief Create a user level task.
|
||||
*
|
||||
* @param id The value behind this pointer will be set to the new task's id
|
||||
* @param fname Filename of the executable to start the task with
|
||||
* @param sd Valid socket descriptor to a TCP/IP connection
|
||||
* @param argv Pointer to arguments array
|
||||
* @param prio Desired priority of the new kernel task
|
||||
* @param core_id Start the new task on the core with this id
|
||||
*
|
||||
* @return
|
||||
|
|
|
@ -112,6 +112,8 @@ typedef struct task {
|
|||
size_t tls_mem_size;
|
||||
/// TLS file size
|
||||
size_t tls_file_size;
|
||||
/// Socket descriptor to the proxy
|
||||
int sd;
|
||||
/// LwIP error code
|
||||
int lwip_err;
|
||||
/// FPU state
|
||||
|
|
|
@ -48,11 +48,18 @@
|
|||
#include <lwip/dhcp.h>
|
||||
#include <lwip/netifapi.h>
|
||||
#include <lwip/timers.h>
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/stats.h>
|
||||
#include <netif/etharp.h>
|
||||
#include <net/mmnif.h>
|
||||
|
||||
static struct netif mmnif_netif;
|
||||
#define HERMIT_PORT 0x494F
|
||||
#define HEMRIT_MAGIC 0x7E317
|
||||
|
||||
static struct netif mmnif_netif;
|
||||
static const int sobufsize = 131072;
|
||||
volatile int8_t shutdown = 0;
|
||||
/*
|
||||
* Note that linker symbols are not variables, they have no memory allocated for
|
||||
* maintaining a value, rather their address is their value.
|
||||
|
@ -76,6 +83,7 @@ extern atomic_int32_t possible_cpus;
|
|||
extern int32_t isle;
|
||||
extern int32_t possible_isles;
|
||||
|
||||
#if 0
|
||||
static int foo(void* arg)
|
||||
{
|
||||
int i;
|
||||
|
@ -87,6 +95,7 @@ static int foo(void* arg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hermit_init(void)
|
||||
{
|
||||
|
@ -173,6 +182,14 @@ static int init_netifs(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int network_shutdown(void)
|
||||
{
|
||||
mmnif_shutdown();
|
||||
netifapi_netif_set_down(&mmnif_netif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if MAX_CORES > 1
|
||||
int smp_main(void)
|
||||
{
|
||||
|
@ -202,13 +219,15 @@ int smp_main(void)
|
|||
// init task => creates all other tasks an initialize the LwIP
|
||||
static int initd(void* arg)
|
||||
{
|
||||
int s, c, len, err;
|
||||
int32_t magic;
|
||||
struct sockaddr_in server, client;
|
||||
|
||||
//char* argv1[] = {"/bin/hello", NULL};
|
||||
//char* argv2[] = {"/bin/jacobi", NULL};
|
||||
//char* argv3[] = {"/bin/stream", NULL};
|
||||
//char* argv4[] = {"/bin/thr_hello", NULL};
|
||||
|
||||
init_netifs();
|
||||
|
||||
//create_kernel_task(NULL, foo, "foo1", NORMAL_PRIO);
|
||||
//create_kernel_task(NULL, foo, "foo2", NORMAL_PRIO);
|
||||
//create_user_task(NULL, "/bin/hello", argv1, NORMAL_PRIO);
|
||||
|
@ -217,6 +236,66 @@ static int initd(void* arg)
|
|||
//create_user_task(NULL, "/bin/stream", argv3, NORMAL_PRIO);
|
||||
//create_user_task(NULL, "/bin/thr_hello", argv4, NORMAL_PRIO);
|
||||
|
||||
init_netifs();
|
||||
|
||||
s = socket(PF_INET , SOCK_STREAM , 0);
|
||||
if (s < 0) {
|
||||
kprintf("socket failed: %d\n", server);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// prepare the sockaddr_in structure
|
||||
memset((char *) &server, 0x00, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
server.sin_port = htons(HERMIT_PORT);
|
||||
|
||||
if ((err = bind(s, (struct sockaddr *) &server, sizeof(server))) < 0)
|
||||
{
|
||||
kprintf("bind failed: %d\n", errno);
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((err = listen(s, 2)) < 0)
|
||||
{
|
||||
kprintf("listen failed: %d\n", errno);
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = sizeof(struct sockaddr_in);
|
||||
while(!shutdown)
|
||||
{
|
||||
kputs("TCP server listening.\n");
|
||||
|
||||
if ((c = accept(s, (struct sockaddr *)&client, (socklen_t*)&len)) < 0)
|
||||
{
|
||||
kprintf("accept faild: %d\n", errno);
|
||||
closesocket(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
kputs("Establish IP connection\n");
|
||||
|
||||
setsockopt(c, SOL_SOCKET, SO_RCVBUF, (char *) &sobufsize, sizeof(sobufsize));
|
||||
setsockopt(c, SOL_SOCKET, SO_SNDBUF, (char *) &sobufsize, sizeof(sobufsize));
|
||||
|
||||
read(c, &magic, sizeof(int32_t));
|
||||
if (magic != HEMRIT_MAGIC)
|
||||
{
|
||||
kprintf("Invalid magic number %d\n", magic);
|
||||
closesocket(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
create_user_task_form_socket(NULL, c, NORMAL_PRIO);
|
||||
}
|
||||
|
||||
closesocket(s);
|
||||
|
||||
network_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
#include <hermit/semaphore.h>
|
||||
#include <hermit/time.h>
|
||||
|
||||
#include <lwip/sockets.h>
|
||||
#include <lwip/err.h>
|
||||
#include <lwip/stats.h>
|
||||
|
||||
static spinlock_t lwip_lock = SPINLOCK_INIT;
|
||||
|
||||
static tid_t sys_getpid(void)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
|
@ -53,19 +59,74 @@ static void sys_yield(void)
|
|||
reschedule();
|
||||
}
|
||||
|
||||
void NORETURN do_exit(int arg);
|
||||
|
||||
/** @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;
|
||||
|
||||
if (task->sd >= 0)
|
||||
{
|
||||
spinlock_lock(&lwip_lock);
|
||||
write(task->sd, &sysnr, sizeof(int));
|
||||
write(task->sd, &arg, sizeof(int));
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
closesocket(task->sd);
|
||||
task->sd = -1;
|
||||
}
|
||||
|
||||
do_exit(arg);
|
||||
}
|
||||
|
||||
static int sys_write(int fd, const char* buf, size_t len)
|
||||
{
|
||||
task_t* task = per_core(current_task);
|
||||
int ret, sysnr = __NR_write;
|
||||
size_t i;
|
||||
|
||||
//TODO: Currently, we ignore the file descriptor
|
||||
|
||||
if (BUILTIN_EXPECT(!buf, 0))
|
||||
return -1;
|
||||
|
||||
for(i=0; i<len; i++)
|
||||
kputchar(buf[i]);
|
||||
if (task->sd < 0)
|
||||
{
|
||||
for(i=0; i<len; i++)
|
||||
kputchar(buf[i]);
|
||||
|
||||
return len;
|
||||
return len;
|
||||
}
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
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;
|
||||
|
||||
i=0;
|
||||
while(i<len)
|
||||
{
|
||||
ret = write(task->sd, (char*)buf+i, len-i);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
i += ret;
|
||||
}
|
||||
|
||||
ret = len;
|
||||
|
||||
out:
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t sys_sbrk(int incr)
|
||||
|
@ -96,12 +157,72 @@ static ssize_t sys_sbrk(int incr)
|
|||
|
||||
static int sys_open(const char* name, int flags, int mode)
|
||||
{
|
||||
return 0;
|
||||
task_t* task = per_core(current_task);
|
||||
int i, ret, sysnr = __NR_open;
|
||||
size_t len = strlen(name+1);
|
||||
|
||||
if (task->sd < 0)
|
||||
return 0;
|
||||
|
||||
len = strlen(name+1);
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = write(task->sd, &len, sizeof(size_t));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
i=0;
|
||||
while(i<len)
|
||||
{
|
||||
ret = write(task->sd, name+i, len-i);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
i += ret;
|
||||
}
|
||||
|
||||
ret = write(task->sd, &flags, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = write(task->sd, &mode, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
read(task->sd, &ret, sizeof(int));
|
||||
|
||||
out:
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sys_close(int fd)
|
||||
{
|
||||
return 0;
|
||||
task_t* task = per_core(current_task);
|
||||
int ret, sysnr = __NR_close;
|
||||
|
||||
if (task->sd < 0)
|
||||
return 0;
|
||||
|
||||
spinlock_lock(&lwip_lock);
|
||||
|
||||
ret = write(task->sd, &sysnr, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
ret = write(task->sd, &fd, sizeof(int));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
read(task->sd, &ret, sizeof(int));
|
||||
|
||||
out:
|
||||
spinlock_unlock(&lwip_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sys_msleep(unsigned int msec)
|
||||
|
@ -171,7 +292,7 @@ static int sys_sem_timedwait(sem_t *sem, unsigned int ms)
|
|||
|
||||
static int sys_clone(tid_t* id, void* ep, void* argv)
|
||||
{
|
||||
return clone_task(id, ep, argv, per_core(current_task)->prio);
|
||||
return clone_task(id, ep, argv, per_core(current_task)->prio);
|
||||
}
|
||||
|
||||
static int default_handler(void)
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
* A task's id will be its position in this array.
|
||||
*/
|
||||
static task_t task_table[MAX_TASKS] = { \
|
||||
[0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0}, \
|
||||
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, 0}};
|
||||
[0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, -1, 0}, \
|
||||
[1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, NULL, 0, NULL, NULL, 0, 0, 0, -1, 0}};
|
||||
|
||||
static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT;
|
||||
|
||||
|
@ -215,7 +215,7 @@ void finish_task_switch(void)
|
|||
|
||||
/** @brief A procedure to be called by
|
||||
* procedures which are called by exiting tasks. */
|
||||
static void NORETURN do_exit(int arg)
|
||||
void NORETURN do_exit(int arg)
|
||||
{
|
||||
task_t* curr_task = per_core(current_task);
|
||||
const uint32_t core_id = CORE_ID;
|
||||
|
@ -252,11 +252,6 @@ void NORETURN leave_kernel_task(void) {
|
|||
do_exit(result);
|
||||
}
|
||||
|
||||
/** @brief To be called by the systemcall to exit tasks */
|
||||
void NORETURN sys_exit(int arg) {
|
||||
do_exit(arg);
|
||||
}
|
||||
|
||||
/** @brief Aborting a task is like exiting it with result -1 */
|
||||
void NORETURN abort(void) {
|
||||
do_exit(-1);
|
||||
|
@ -319,6 +314,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
|
|||
task_table[i].tls_addr = curr_task->tls_addr;
|
||||
task_table[i].tls_mem_size = curr_task->tls_mem_size;
|
||||
task_table[i].tls_file_size = curr_task->tls_file_size;
|
||||
task_table[i].sd = task_table[i].sd;
|
||||
task_table[i].lwip_err = 0;
|
||||
task_table[i].user_usage = curr_task->user_usage;
|
||||
task_table[i].page_map = curr_task->page_map;
|
||||
|
@ -350,7 +346,7 @@ int clone_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio)
|
|||
}
|
||||
|
||||
spinlock_irqsave_unlock(&table_lock);
|
||||
out:
|
||||
out:
|
||||
if (ret)
|
||||
kfree(stack);
|
||||
|
||||
|
@ -403,6 +399,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c
|
|||
task_table[i].tls_addr = 0;
|
||||
task_table[i].tls_mem_size = 0;
|
||||
task_table[i].tls_file_size = 0;
|
||||
task_table[i].sd = -1;
|
||||
task_table[i].lwip_err = 0;
|
||||
|
||||
spinlock_irqsave_init(&task_table[i].page_lock);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 6dbcf238e2e6abe4ae90a8c64521fbf8d75c3ce3
|
||||
Subproject commit 9209bfad66bb4ca907bac43515be5b3905fd4f1f
|
|
@ -5,7 +5,7 @@ CC = gcc
|
|||
CFLAGS = -O2 -Wall
|
||||
HEXDUMP = hexdump
|
||||
LDFLGAS =
|
||||
EXECFILES = $(shell find ../usr/examples -perm -u+r+x -type f)
|
||||
EXECFILES = ../usr/examples/hello #$(shell find ../usr/examples -perm -u+r+x -type f)
|
||||
|
||||
# Prettify output
|
||||
V = 0
|
||||
|
|
Loading…
Add table
Reference in a new issue