diff --git a/runtime/include/types.h b/runtime/include/types.h index 5fb0441..27aa6d3 100644 --- a/runtime/include/types.h +++ b/runtime/include/types.h @@ -120,7 +120,7 @@ typedef enum #define SBOX_PREOPEN_MAGIC (707707707) // reads lol lol lol upside down #define SOFTINT_TIMER_START_USEC (10 * 1000) // start timers 10 ms from now. -#define SOFTINT_TIMER_PERIOD_USEC (1000 * 5) // 100ms timer.. +#define SOFTINT_TIMER_PERIOD_USEC (1000 * 5) // 5ms timer.. #ifdef DEBUG #ifdef NOSTDIO diff --git a/runtime/src/libc/syscall.c b/runtime/src/libc/syscall.c deleted file mode 100644 index 6b1f364..0000000 --- a/runtime/src/libc/syscall.c +++ /dev/null @@ -1,737 +0,0 @@ -#ifdef USE_SYSCALL - -/* code from https://github.com/gwsystems/silverfish/blob/master/runtime/libc/libc_backing.c */ -#include -#include -#include -#include - -// What should we tell the child program its UID and GID are? -#define UID 0xFF -#define GID 0xFE - -// Elf auxilary vector values (see google for what those are) -#define AT_NULL 0 -#define AT_IGNORE 1 -#define AT_EXECFD 2 -#define AT_PHDR 3 -#define AT_PHENT 4 -#define AT_PHNUM 5 -#define AT_PAGESZ 6 -#define AT_BASE 7 -#define AT_FLAGS 8 -#define AT_ENTRY 9 -#define AT_NOTELF 10 -#define AT_UID 11 -#define AT_EUID 12 -#define AT_GID 13 -#define AT_EGID 14 -#define AT_CLKTCK 17 -#define AT_SECURE 23 -#define AT_BASE_PLATFORM 24 -#define AT_RANDOM 25 - -// offset = a WASM ptr to memory the runtime can use -void -stub_init(i32 offset) -{ - // What program name will we put in the auxiliary vectors - char *program_name = sandbox_current()->mod->name; - // Copy the program name into WASM accessible memory - i32 program_name_offset = offset; - strcpy(get_memory_ptr_for_runtime(offset, sizeof(program_name)), program_name); - offset += sizeof(program_name); - - // The construction of this is: - // evn1, env2, ..., NULL, auxv_n1, auxv_1, auxv_n2, auxv_2 ..., NULL - i32 env_vec[] = { - // Env variables would live here, but we don't supply any - 0, - // We supply only the bare minimum AUX vectors - AT_PAGESZ, - WASM_PAGE_SIZE, - AT_UID, - UID, - AT_EUID, - UID, - AT_GID, - GID, - AT_EGID, - GID, - AT_SECURE, - 0, - AT_RANDOM, - (i32)rand(), // It's pretty stupid to use rand here, but w/e - 0, - }; - i32 env_vec_offset = offset; - memcpy(get_memory_ptr_for_runtime(env_vec_offset, sizeof(env_vec)), env_vec, sizeof(env_vec)); - - module_libc_init(sandbox_current()->mod, env_vec_offset, program_name_offset); -} - -// Emulated syscall implementations - -// We define our own syscall numbers, because WASM uses x86_64 values even on systems that are not x86_64 -#define SYS_READ 0 -u32 -wasm_read(i32 filedes, i32 buf_offset, i32 nbyte) -{ - char *buf = get_memory_ptr_void(buf_offset, nbyte); - i32 res = (i32)read(filedes, buf, nbyte); - - if (res == -1) return -errno; - - return res; -} - -#define SYS_WRITE 1 -i32 -wasm_write(i32 fd, i32 buf_offset, i32 buf_size) -{ - char *buf = get_memory_ptr_void(buf_offset, buf_size); - i32 res = (i32)write(fd, buf, buf_size); - - if (res == -1) return -errno; - - return res; -} - -#define WO_RDONLY 00 -#define WO_WRONLY 01 -#define WO_RDWR 02 -#define WO_CREAT 0100 -#define WO_EXCL 0200 -#define WO_NOCTTY 0400 -#define WO_TRUNC 01000 -#define WO_APPEND 02000 -#define WO_NONBLOCK 04000 -#define WO_DSYNC 010000 -#define WO_SYNC 04010000 -#define WO_RSYNC 04010000 -#define WO_DIRECTORY 0200000 -#define WO_NOFOLLOW 0400000 -#define WO_CLOEXEC 02000000 - - -#define SYS_OPEN 2 -i32 -wasm_open(i32 path_off, i32 flags, i32 mode) -{ - char *path = get_memory_string(path_off); - - i32 modified_flags = 0; - - if (flags & WO_RDONLY) { - modified_flags |= O_RDONLY; - flags ^= WO_RDONLY; - } - - if (flags & WO_WRONLY) { - modified_flags |= O_WRONLY; - flags ^= WO_WRONLY; - } - - if (flags & WO_RDWR) { - modified_flags |= O_RDWR; - flags ^= WO_RDWR; - } - - if (flags & WO_APPEND) { - modified_flags |= O_APPEND; - flags ^= WO_APPEND; - } - - if (flags & WO_CREAT) { - modified_flags |= O_CREAT; - flags ^= WO_CREAT; - } - - if (flags & WO_EXCL) { - modified_flags |= O_EXCL; - flags ^= WO_EXCL; - } - - i32 res = (i32)open(path, modified_flags, mode); - - if (res == -1) return -errno; - - return res; -} - -#define SYS_CLOSE 3 -i32 -wasm_close(i32 fd) -{ - i32 res = (i32)close(fd); - - if (res == -1) return -errno; - - return res; -} - -// What the wasm stat structure looks like -struct wasm_stat { - i64 st_dev; - u64 st_ino; - u32 st_nlink; - - u32 st_mode; - u32 st_uid; - u32 st_gid; - u32 __pad0; - u64 st_rdev; - u64 st_size; - i32 st_blksize; - i64 st_blocks; - - struct { - i32 tv_sec; - i32 tv_nsec; - } st_atim; - struct { - i32 tv_sec; - i32 tv_nsec; - } st_mtim; - struct { - i32 tv_sec; - i32 tv_nsec; - } st_ctim; - i32 __pad1[3]; -}; - -#define SYS_STAT 4 -// What the OSX stat structure looks like: -// struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is NOT defined */ -// dev_t st_dev; /* device inode resides on */ -// ino_t st_ino; /* inode's number */ -// mode_t st_mode; /* inode protection mode */ -// nlink_t st_nlink; /* number of hard links to the file */ -// uid_t st_uid; /* user-id of owner */ -// gid_t st_gid; /* group-id of owner */ -// dev_t st_rdev; /* device type, for special file inode */ -// struct timespec st_atimespec; /* time of last access */ -// struct timespec st_mtimespec; /* time of last data modification */ -// struct timespec st_ctimespec; /* time of last file status change */ -// off_t st_size; /* file size, in bytes */ -// quad_t st_blocks; /* blocks allocated for file */ -// u_long st_blksize;/* optimal file sys I/O ops blocksize */ -// u_long st_flags; /* user defined flags for file */ -// u_long st_gen; /* file generation number */ -// }; - -i32 -wasm_stat(u32 path_str_offset, i32 stat_offset) -{ - char * path = get_memory_string(path_str_offset); - struct wasm_stat *stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat)); - - struct stat stat; - i32 res = lstat(path, &stat); - if (res == -1) return -errno; - - *stat_ptr = (struct wasm_stat){ - .st_dev = stat.st_dev, - .st_ino = stat.st_ino, - .st_nlink = stat.st_nlink, - .st_mode = stat.st_mode, - .st_uid = stat.st_uid, - .st_gid = stat.st_gid, - .st_rdev = stat.st_rdev, - .st_size = stat.st_size, - .st_blksize = stat.st_blksize, - .st_blocks = stat.st_blocks, - }; -#ifdef __APPLE__ - stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec; - stat_ptr->st_atim.tv_nsec = stat.st_atimespec.tv_nsec; - - stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec; - stat_ptr->st_mtim.tv_nsec = stat.st_mtimespec.tv_nsec; - - stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec; - stat_ptr->st_ctim.tv_nsec = stat.st_ctimespec.tv_nsec; -#else - stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec; - stat_ptr->st_atim.tv_nsec = stat.st_atim.tv_nsec; - - stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec; - stat_ptr->st_mtim.tv_nsec = stat.st_mtim.tv_nsec; - - stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec; - stat_ptr->st_ctim.tv_nsec = stat.st_ctim.tv_nsec; -#endif - - return res; -} - -#define SYS_FSTAT 5 -i32 -wasm_fstat(i32 filedes, i32 stat_offset) -{ - struct wasm_stat *stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat)); - - struct stat stat; - i32 res = fstat(filedes, &stat); - if (res == -1) return -errno; - - *stat_ptr = (struct wasm_stat){ - .st_dev = stat.st_dev, - .st_ino = stat.st_ino, - .st_nlink = stat.st_nlink, - .st_mode = stat.st_mode, - .st_uid = stat.st_uid, - .st_gid = stat.st_gid, - .st_rdev = stat.st_rdev, - .st_size = stat.st_size, - .st_blksize = stat.st_blksize, - .st_blocks = stat.st_blocks, - }; -#ifdef __APPLE__ - stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec; - stat_ptr->st_atim.tv_nsec = stat.st_atimespec.tv_nsec; - - stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec; - stat_ptr->st_mtim.tv_nsec = stat.st_mtimespec.tv_nsec; - - stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec; - stat_ptr->st_ctim.tv_nsec = stat.st_ctimespec.tv_nsec; -#else - stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec; - stat_ptr->st_atim.tv_nsec = stat.st_atim.tv_nsec; - - stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec; - stat_ptr->st_mtim.tv_nsec = stat.st_mtim.tv_nsec; - - stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec; - stat_ptr->st_ctim.tv_nsec = stat.st_ctim.tv_nsec; -#endif - - return res; -} - -#define SYS_LSTAT 6 -i32 -wasm_lstat(i32 path_str_offset, i32 stat_offset) -{ - char * path = get_memory_string(path_str_offset); - struct wasm_stat *stat_ptr = get_memory_ptr_void(stat_offset, sizeof(struct wasm_stat)); - - struct stat stat; - i32 res = lstat(path, &stat); - if (res == -1) return -errno; - - *stat_ptr = (struct wasm_stat){ - .st_dev = stat.st_dev, - .st_ino = stat.st_ino, - .st_nlink = stat.st_nlink, - .st_mode = stat.st_mode, - .st_uid = stat.st_uid, - .st_gid = stat.st_gid, - .st_rdev = stat.st_rdev, - .st_size = stat.st_size, - .st_blksize = stat.st_blksize, - .st_blocks = stat.st_blocks, - }; -#ifdef __APPLE__ - stat_ptr->st_atim.tv_sec = stat.st_atimespec.tv_sec; - stat_ptr->st_atim.tv_nsec = stat.st_atimespec.tv_nsec; - - stat_ptr->st_mtim.tv_sec = stat.st_mtimespec.tv_sec; - stat_ptr->st_mtim.tv_nsec = stat.st_mtimespec.tv_nsec; - - stat_ptr->st_ctim.tv_sec = stat.st_ctimespec.tv_sec; - stat_ptr->st_ctim.tv_nsec = stat.st_ctimespec.tv_nsec; -#else - stat_ptr->st_atim.tv_sec = stat.st_atim.tv_sec; - stat_ptr->st_atim.tv_nsec = stat.st_atim.tv_nsec; - - stat_ptr->st_mtim.tv_sec = stat.st_mtim.tv_sec; - stat_ptr->st_mtim.tv_nsec = stat.st_mtim.tv_nsec; - - stat_ptr->st_ctim.tv_sec = stat.st_ctim.tv_sec; - stat_ptr->st_ctim.tv_nsec = stat.st_ctim.tv_nsec; -#endif - - return res; -} - - -#define SYS_LSEEK 8 -i32 -wasm_lseek(i32 filedes, i32 file_offset, i32 whence) -{ - i32 res = (i32)lseek(filedes, file_offset, whence); - - if (res == -1) return -errno; - - return res; -} - -#define SYS_MMAP 9 -u32 -wasm_mmap(i32 addr, i32 len, i32 prot, i32 flags, i32 fd, i32 offset) -{ - if (addr != 0) { - printf("parameter void *addr is not supported!\n"); - assert(0); - } - - if (fd != -1) { - printf("file mapping is not supported!\n"); - assert(0); - } - - assert(len % WASM_PAGE_SIZE == 0); - - i32 result = sandbox_lmbound; - for (int i = 0; i < len / WASM_PAGE_SIZE; i++) { expand_memory(); } - - return result; -} - -#define SYS_MUNMAP 11 - -#define SYS_BRK 12 - -#define SYS_RT_SIGACTION 13 - -#define SYS_RT_SIGPROGMASK 14 - -#define SYS_IOCTL 16 -i32 -wasm_ioctl(i32 fd, i32 request, i32 data_offet) -{ - // musl libc does some ioctls to stdout, so just allow these to silently go through - // FIXME: The above is idiotic - return 0; -} - -#define SYS_READV 19 -struct wasm_iovec { - i32 base_offset; - i32 len; -}; - -i32 -wasm_readv(i32 fd, i32 iov_offset, i32 iovcnt) -{ - i32 read = 0; - struct wasm_iovec *iov = get_memory_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec)); - for (int i = 0; i < iovcnt; i++) { read += wasm_read(fd, iov[i].base_offset, iov[i].len); } - - return read; -} - -#define SYS_WRITEV 20 -i32 -wasm_writev(i32 fd, i32 iov_offset, i32 iovcnt) -{ - struct wasm_iovec *iov = get_memory_ptr_void(iov_offset, iovcnt * sizeof(struct wasm_iovec)); - - // If we aren't on MUSL, pass writev to printf if possible -#if defined(__APPLE__) || defined(__GLIBC__) - if (fd == 1) { - int sum = 0; - for (int i = 0; i < iovcnt; i++) { - i32 len = iov[i].len; - void *ptr = get_memory_ptr_void(iov[i].base_offset, len); - - printf("%.*s", len, ptr); - sum += len; - } - return sum; - } -#endif - - struct iovec vecs[iovcnt]; - for (int i = 0; i < iovcnt; i++) { - i32 len = iov[i].len; - void *ptr = get_memory_ptr_void(iov[i].base_offset, len); - vecs[i] = (struct iovec){ ptr, len }; - } - - i32 res = (i32)writev(fd, vecs, iovcnt); - if (res == -1) return -errno; - - return res; -} - -#define SYS_MADVISE 28 - -#define SYS_GETPID 39 -u32 -wasm_getpid() -{ - return (u32)getpid(); -} - - -#define WF_DUPFD 0 -#define WF_GETFD 1 -#define WF_SETFD 2 -#define WF_GETFL 3 -#define WF_SETFL 4 - -#define WF_SETOWN 8 -#define WF_GETOWN 9 -#define WF_SETSIG 10 -#define WF_GETSIG 11 - -#define WF_GETLK 5 -#define WF_SETLK 6 -#define WF_SETLKW 7 - -#define SYS_FCNTL 72 -u32 -wasm_fcntl(u32 fd, u32 cmd, u32 arg_or_lock_ptr) -{ - switch (cmd) { - case WF_SETFD: - // return fcntl(fd, F_SETFD, arg_or_lock_ptr); - return 0; - case WF_SETLK: - return 0; - default: - assert(0); - } -} - -#define SYS_FSYNC 74 -u32 -wasm_fsync(u32 filedes) -{ - u32 res = fsync(filedes); - if (res == -1) return -errno; - - return 0; -} - -#define SYS_GETCWD 79 -u32 -wasm_getcwd(u32 buf_offset, u32 buf_size) -{ - char *buf = get_memory_ptr_void(buf_offset, buf_size); - char *res = getcwd(buf, buf_size); - - if (!res) return 0; - return buf_offset; -} - -#define SYS_UNLINK 87 -u32 -wasm_unlink(u32 path_str_offset) -{ - char *str = get_memory_string(path_str_offset); - u32 res = unlink(str); - if (res == -1) return -errno; - - return 0; -} - -#define SYS_GETEUID 107 -u32 -wasm_geteuid() -{ - return (u32)geteuid(); -} - -#define SYS_SET_THREAD_AREA 205 - -#define SYS_SET_TID_ADDRESS 218 - -#define SYS_GET_TIME 228 -struct wasm_time_spec { - u64 sec; - u32 nanosec; -}; - -i32 -wasm_get_time(i32 clock_id, i32 timespec_off) -{ - clockid_t real_clock; - switch (clock_id) { - case 0: - real_clock = CLOCK_REALTIME; - break; - case 1: - real_clock = CLOCK_MONOTONIC; - break; - case 2: - real_clock = CLOCK_PROCESS_CPUTIME_ID; - break; - default: - assert(0); - } - - struct wasm_time_spec *timespec = get_memory_ptr_void(timespec_off, sizeof(struct wasm_time_spec)); - - struct timespec native_timespec = { 0, 0 }; - int res = clock_gettime(real_clock, &native_timespec); - if (res == -1) return -errno; - - timespec->sec = native_timespec.tv_sec; - timespec->nanosec = native_timespec.tv_nsec; - - return res; -} - -#define SYS_EXIT_GROUP 231 -i32 -wasm_exit_group(i32 status) -{ - exit(status); - return 0; -} - -#define SYS_FCHOWN 93 -i32 -wasm_fchown(i32 fd, u32 owner, u32 group) -{ - return fchown(fd, owner, group); -} - -// networking syscalls -#define SYS_SOCKET 41 -#define SYS_CONNECT 42 -#define SYS_ACCEPT 43 -#define SYS_BIND 49 -#define SYS_LISTEN 50 -i32 -wasm_socket(i32 domain, i32 type, i32 protocol) -{ - return socket(domain, type, protocol); -} - -i32 -wasm_connect(i32 sockfd, i32 sockaddr_offset, i32 addrlen) -{ - return connect(sockfd, get_memory_ptr_void(sockaddr_offset, addrlen), addrlen); -} - -i32 -wasm_accept(i32 sockfd, i32 sockaddr_offset, i32 addrlen_offset) -{ - socklen_t *addrlen = get_memory_ptr_void(addrlen_offset, sizeof(socklen_t)); - - return accept(sockfd, get_memory_ptr_void(sockaddr_offset, *addrlen), addrlen); -} - -i32 -wasm_bind(i32 sockfd, i32 sockaddr_offset, i32 addrlen) -{ - return bind(sockfd, get_memory_ptr_void(sockaddr_offset, addrlen), addrlen); -} - -i32 -wasm_listen(i32 sockfd, i32 backlog) -{ - return listen(sockfd, backlog); -} - -#define SYS_SENDTO 44 -#define SYS_RECVFROM 45 - -i32 -wasm_sendto(i32 fd, i32 buff_offset, i32 len, i32 flags, i32 sockaddr_offset, i32 sockaddr_len) -{ - char * buf = get_memory_ptr_void(buff_offset, len); - struct sockaddr *addr = sockaddr_len ? get_memory_ptr_void(sockaddr_offset, sockaddr_len) : NULL; - - return sendto(fd, buf, len, flags, addr, sockaddr_len); -} - -i32 -wasm_recvfrom(i32 fd, i32 buff_offset, i32 size, i32 flags, i32 sockaddr_offset, i32 socklen_offset) -{ - char * buf = get_memory_ptr_void(buff_offset, size); - socklen_t * len = get_memory_ptr_void(socklen_offset, sizeof(socklen_t)); - struct sockaddr *addr = *len ? get_memory_ptr_void(sockaddr_offset, *len) : NULL; - - return recvfrom(fd, buf, size, flags, addr, addr ? len : NULL); -} - -i32 -inner_syscall_handler(i32 n, i32 a, i32 b, i32 c, i32 d, i32 e, i32 f) -{ - i32 res; - switch (n) { - case SYS_READ: - return wasm_read(a, b, c); - case SYS_WRITE: - return wasm_write(a, b, c); - case SYS_OPEN: - return wasm_open(a, b, c); - case SYS_CLOSE: - return wasm_close(a); - case SYS_STAT: - return wasm_stat(a, b); - case SYS_FSTAT: - return wasm_fstat(a, b); - case SYS_LSTAT: - return wasm_lstat(a, b); - case SYS_LSEEK: - return wasm_lseek(a, b, c); - case SYS_MMAP: - return wasm_mmap(a, b, c, d, e, f); - case SYS_MUNMAP: - return 0; - case SYS_BRK: - return 0; - case SYS_RT_SIGACTION: - return 0; - case SYS_RT_SIGPROGMASK: - return 0; - case SYS_IOCTL: - return wasm_ioctl(a, b, c); - case SYS_READV: - return wasm_readv(a, b, c); - case SYS_WRITEV: - return wasm_writev(a, b, c); - case SYS_MADVISE: - return 0; - case SYS_GETPID: - return wasm_getpid(); - case SYS_FCNTL: - return wasm_fcntl(a, b, c); - case SYS_FSYNC: - return wasm_fsync(a); - case SYS_UNLINK: - return wasm_unlink(a); - case SYS_GETCWD: - return wasm_getcwd(a, b); - case SYS_GETEUID: - return wasm_geteuid(); - case SYS_SET_THREAD_AREA: - return 0; - case SYS_SET_TID_ADDRESS: - return 0; - case SYS_GET_TIME: - return wasm_get_time(a, b); - case SYS_EXIT_GROUP: - return wasm_exit_group(a); - case SYS_FCHOWN: - return wasm_fchown(a, b, c); - - case SYS_SOCKET: - return wasm_socket(a, b, c); - case SYS_CONNECT: - return wasm_connect(a, b, c); - case SYS_ACCEPT: - return wasm_accept(a, b, c); - case SYS_BIND: - return wasm_bind(a, b, c); - case SYS_LISTEN: - return wasm_listen(a, b); - case SYS_SENDTO: - return wasm_sendto(a, b, c, d, e, f); - case SYS_RECVFROM: - return wasm_recvfrom(a, b, c, d, e, f); - } - printf("syscall %d (%d, %d, %d, %d, %d, %d)\n", n, a, b, c, d, e, f); - assert(0); - - return 0; -} - -#endif diff --git a/runtime/src/main.c b/runtime/src/main.c index 882087f..721d7ba 100644 --- a/runtime/src/main.c +++ b/runtime/src/main.c @@ -19,7 +19,10 @@ u32 first_worker_processor = 0; int worker_threads_argument[SBOX_NCORES] = { 0 }; // The worker sets its argument to -1 on error pthread_t worker_threads[SBOX_NCORES]; -static unsigned long long +/** + * @return timestamp in usec + **/ +static u64 get_time() { struct timeval Tp; @@ -29,6 +32,10 @@ get_time() return (Tp.tv_sec * 1000000 + Tp.tv_usec); } +/** + * Returns instructions on use of CLI if used incorrectly + * @param cmd - The command the user entered + **/ static void usage(char *cmd) { @@ -36,8 +43,10 @@ usage(char *cmd) debuglog("%s \n", cmd); } -// Sets the process data segment (RLIMIT_DATA) and # file descriptors -// (RLIMIT_NOFILE) soft limit to its hard limit (see man getrlimit) +/** + * Sets the process data segment (RLIMIT_DATA) and # file descriptors + * (RLIMIT_NOFILE) soft limit to its hard limit (see man getrlimit) + **/ void set_resource_limits_to_max(){ struct rlimit resource_limit; if (getrlimit(RLIMIT_DATA, &resource_limit) < 0) { @@ -60,6 +69,9 @@ void set_resource_limits_to_max(){ } } +/** + * Check the number of cores and the compiler flags and allocate available cores + **/ void allocate_available_cores(){ // Find the number of processors currently online total_online_processors = sysconf(_SC_NPROCESSORS_ONLN); @@ -80,8 +92,11 @@ void allocate_available_cores(){ first_worker_processor, MOD_REQ_CORE); } -// If NOSTIO is defined, close stdin, stdout, stderr, and write to logfile named awesome.log. Otherwise, log to STDOUT -// NOSTIO = No Standard Input/Output? +/** + * If NOSTIO is defined, close stdin, stdout, stderr, and write to logfile named awesome.log. + * Otherwise, log to STDOUT + * NOSTIO = No Standard Input/Output? + **/ void process_nostio(){ #ifdef NOSTDIO fclose(stdout); @@ -97,6 +112,9 @@ void process_nostio(){ #endif } +/** + * Starts all worker threads and sleeps forever on pthread_join, which should never return + **/ void start_worker_threads(){ for (int i = 0; i < total_worker_processors; i++) { int ret = pthread_create(&worker_threads[i], NULL, sandbox_run_func, (void *)&worker_threads_argument[i]); diff --git a/runtime/src/runtime.c b/runtime/src/runtime.c index c71a6a6..3dae203 100644 --- a/runtime/src/runtime.c +++ b/runtime/src/runtime.c @@ -68,6 +68,9 @@ sandbox_pull(void) static __thread unsigned int in_callback; +/** + * Run all outstanding events in the libuv event loop + **/ void sandbox_io_nowait(void) { @@ -82,10 +85,13 @@ sandbox_io_nowait(void) // zero, so there is nothing (don't block!) } +/** + * @param interrupt seems to be treated as boolean to indicate is_interrupt or not + * @returns A sandbox??? + **/ struct sandbox * sandbox_schedule(int interrupt) { - struct sandbox *s = NULL; if (ps_list_head_empty(&local_run_queue)) { // this is in an interrupt context, don't steal work here! if (interrupt) return NULL; @@ -95,15 +101,15 @@ sandbox_schedule(int interrupt) } } - s = ps_list_head_first_d(&local_run_queue, struct sandbox); + struct sandbox *sandbox = ps_list_head_first_d(&local_run_queue, struct sandbox); - assert(s->state != SANDBOX_RETURNED); + assert(sandbox->state != SANDBOX_RETURNED); // round-robin - ps_list_rem_d(s); - ps_list_head_append_d(&local_run_queue, s); - debuglog("[%p: %s]\n", s, s->mod->name); + ps_list_rem_d(sandbox); + ps_list_head_append_d(&local_run_queue, sandbox); + debuglog("[%p: %s]\n", sandbox, sandbox->mod->name); - return s; + return sandbox; } /** @@ -123,6 +129,11 @@ sandbox_local_free(unsigned int number_to_free) } } + +/** + * ??? + * @return sandbox + **/ struct sandbox * sandbox_schedule_io(void) { @@ -138,6 +149,11 @@ sandbox_schedule_io(void) return s; } + +/** + * ??? + * @param s sandbox + **/ void sandbox_wakeup(sandbox_t *s) { @@ -152,6 +168,10 @@ done: softint_enable(); } + +/** + * ??? + **/ void sandbox_block(void) { @@ -166,6 +186,10 @@ sandbox_block(void) sandbox_switch(s); } + +/** + * ??? + **/ void sandbox_block_http(void) { @@ -184,6 +208,10 @@ sandbox_block_http(void) #endif } + +/** + * ??? + **/ void __attribute__((noinline)) __attribute__((noreturn)) sandbox_switch_preempt(void) { pthread_kill(pthread_self(), SIGUSR1); @@ -192,19 +220,32 @@ void __attribute__((noinline)) __attribute__((noreturn)) sandbox_switch_preempt( while (true) ; } + +/** + * ??? + * @param s sandbox + **/ static inline void sandbox_local_stop(struct sandbox *s) { ps_list_rem_d(s); } +/** + * Adds sandbox to the completion queue + * @param sandbox + **/ void -sandbox_local_end(struct sandbox *s) +sandbox_local_end(struct sandbox *sandbox) { - assert(ps_list_singleton_d(s)); - ps_list_head_append_d(&local_completion_queue, s); + assert(ps_list_singleton_d(sandbox)); + ps_list_head_append_d(&local_completion_queue, sandbox); } +/** + * ??? + * @param data - argument provided by pthread API. We set to -1 on error + **/ void * sandbox_run_func(void *data) { @@ -244,7 +285,9 @@ sandbox_run(sbox_request_t *sandbox_request) sandbox_deque_push(sandbox_request); } -// perhaps respond to request +/** + * ??? + **/ void sandbox_exit(void) { diff --git a/runtime/src/sandbox.c b/runtime/src/sandbox.c index 32a0311..09a5475 100644 --- a/runtime/src/sandbox.c +++ b/runtime/src/sandbox.c @@ -150,6 +150,10 @@ sandbox_client_request_get(void) return 1; } +/** + * Sends Response Back to Client + * @return RC. -1 on Failure + **/ static inline int sandbox_client_response_set(void) { @@ -182,6 +186,9 @@ sandbox_client_response_set(void) done: assert(sndsz == curr->rr_data_len); + // Get End Timestamp + curr->total_time = rdtsc() - curr->start_time; + printf("Function returned in %lu cycles\n", curr->total_time); #ifndef USE_HTTP_UVIO int r = send(curr->csock, curr->req_resp_data, sndsz, 0); @@ -208,65 +215,6 @@ done: return 0; } -// static inline int -// sandbox_client_response_set(void) -//{ -//#ifndef STANDALONE -// struct sandbox *curr = sandbox_current(); -// -// int bodylen = curr->rr_data_len; -// if (bodylen > 0) { -// http_response_body_set(curr->req_resp_data, bodylen); -// char len[16] = { 0 }; -// sprintf(len, "%d", bodylen); -// //content-length = body length -// char *key = curr->req_resp_data + curr->rr_data_len; -// int lenlen = strlen("content-length: "), dlen = strlen(len); -// strcpy(key, "content-length: "); -// strncat(key + lenlen, len, dlen); -// strncat(key + lenlen + dlen, "\r\n", 2); -// http_response_header_set(key, lenlen + dlen + 2); -// curr->rr_data_len += lenlen + dlen + 2; -// -// //content-type as set in the headers. -// key = curr->req_resp_data + curr->rr_data_len; -// strcpy(key, "content-type: "); -// lenlen = strlen("content-type: "); -// dlen = strlen(curr->mod->rspctype); -// if (dlen == 0) { -// int l = strlen("text/plain\r\n\r\n"); -// strncat(key + lenlen, "text/plain\r\n\r\n", l); -// http_response_header_set(key, lenlen + l); -// curr->rr_data_len += lenlen + l; -// } else { -// strncat(key + lenlen, curr->mod->rspctype, dlen); -// strncat(key + lenlen + dlen, "\r\n\r\n", 4); -// http_response_header_set(key, lenlen + dlen + 4); -// curr->rr_data_len += lenlen + dlen + 4; -// } -// //TODO - other headers requested in module! -// } -// -// char *st = curr->req_resp_data + curr->rr_data_len; -// strcpy(st, "HTTP/1.1 200 OK\r\n"); -// curr->rr_data_len += strlen("HTTP/1.1 200 OK\r\n"); -// -// http_response_status_set(st, strlen("HTTP/1.1 200 OK\r\n")); -// int n = http_response_vector(); -//#ifndef USE_HTTP_UVIO -// int r = writev(curr->csock, curr->rsi.bufs, n); -// if (r < 0) perror("writev"); -//#else -// uv_write_t req = { .data = curr, }; -// int r = uv_write(&req, (uv_stream_t *)&curr->cuv, curr->rsi.bufs, n, sb_write_callback); -// sandbox_block_http(); -//#endif -// return 0; -//#else -// return 0; -//#endif -//} - void sandbox_entry(void) { diff --git a/runtime/src/softint.c b/runtime/src/softint.c index a5cce99..182700d 100644 --- a/runtime/src/softint.c +++ b/runtime/src/softint.c @@ -13,12 +13,16 @@ #include #include -__thread static volatile sig_atomic_t alarm_cnt = 0, usr1_cnt = 0; +__thread static volatile sig_atomic_t alarm_cnt = 0; +__thread static volatile sig_atomic_t usr1_cnt = 0; __thread volatile sig_atomic_t softint_off = 0; static const int softints[] = { SIGALRM, SIGUSR1 }; +/** + * Arms the periodic timers + **/ void softint_timer_arm(void) { @@ -37,6 +41,9 @@ softint_timer_arm(void) #endif } +/** + * Disarms the periodic timers + **/ void softint_timer_disarm(void) { @@ -53,6 +60,10 @@ softint_timer_disarm(void) } } +/** + * ??? + * @param u ??? + **/ static inline void softint_alarm_schedule(void *u) { @@ -87,6 +98,12 @@ skip: extern pthread_t worker_threads[]; +/** + * ??? + * @param sig Signal Type + * @param si ??? + * @param u ??? + **/ static inline void softint_handler(int sig, siginfo_t *si, void *u) { @@ -159,6 +176,9 @@ softint_handler(int sig, siginfo_t *si, void *u) #endif } +/** + * ??? + **/ void softint_init(void) { diff --git a/runtime/src/util.c b/runtime/src/util.c index db050d8..dee60a9 100644 --- a/runtime/src/util.c +++ b/runtime/src/util.c @@ -11,6 +11,12 @@ #define UTIL_MOD_LINE_MAX 1024 + +/** + * Removes leading and trailing spaces from a string + * @param str source string + * @return string without leading or training spaces + **/ static char * util_remove_spaces(char *str) { @@ -26,6 +32,7 @@ util_remove_spaces(char *str) /** * Parses a JSON file and allocates one or more new modules * @param filename The path of the JSON file + * @return RC 0 on Success. -1 on Error */ int util_parse_modules_file_json(char *filename) @@ -162,12 +169,14 @@ util_parse_modules_file_json(char *filename) return 0; } -/* +/** * TEST data file should contain: * module_name: * and if your arg has to contain a ',', woops i can't deal with that for now! * if the first character in a line is ";", then the line is ignored! - */ + * @param filename + * @return RC 0 on Success. -1 on Error + **/ int parse_sandbox_file_custom(char *filename) { @@ -227,7 +236,13 @@ parse_sandbox_file_custom(char *filename) return 0; } - +/** + * ??? + * @param mod + * @param str + * @param addr + * @return sandbox + **/ struct sandbox * util_parse_sandbox_string_json(struct module *mod, char *str, const struct sockaddr *addr) { @@ -276,6 +291,13 @@ util_parse_sandbox_string_json(struct module *mod, char *str, const struct socka return NULL; } +/** + * ??? + * @param mod + * @param str + * @param addr + * @return sandbox + **/ struct sandbox * util_parse_sandbox_string_custom(struct module *mod, char *str, const struct sockaddr *addr) { @@ -305,12 +327,13 @@ util_parse_sandbox_string_custom(struct module *mod, char *str, const struct soc return sb; } -/* +/** * Each line in the file should be like: - * * module_path:module_name:module_nargs:module_stack_size:module_max_heap_size[:moreargs::argn\n] * if the first character in a line is ";", then the line is ignored! - */ + * @param filename + * @return RC + **/ int util_parse_modules_file_custom(char *filename) {