add Biscuit user programs from origin

master
WangRunji 6 years ago
parent f36b2014d2
commit fc8393f95e

@ -0,0 +1,52 @@
cmake_minimum_required(VERSION 3.0)
project(biscuit_user)
enable_language(ASM)
# Path
aux_source_directory(c SRCS)
aux_source_directory(c/libs LIBS)
include_directories(c/include)
set(EXECUTABLE_OUTPUT_PATH ${ARCH})
# Toolchain
if (${ARCH} STREQUAL i386)
if(APPLE)
set(PREFIX i386-elf-)
endif ()
set(CMAKE_C_FLAGS "-m32")
elseif (${ARCH} STREQUAL x86_64)
if(APPLE)
set(PREFIX x86_64-elf-)
endif ()
set(CMAKE_C_FLAGS "-m64")
elseif (${ARCH} STREQUAL riscv32)
set(PREFIX riscv64-unknown-elf-)
set(CMAKE_C_FLAGS "-march=rv32imac -mabi=ilp32 -mcmodel=medany")
elseif (${ARCH} STREQUAL riscv64)
set(PREFIX riscv64-unknown-elf-)
set(CMAKE_C_FLAGS "-march=rv64imac -mabi=lp64 -mcmodel=medany")
elseif (${ARCH} STREQUAL aarch64)
set(PREFIX aarch64-none-elf-)
set(CMAKE_C_FLAGS "-mgeneral-regs-only")
set(LINK_FLAGS "-Ttext 0xffff000000000000")
else()
message("Unsupported arch: ${ARCH}")
endif ()
set(CMAKE_ASM_COMPILER ${PREFIX}gcc)
set(CMAKE_C_COMPILER ${PREFIX}gcc)
set(CMAKE_RANLIB ${PREFIX}ranlib)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -MMD -MP -O -g -ffreestanding -nostdlib -nostdinc -fno-builtin -mno-red-zone -fno-stack-protector -fPIC -std=gnu11")
set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_C_LINK_FLAGS "${LINK_FLAGS} -nostdlib") # override default value to get rid of '-Wl,-search_paths_first -Wl,-headerpad_max_install_names'
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # override default value to get rid of '-rdynamic' on Linux
# Library
add_library(ulib ${LIBS})
# Execuatble
foreach (PATH ${SRCS})
get_filename_component(NAME ${PATH} NAME_WE)
add_executable(${NAME} ${PATH})
target_link_libraries(${NAME} ulib)
endforeach ()

@ -0,0 +1,131 @@
#include <litc.h>
static int lstn(uint16_t lport)
{
fprintf(stderr, "listen on port %d\n", (int)lport);
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
err(-1, "socket");
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(lport);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
err(-1, "bind");
if (listen(s, 10) == -1)
err(-1, "listen");
int ret;
socklen_t slen = sizeof(sin);
if ((ret = accept(s, (struct sockaddr *)&sin, &slen)) == -1)
err(-1, "accept");
if (close(s))
err(-1, "close");
uint a = (sin.sin_addr.s_addr >> 0) & 0xff;
uint b = (sin.sin_addr.s_addr >> 8) & 0xff;
uint c = (sin.sin_addr.s_addr >> 16) & 0xff;
uint d = (sin.sin_addr.s_addr >> 24) & 0xff;
fprintf(stderr, "connection from %u.%u.%u.%u:%d\n", a, b, c, d,
(int)ntohs(sin.sin_port));
return ret;
}
// latency debugging code
//ulong allw[100];
//
//void dump(ulong *worst)
//{
// for (int i = 0; i < 100; i++)
// printf("%d: %lu\n", i, worst[i]);
// printf("\n");
//}
//
//void insert(ulong *worst, ulong n)
//{
// if (n < worst[0])
// return;
// if (n > worst[99]) {
// int i = 99;
// memmove(worst, worst + 1, i*sizeof(worst[0]));
// worst[i] = n;
// return;
// }
// for (int i = 0; i < 99; i++) {
// if (n > worst[i] && n <= worst[i+1]) {
// memmove(worst, worst + 1, i*sizeof(worst[0]));
// worst[i] = n;
// return;
// }
// }
//}
int main(int argc, char **argv)
{
// bring all file metadaa and binary text/data into the page cache in
// hopes that the kernel won't mix blocks from the new image with
// blocks from the old.
int status;
switch (fork()) {
case 0:
{
int fd = open("/dev/null", O_WRONLY);
if (fd == -1)
err(-1, "open");
if (dup2(fd, 1) == -1)
err(-1, "dup2");
close(fd);
char * const args[] = {"/bin/cat", "/bin/bimage", NULL};
execv(args[0], args);
err(-1, "execv");
}
case -1:
err(-1, "fork");
default:
if (wait(&status) == -1)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errx(-1, "child failed");
}
int fd;
if ((fd = open("/dev/rsd0c", O_WRONLY)) == -1)
err(-1, "open");
int s = lstn(31338);
sync();
const int blksz = 4096;
char buf[blksz];
size_t did = 0;
int mb = 1;
for (;;) {
ssize_t bs = 0;
ssize_t r = 0;
while (bs != blksz &&
(r = read(s, buf + bs, sizeof(buf) - bs)) > 0)
bs += r;
if (r == -1)
err(-1, "read");
if (bs == 0)
break;
if ((did % blksz) != 0)
fprintf(stderr, "slow write\n");
if (write(fd, buf, bs) != bs)
err(-1, "write");
did += bs;
if (did >> 20 >= mb) {
fprintf(stderr, "%dMB\n", mb);
mb += 1;
}
}
if (fsync(fd) == -1)
err(-1, "fsync");
if (close(s) == -1)
err(-1, "close");
if (close(fd) == -1)
err(-1, "close");
fprintf(stderr, "wrote %zu bytes. rebooting.\n", did);
reboot();
return 0;
}

@ -0,0 +1,136 @@
#include <litc.h>
static long
_fetch(long n)
{
long ret;
if ((ret = sys_info(n)) == -1)
errx(-1, "sysinfo");
return ret;
}
__attribute__((unused))
static long
gccount(void)
{
return _fetch(SINFO_GCCOUNT);
}
__attribute__((unused))
static long
gctotns(void)
{
return _fetch(SINFO_GCPAUSENS);
}
__attribute__((unused))
static long
gcheapuse(void)
{
return _fetch(SINFO_GCHEAPSZ);
}
__attribute__((noreturn))
void usage(const char *msg)
{
if (msg != NULL)
printf("%s\n\n", msg);
printf("usage:\n");
printf("%s [-mvSg] [-h <int>] [-s <int>] [-w <int>] [-n <int>] "
"[-l <int>]\n", __progname);
printf("where:\n");
printf("-d bloat kernel heap with vnodes\n");
printf("-g force kernel GC\n");
printf("-h <int> set kernel heap minimum to int MB\n");
printf("-H <int> set kernel heap growth factor as int\n");
printf("-l <int> set kernel heap reservation max to int MB\n");
printf("-s <int>/<int> set GC mutator assist ratio to <int>/<int>\n\n");
exit(-1);
}
int main(int argc, char **argv)
{
long kheap = 0, growperc = 0, hmax = 0;
int newthing = 0, dogc = 0;
long anum = 0, adenom = 0;
int c;
while ((c = getopt(argc, argv, "gdH:h:s:l:")) != -1) {
switch (c) {
case 'd':
newthing = 1;
break;
case 'g':
dogc = 1;
break;
case 'h':
kheap = strtol(optarg, NULL, 0);
break;
case 'H':
growperc = strtol(optarg, NULL, 0);
break;
case 's':
{
char *end;
anum = strtol(optarg, &end, 0);
if (*end != '/')
usage("invalid ratio");
end++;
adenom = strtol(end, NULL, 0);
if (anum <= 0 || adenom <= 0)
usage("invalid ratio");
break;
}
case 'l':
hmax = strtol(optarg, NULL, 0);
if (hmax == 0)
errx(-1, "must be non-zero");
break;
default:
usage(NULL);
break;
}
}
if (optind != argc)
usage(NULL);
if (newthing) {
printf("bloat kernel heap...\n");
const long hack4 = 1 << 7;
if (sys_prof(hack4, 0, 0, 0) == -1)
err(-1, "hack4");
pause();
}
if (kheap) {
const long hack = 1ul << 4;
if (sys_prof(hack, kheap, 0, 0) == -1)
err(-1, "sys prof");
}
if (growperc) {
const long hack2 = 1ul << 5;
if (sys_prof(hack2, growperc, 0, 0) == -1)
err(-1, "sys prof");
}
if (hmax) {
hmax <<= 20;
const long prof_hack5 = 1ul << 8;
if (sys_prof(prof_hack5, hmax, 0, 0) == -1)
err(-1, "sys prof");
}
if (adenom != 0) {
const long prof_hack6 = 1ul << 9;
if (sys_prof(prof_hack6, anum, adenom, 0) == -1)
err(-1, "sys prof");
}
if (dogc) {
_fetch(10);
printf("kernel heap use: %ld Mb\n", gcheapuse()/(1 << 20));
}
return 0;
}

@ -0,0 +1,231 @@
#include <litc.h>
static long
nowms(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL))
err(-1, "gettimeofday");
return tv.tv_sec*1000 + tv.tv_usec/1000;
}
static long
_fetch(long n)
{
long ret;
if ((ret = sys_info(n)) < 0)
errx(-1, "sysinfo");
return ret;
}
static long
gccount(void)
{
return _fetch(SINFO_GCCOUNT);
}
static long
gctotns(void)
{
return _fetch(SINFO_GCPAUSENS);
}
static long
gcheapuse(void)
{
return _fetch(SINFO_GCHEAPSZ);
}
struct res_t {
long xput;
long longest;
};
__attribute__((noreturn))
static void _workmmap(long endms, int resfd)
{
long longest = 0;
long count = 0;
while (1) {
long st = nowms();
if (st > endms)
break;
size_t sz = 4096 * 100;
void *m = mmap(NULL, sz, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (m == MAP_FAILED)
err(-1, "mmap");
if (munmap(m, sz))
err(-1, "munmap");
long tot = nowms() - st;
if (tot > longest)
longest = tot;
count++;
}
struct res_t rs = {.xput = count, .longest = longest};
if (write(resfd, &rs, sizeof(rs)) != sizeof(rs))
err(-1, "res write");
exit(0);
}
static void work(long wf, const long np)
{
long secs = wf;
if (secs < 0)
secs = 1;
else if (secs > 60)
secs = 60;
printf("working for %ld seconds with %ld processes...\n", secs, np);
int resp[2];
if (pipe(resp))
err(-1, "pipe");
long bgcs = gccount();
long bgcns = gctotns();
long endms = nowms() + secs*1000;
pid_t ps[np];
int i;
for (i = 0; i < np; i++) {
if ((ps[i] = fork()) < 0)
errx(-1, "fork");
else if (ps[i] == 0) {
close(resp[0]);
_workmmap(endms, resp[1]);
}
}
close(resp[1]);
struct gcfrac_t gcf = gcfracst();
//fake_sys(1);
long longest = 0, totalxput = 0;
long longarr[np];
for (i = 0; i < np; i++) {
int status;
if (wait(&status) < 0)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
err(-1, "child failed");
struct res_t got;
if (read(resp[0], &got, sizeof(got)) != sizeof(got))
err(-1, "res read");
totalxput += got.xput;
longarr[i] = got.longest;
if (got.longest > longest)
longest = got.longest;
}
//fake_sys(0);
long gcs = gccount() - bgcs;
long gcns = gctotns() - bgcns;
long xput = secs > 0 ? totalxput/secs : 0;
printf("iterations/sec: %ld (%ld total)\n", xput, totalxput);
printf("CPU time GC'ing: %f%%\n", gcfracend(&gcf, NULL, NULL, NULL));
printf("max latency: %ld ms\n", longest);
printf("each process' latency:\n");
for (i = 0; i < np; i++)
printf(" %ld\n", longarr[i]);
printf("%ld gcs (%ld ms)\n", gcs, gcns/1000000);
printf("kernel heap use: %ld Mb\n", gcheapuse()/(1 << 20));
}
int _vnodes(long sf)
{
size_t nf = 1000*sf;
printf("creating %zu vnodes...\n", nf);
size_t tenpct = nf/10;
size_t next = 1;
size_t n;
for (n = 0; n < nf; n++) {
int fd = open("dummy", O_CREAT | O_EXCL | O_RDWR, S_IRWXU);
if (fd < 0)
err(-1, "open");
if (unlink("dummy"))
err(-1, "unlink");
size_t cp = n/tenpct;
if (cp >= next) {
printf("%zu%%\n", cp*10);
next = cp + 1;
}
}
return 0;
}
__attribute__((noreturn))
void usage(void)
{
printf("usage:\n");
printf("%s [-g] [-s <int>] [-w <int>] [-n <int>]\n", __progname);
printf("where:\n");
printf("-g force kernel GC, then exit\n");
printf("-s <int> set scale factor to int\n");
printf("-w <int> set work factor to int\n");
printf("-n <int> set number of worker processes to int\n\n");
exit(-1);
}
int main(int argc, char **argv)
{
long sf = 1, wf = 1, nprocs = 1;
int dogc = 0;
int c;
while ((c = getopt(argc, argv, "n:gms:w:")) != -1) {
switch (c) {
case 'g':
dogc = 1;
break;
case 'n':
nprocs = strtol(optarg, NULL, 0);
break;
case 's':
sf = strtol(optarg, NULL, 0);
break;
case 'w':
wf = strtol(optarg, NULL, 0);
break;
default:
usage();
break;
}
}
if (optind != argc)
usage();
if (dogc) {
_fetch(10);
printf("kernel heap use: %ld Mb\n", gcheapuse()/(1 << 20));
return 0;
}
if (sf < 0)
sf = 1;
if (wf < 0)
wf = 1;
if (nprocs < 0)
nprocs = 1;
printf("scale factor: %ld, work factor: %ld, worker procs: %ld\n",
sf, wf, nprocs);
long st = nowms();
int (*f)(long) = _vnodes;
if (f(sf))
return -1;
long tot = nowms() - st;
printf("setup: %ld ms\n", tot);
work(wf, nprocs);
return 0;
}

@ -0,0 +1,41 @@
#include <litc.h>
int main(int argc, char **argv)
{
char dname[] = "/d";
int depth = 10;
if (argc >= 2)
depth = atoi(argv[1]);
//printf("using depth: %d\n", depth);
int domkdir = 1;
if (argc >= 3)
domkdir = atoi(argv[2]);
//if (domkdir)
// printf("making dirs...\n");
//else
// printf("skip dir make\n");
char boof[1024];
char *p = boof;
char *end = boof + sizeof(boof);
int i;
for (i = 0; i < depth; i++) {
p += snprintf(p, end - p, "%s", dname);
if (domkdir)
mkdir(boof, 0);
}
char *fn = "/politicians";
snprintf(p, end - p, "%s", fn);
//printf("using \"%s\"...\n", boof);
open(boof, O_RDWR | O_CREAT, 0);
for (i = 0; i < 100; i++) {
int ret;
if ((ret = open(boof, O_RDONLY, 0)) < 0)
err(ret, "open");
}
//printf("done\n");
return 0;
}

@ -0,0 +1,33 @@
#include <litc.h>
static char buf[512];
int main(int argc, char **argv)
{
char *fn = "/bigfile.txt";
int fd;
if ((fd = open(fn, O_RDONLY, 0)) < 0)
errx(-1, "open");
int i;
int ret;
int blks = 1000;
for (i = 0; i < blks; i++) {
printf("read %d\n", i);
size_t c = sizeof(buf);
size_t e = c;
if ((ret = read(fd, buf, c)) != e) {
printf("read failed %d\n", ret);
return -1;
}
int j;
for (j = 0; j < sizeof(buf); j++)
if (buf[j] != 'A')
errx(-1, "mismatch!");
}
if (close(fd))
errx(-1, "close");
return 0;
}

@ -0,0 +1,223 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
static char buf[40960];
static char name[100];
static char *prog_name;
static char *topdir;
#define NDIR 100
static char dir[100];
time_t ds;
time_t du;
struct timeval before, end;
void rgettimeofday(struct timeval *h, void *p)
{
time_t hi, lo, v;
asm(
"rdtsc\n"
: "=a"(lo), "=d"(hi)
:
:);
v = hi << 32 | lo;
if (h)
h->tv_usec = v;
}
void start()
{
rgettimeofday(&before, NULL);
}
long stop()
{
rgettimeofday(&end, NULL);
long time = (end.tv_sec - before.tv_sec) * 1000000 +
(end.tv_usec - before.tv_usec);
return time;
}
void creat_dir()
{
int i;
//umask(0);
for (i = 0; i < NDIR; i++) {
snprintf(dir, sizeof(dir), "%s/d%d", topdir, i);
if (mkdir(dir, 0777) != 0) {
printf("%s: mkdir %s failed %d\n", prog_name, dir, errno);
}
}
}
void
creat_test(int n, int size)
{
int i;
int r;
int fd;
int j;
start();
for (i = 0, j = 0; i < n; i ++) {
snprintf(name, sizeof(name), "%s/d%d/g%d", topdir, j, i);
if((fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
printf("%s: create %s failed %d\n", prog_name, name, errno);
exit(1);
}
if ((r = write(fd, buf, size)) < 0) {
printf("%s: write failed %d %d\n", prog_name, r, errno);
exit(1);
}
if ((r = close(fd)) < 0) {
printf("%s: close failed %d %d\n", prog_name, r, errno);
}
if ((i+1) % 100 == 0) j++;
}
long time = stop();
printf("%s: creat took %ld usec\n", prog_name, time);
}
void
write_test(char *name, int n, int size)
{
int i;
int r;
int fd;
if((fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
printf("%s: create %d failed %d\n", prog_name, fd, errno);
exit(1);
}
for (i = 0; i < n; i ++) {
if ((r = write(fd, buf, size)) < 0) {
printf("%s: write failed %d %d\n", prog_name, r, errno);
exit(1);
}
}
if ((r = close(fd)) < 0) {
printf("%s: close failed %d %d\n", prog_name, r, errno);
}
}
void
flush_cache()
{
write_test("t", 20000, 4096);
}
void
read_test(int n, int size)
{
int i;
int r;
int fd;
int j;
start();
for (i = 0, j = 0; i < n; i ++) {
snprintf(name, sizeof(name), "%s/d%d/g%d", topdir, j, i);
if((fd = open(name, O_RDONLY, 0)) < 0) {
printf("%s: open %d failed %d %d\n", prog_name, i, fd, errno);
exit(1);
}
if ((r = read(fd, buf, size)) < 0) {
printf("%s: read failed %d %d\n", prog_name, r, errno);
exit(1);
}
if ((r = close(fd)) < 0) {
printf("%s: close failed %d %d\n", prog_name, r, errno);
}
if ((i+1) % 100 == 0) j++;
}
long time = stop();
printf("%s: read took %ld usec\n", prog_name, time);
}
void
delete_test(int n)
{
int i;
int r;
int j;
start();
for (i = 0, j = 0; i < n; i ++) {
snprintf(name, sizeof(name), "%s/d%d/g%d", topdir, j, i);
if ((r = unlink(name)) < 0) {
printf("%s: unlink failed %d\n", prog_name, r);
exit(1);
}
if ((i+1) % 100 == 0) j++;
}
long time = stop();
printf("%s: unlink took %ld usec\n", prog_name, time);
}
int main(int argc, char *argv[])
{
int n;
int size;
prog_name = argv[0];
if (argc != 4) {
printf("%s: %s num size dir\n", prog_name, prog_name);
exit(1);
}
n = atoi(argv[1]);
size = atoi(argv[2]);
topdir = argv[3];
printf("%s %d %d %s\n", prog_name, n, size, topdir);
creat_dir();
//printstats(topdir, 1);
creat_test(n, size);
//printstats(topdir, 0);
read_test(n, size);
delete_test(n);
unlink("t");
return 0;
}

@ -0,0 +1,41 @@
#include <litc.h>
static char buf[512];
int main(int argc, char **argv)
{
char *fn = "/bigdaddy.txt";
int fd;
if ((fd = open(fn, O_RDWR, 0)) >= 0) {
printf("deleting %s\n", fn);
close(fd);
if (unlink(fn) < 0)
errx(-1, "unlink");
}
if ((fd = open(fn, O_RDWR | O_CREAT, 0)) < 0)
errx(-1, "open");
int i;
for (i = 0; i < sizeof(buf); i++)
buf[i] = 0x41 + (i / 1000);
int ret;
//int blks = 1000;
int blks = 140;
for (i = 0; i < blks; i++) {
//printf("write %d\n", i);
size_t c = sizeof(buf);
size_t e = c;
if ((ret = write(fd, buf, c)) != e) {
printf("write failed %d\n", ret);
return -1;
}
}
if (close(fd))
errx(-1, "close");
printf("done\n");
return 0;
}

@ -0,0 +1,23 @@
#include <litc.h>
int main(int argc, char **argv)
{
if (argc <= 1)
errx(-1, "usage: %s file1 [file2]...", argv[0]);
int i;
for (i = 1; i < argc; i++) {
int fd;
fd = open(argv[i], O_RDONLY, 0);
if (fd < 0)
err(-1, "open");
char buf[512];
long ret;
while ((ret = read(fd, buf, sizeof(buf))) > 0)
write(1, buf, ret);
if (ret < 0)
err(-1, "read");
close(fd);
}
return 0;
}

@ -0,0 +1,41 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#define BSIZE 4096
char buf[BSIZE];
struct stat statbuf;
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("Usage: %s filename\n", argv[0]);
exit(-1);
}
if(stat(argv[1], &statbuf) < 0) {
err(-1, "stat");
}
int fd = open(argv[1], O_RDONLY, 0);
if (fd < 0)
err(-1, "fopen");
ulong cksum = 0;
size_t tot = 0, r;
while ((r = read(fd, buf, sizeof(buf))) > 0) {
for (int i = 0; i < r; i++) {
cksum += buf[i];
}
tot += r;
}
if (tot != statbuf.st_size) {
printf("didn't read enough data\n");
exit(-1);
}
printf("cksum: %s = cksum %lx tot %ld\n", argv[1], cksum, tot);
return 0;
}

@ -0,0 +1,14 @@
#include <litc.h>
int main(int argc, char **argv)
{
char buf[81];
int i;
for (i = 0; i < 79; i++)
buf[i] = ' ';
buf[sizeof(buf) - 2] = '\n';
buf[sizeof(buf) - 1] = 0;
for (i = 0; i < 24; i++)
printf("%s", buf);
return 0;
}

@ -0,0 +1,13 @@
#include <litc.h>
int main(int argc, char **argv)
{
while (1) {
char *ret = readline("input:");
if (!ret)
break;
printf("got: %s\n", ret);
}
return 0;
}

@ -0,0 +1,564 @@
/*
* Ebizzy - replicate a large ebusiness type of workload.
*
* Written by Valerie Henson <val@nmt.edu>
*
* Copyright 2006 - 2007 Intel Corporation
* Copyright 2007 Valerie Henson <val@nmt.edu>
*
* Rodrigo Rubira Branco <rrbranco@br.ibm.com> - HP/BSD/Solaris port and some
* new features
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*/
/*
* This program is designed to replicate a common web search app
* workload. A lot of search applications have the basic pattern: Get
* a request to find a certain record, index into the chunk of memory
* that contains it, copy it into another chunk, then look it up via
* binary search. The interesting parts of this workload are:
*
* Large working set
* Data alloc/copy/free cycle
* Unpredictable data access patterns
*
* Fiddle with the command line options until you get something
* resembling the kind of workload you want to investigate.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <malloc.h>
/*
* Command line options
*/
static unsigned int always_mmap;
static unsigned int never_mmap;
static uint64_t chunks;
static unsigned int use_permissions;
static unsigned int use_holes;
static unsigned int random_size;
static uint64_t chunk_size;
static uint64_t seconds;
static unsigned int threads;
static unsigned int verbose;
static unsigned int linear;
static unsigned int touch_pages;
static unsigned int no_lib_memcpy;
/*
* Other global variables
*/
typedef size_t record_t;
static unsigned int record_size = sizeof (record_t);
static char *cmd;
static record_t **mem;
static char **hole_mem;
static unsigned int page_size;
static volatile int threads_go;
static uint64_t records_read;
/* Global lock to serialize records aggregation */
pthread_mutex_t records_count_lock;
static void
usage(void)
{
fprintf(stderr, "Usage: %s [options]\n"
"-T\t\t Just 'touch' the allocated pages\n"
"-l\t\t Don't use library memcpy\n"
"-m\t\t Always use mmap instead of malloc\n"
"-M\t\t Never use mmap\n"
"-n <num>\t Number of memory chunks to allocate\n"
"-p \t\t Prevent mmap coalescing using permissions\n"
"-P \t\t Prevent mmap coalescing using holes\n"
"-R\t\t Randomize size of memory to copy and search\n"
"-s <size>\t Size of memory chunks, in bytes\n"
"-S <seconds>\t Number of seconds to run\n"
"-t <num>\t Number of threads (2 * number cpus by default)\n"
"-v[v[v]]\t Be verbose (more v's for more verbose)\n"
"-z\t\t Linear search instead of binary search\n",
cmd);
exit(1);
}
/*
* Read options, check them, and set some defaults.
*/
static void
read_options(int argc, char *argv[])
{
int c;
/* page_size = getpagesize(); */
page_size = 4096; // Hard-code it for now.
/*
* Set some defaults. These are currently tuned to run in a
* reasonable amount of time on my laptop.
*
* We could set the static defaults in the declarations, but
* then the defaults would be split between here and the top
* of the file, which is annoying.
*/
/* threads = 2 * sysconf(_SC_NPROCESSORS_ONLN); */
threads = 1;
chunks = 10;
chunk_size = record_size * 64 * 1024;
seconds = 10;
linear = 1; // Force linear search for now.
/* On to option processing */
cmd = argv[0];
while ((c = getopt(argc, argv, "lmMn:pPRs:S:t:vzT")) != -1) {
switch (c) {
case 'l':
no_lib_memcpy = 1;
break;
case 'm':
always_mmap = 1;
break;
case 'M':
never_mmap = 1;
break;
case 'n':
chunks = strtoul(optarg, NULL, 0);
if (chunks == 0)
usage();
break;
case 'p':
use_permissions = 1;
break;
case 'P':
use_holes = 1;
break;
case 'R':
random_size = 1;
break;
case 's':
chunk_size = strtoul(optarg, NULL, 0);
if (chunk_size == 0)
usage();
break;
case 'S':
seconds = strtoul(optarg, NULL, 0);
if (seconds == 0)
usage();
break;
case 't':
threads = atoi(optarg);
if (threads == 0)
usage();
break;
case 'T':
touch_pages = 1;
break;
case 'v':
verbose++;
break;
case 'z':
linear = 1;
break;
default:
usage();
}
}
if (verbose)
printf("ebizzy 0.2\n"
"(C) 2006-7 Intel Corporation\n"
"(C) 2007 Valerie Henson <val@nmt.edu>\n");
if (verbose) {
printf("always_mmap %u\n", always_mmap);
printf("never_mmap %u\n", never_mmap);
printf("chunks %lu\n", chunks);
printf("prevent coalescing using permissions %u\n",
use_permissions);
printf("prevent coalescing using holes %u\n", use_holes);
printf("random_size %u\n", random_size);
printf("chunk_size %lu\n", chunk_size);
printf("seconds %lu\n", seconds);
printf("threads %u\n", threads);
printf("verbose %u\n", verbose);
printf("linear %u\n", linear);
printf("touch_pages %u\n", touch_pages);
printf("page size %d\n", page_size);
}
/* Check for incompatible options */
if (always_mmap && never_mmap) {
fprintf(stderr, "Both -m \"always mmap\" and -M "
"\"never mmap\" option specified\n");
usage();
}
#if 0
if (never_mmap)
mallopt(M_MMAP_MAX, 0);
#endif
if (chunk_size < record_size) {
fprintf(stderr, "Chunk size %lu smaller than record size %u\n",
chunk_size, record_size);
usage();
}
}
static void
touch_mem(char *dest, size_t size)
{
int i;
if (touch_pages) {
for (i = 0; i < size; i += page_size)
*(dest + i) = 0xff;
}
}
static void *
alloc_mem(size_t size)
{
char *p;
int err = 0;
if (always_mmap) {
p = mmap((void *) 0, size, (PROT_READ | PROT_WRITE),
(MAP_PRIVATE | MAP_ANONYMOUS), -1, 0);
if (p == MAP_FAILED)
err = 1;
} else {
p = malloc(size);
if (p == NULL)
err = 1;
}
if (err) {
fprintf(stderr, "Couldn't allocate %zu bytes, try smaller "
"chunks or size options\n"
"Using -n %lu chunks and -s %lu size\n",
size, chunks, chunk_size);
exit(1);
}
return (p);
}
static void
free_mem(void *p, size_t size)
{
if (always_mmap)
munmap(p, size);
else
free(p);
}
/*
* Factor out differences in memcpy implementation by optionally using
* our own simple memcpy implementation.
*/
static void
my_memcpy(void *dest, void *src, size_t len)
{
char *d = (char *) dest;
char *s = (char *) src;
int i;
for (i = 0; i < len; i++)
d[i] = s[i];
return;
}
static void
allocate(void)
{
int i;
mem = alloc_mem(chunks * sizeof (record_t *));
if (use_holes)
hole_mem = alloc_mem(chunks * sizeof (record_t *));
for (i = 0; i < chunks; i++) {
mem[i] = (record_t *) alloc_mem(chunk_size);
/* Prevent coalescing using holes */
if (use_holes)
hole_mem[i] = alloc_mem(page_size);
}
/* Free hole memory */
if (use_holes)
for (i = 0; i < chunks; i++)
free_mem(hole_mem[i], page_size);
if (verbose)
printf("Allocated memory\n");
}
static void
write_pattern(void)
{
int i, j;
for (i = 0; i < chunks; i++) {
for(j = 0; j < chunk_size / record_size; j++)
mem[i][j] = (record_t) j;
#if 0 /* Biscuit doesn't support mprotect yet. */
/* Prevent coalescing by alternating permissions */
if (use_permissions && (i % 2) == 0)
mprotect((void *) mem[i], chunk_size, PROT_READ);
#endif
}
if (verbose)
printf("Wrote memory\n");
}
static void *
linear_search(record_t key, record_t *base, size_t size)
{
record_t *p;
record_t *end = base + (size / record_size);
for(p = base; p < end; p++)
if (*p == key)
return p;
return NULL;
}
#if 0
static int
compare(const void *p1, const void *p2)
{
return (* (record_t *) p1 - * (record_t *) p2);
}
#endif
/*
* Stupid ranged random number function. We don't care about quality.
*
* Inline because it's starting to be a scaling issue.
*/
static inline unsigned int
rand_num(unsigned int max, unsigned int *state)
{
*state = *state * 1103515245 + 12345;
return ((*state/65536) % max);
}
/*
* This function is the meat of the program; the rest is just support.
*
* In this function, we randomly select a memory chunk, copy it into a
* newly allocated buffer, randomly select a search key, look it up,
* then free the memory. An option tells us to allocate and copy a
* randomly sized chunk of the memory instead of the whole thing.
*
* Linear search provided for sanity checking.
*
*/
static unsigned int
search_mem(void)
{
record_t key, *found;
record_t *src, *copy;
unsigned int chunk;
size_t copy_size = chunk_size;
uint64_t i;
unsigned int state = 0x0c0ffee0;
for (i = 0; threads_go == 1; i++) {
chunk = rand_num(chunks, &state);
src = mem[chunk];
/*
* If we're doing random sizes, we need a non-zero
* multiple of record size.
*/
if (random_size)
copy_size = (rand_num(chunk_size / record_size, &state)
+ 1) * record_size;
copy = alloc_mem(copy_size);
if ( touch_pages ) {
touch_mem((char *) copy, copy_size);
} else {
if (no_lib_memcpy)
my_memcpy(copy, src, copy_size);
else
memcpy(copy, src, copy_size);
key = rand_num(copy_size / record_size, &state);
if (verbose > 2)
printf("[%lx] Search key %zu, copy size %zu\n",
pthread_self(), key, copy_size);
#if 1 // Force linear search for now.
found = linear_search(key, copy, copy_size);
#else
if (linear)
found = linear_search(key, copy, copy_size);
else
found = bsearch(&key, copy, copy_size / record_size,
record_size, compare);
#endif
/* Below check is mainly for memory corruption or other bugs */
if (found == NULL) {
fprintf(stderr, "Couldn't find key %zd\n", key);
exit(1);
}
} /* end if ! touch_pages */
free_mem(copy, copy_size);
}
return (i);
}
static void *
thread_run(void *arg)
{
uint64_t records_local;
if (verbose > 1)
printf("[%lx] Thread started\n", pthread_self());
/* Wait for the start signal */
while (threads_go == 0);
records_local = search_mem();
pthread_mutex_lock(&records_count_lock);
records_read += records_local;
pthread_mutex_unlock(&records_count_lock);
if (verbose > 1)
printf("[%lx] Thread finished, processed %lu records\n",
pthread_self(), records_local);
return NULL;
}
static struct timeval
difftimeval(struct timeval *end, struct timeval *start)
{
struct timeval diff;
diff.tv_sec = end->tv_sec - start->tv_sec;
diff.tv_usec = end->tv_usec - start->tv_usec;
return diff;
}
static void
start_threads(void)
{
pthread_t thread_array[threads];
double elapsed;
unsigned int i;
struct rusage start_ru, end_ru;
struct timeval start_time, end_time, usr_time, sys_time, elapsed_time;
int err;
if (verbose)
printf("Threads starting\n");
pthread_mutex_init(&records_count_lock, NULL);
for (i = 0; i < threads; i++) {
err = pthread_create(&thread_array[i], NULL, thread_run, NULL);
if (err) {
fprintf(stderr, "Error creating thread %d\n", i);
exit(1);
}
}
/*
* Begin accounting - this is when we actually do the things
* we want to measure. */
getrusage(RUSAGE_SELF, &start_ru);
gettimeofday(&start_time, NULL);
threads_go = 1;
sleep(seconds);
threads_go = 0;
gettimeofday(&end_time, NULL);
getrusage(RUSAGE_SELF, &end_ru);
/*
* The rest is just clean up.
*/
for (i = 0; i < threads; i++) {
err = pthread_join(thread_array[i], NULL);
if (err) {
fprintf(stderr, "Error joining thread %d\n", i);
exit(1);
}
}
elapsed_time = difftimeval(&end_time, &start_time);
usr_time = difftimeval(&end_ru.ru_utime, &start_ru.ru_utime);
sys_time = difftimeval(&end_ru.ru_stime, &start_ru.ru_stime);
elapsed = elapsed_time.tv_sec + elapsed_time.tv_usec/1e6;
if (verbose)
printf("Threads finished\n");
printf("%lu records/s\n",
(uint64_t) (((double) records_read)/elapsed));
printf("real %f s\n", elapsed);
printf("user %f s\n", usr_time.tv_sec + usr_time.tv_usec/1e6);
printf("sys %f s\n", sys_time.tv_sec + sys_time.tv_usec/1e6);
}
int
main(int argc, char *argv[])
{
read_options(argc, argv);
allocate();
write_pattern();
start_threads();
return 0;
}

@ -0,0 +1,9 @@
#include <litc.h>
int main(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++)
printf("%s%c", argv[i], (i == argc - 1) ? '\n' : ' ');
return 0;
}

@ -0,0 +1,67 @@
#define small "nop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\nnop\n"
#define big small small small small small small small small small
#define uge big big big big big big big big big big big big big
void bloater()
{
// ~50k each
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
asm volatile(
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge uge
);
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,19 @@
#include <litc.h>
int main(int argc, char **argv)
{
int i;
for (i = 0; i < 3; i++) {
printf("hello world!\n");
int j;
for (j = 0; j < 100000000; j++)
asm volatile("":::"memory");
}
printf("faulting!\n");
int *p = (int *)0;
*p = 0;
return 0;
}

@ -0,0 +1,29 @@
#include <litc.h>
int main(int argc, char **argv)
{
if (open((const char *)0x12347, O_RDONLY, 0) >= 0 || errno != EFAULT)
errx(-1, "no fault?");
errno = 0;
if (write(1, (void *)0x7ffffff0, 10) >= 0 || errno != EFAULT)
errx(-1, "no fault?");
errno = 0;
// g0 stack
if (mkdir((const char *)0xffffffffffffffff, 0) == 0 || errno != EFAULT)
errx(-1, "no fault?");
errno = 0;
int fd;
if ((fd = open("/bigfile.txt", O_RDONLY, 0)) < 0)
err(fd, "open");
if (errno != 0)
errx(-1, "errno changed on success?");
// kernel text
if (read(fd, (void *)0x400040, 1024) >= 0 || errno != EFAULT)
errx(-1, "no fault?");
printf("success\n");
return 0;
}

@ -0,0 +1,44 @@
#include<stdio.h>
#include<unistd.h>
#include<err.h>
#include<poll.h>
#include<fcntl.h>
#include<sys/socket.h>
int main(int argc, char **argv)
{
if (fcntl(0, F_SETFL, O_NONBLOCK | fcntl(0, F_GETFL, 0)) == -1)
err(-1, "fcntl");
struct pollfd pfd = {fd: 0, events: POLLIN};
if (poll(&pfd, 1, -1) != 1)
err(-1, "poll");
char buf[128];
ssize_t did = 0, r;
while ((r = read(0, buf, sizeof(buf))) > 0)
did += r;
if (r != -1 || errno != EAGAIN)
err(-1, "read");
if (did != 18)
fprintf(stderr, "unexpected GET len (%zd)\n", did);
char msg[] =
"HTTP/1.1 200 OK\n"
"Server: fweb\n"
"Date: Tue, 06 Dec 2016 23:32:42 GMT\n"
"Content-Type: text/plain\n"
"Connection: close\n"
"\r\n\r\n"
"All work and no play make Jack a dull boy.\n"
"All work an no play make Jack a dull boy.\n"
"all work and no play make Jack a dull boy.\n"
"Allw ork and no play make Jack a dull boy.\n"
"All work and no play make jack a dull boy.\n"
"All work andd no play make Jack a dull boy.\n"
"All work and no play make Jack a dull boy.\n";
size_t mlen = sizeof(msg) - 1;
if (write(1, msg, mlen) != mlen)
err(-1, "write");
return 0;
}

@ -0,0 +1,33 @@
#include <litc.h>
void child(int id)
{
int i;
for (i = 0; i < 3; i++) {
printf("hello from %d\n", id);
}
exit(id);
}
int main(int argc, char **argv)
{
int pid = 0;
int id = 0;
while (id < 100) {
pid = fork();
id++;
if (!pid)
child(id);
//if (wait(NULL) != pid)
// errx(-1, "wrong pid %d", pid);
if (wait4(pid, NULL, 0, NULL) != pid)
errx(-1, "wrong pid %d", pid);
if (wait4(pid - 1, NULL, 0, NULL) > 0)
errx(-1, "wait4 should fail");
if (wait(NULL) > 0)
errx(-1, "wait should fail");
}
printf("parent done!\n");
return 0;
}

@ -0,0 +1,48 @@
#include <litc.h>
static char buf[5120];
void readprint(int fd)
{
long ret;
if ((ret = read(fd, &buf, sizeof(buf))) < 0) {
err(ret, "read");
exit(-1);
}
printf("FD %d read %ld bytes\n", fd, ret);
if (ret == sizeof(buf))
ret = sizeof(buf) - 1;
buf[ret] = '\0';
printf("FD %d returned: %s\n", fd, buf);
}
int main(int argc, char **argv)
{
int pid1 = fork();
int pid2 = fork();
int fd;
if ((fd = open("/boot/uefi/readme.txt", O_RDWR, 0)) < 0) {
err(fd, "open");
return -1;
}
if (pid1 && pid2) {
int j;
for (j = 0; j < 100000000; j++)
asm volatile("":::"memory");
readprint(fd);
return 0;
}
int i;
for (i = 0; i < sizeof(buf); i++)
buf[i] = 0x41 + (i / 1000);
int ret;
if ((ret = write(fd, buf, sizeof(buf))) != sizeof(buf)) {
err(ret, "write");
return -1;
}
return 0;
}

@ -0,0 +1,43 @@
#include <litc.h>
static char buf[1024];
void readprint(int fd)
{
long ret;
if ((ret = read(fd, &buf, sizeof(buf))) < 0) {
err(ret, "read");
exit(-1);
}
printf("FD %d read %ld bytes\n", fd, ret);
if (ret == sizeof(buf))
ret = sizeof(buf) - 1;
buf[ret] = '\0';
printf("FD %d returned: %s\n", fd, buf);
}
int main(int argc, char **argv)
{
int pid = fork();
int fd, ret;
if (pid) {
wait(NULL);
if ((ret = open("/afile", O_RDONLY, 0)) < 0)
errx(ret, "open failed");
fd = ret;
readprint(fd);
return 0;
}
if ((ret = open("/afile", O_RDWR|O_CREAT, 0755)) < 0)
errx(ret, "open failed");
fd = ret;
snprintf(buf, sizeof(buf), "heeeey yeaaa yeaaa yea yea, heeeeey"
"yeaaaa, yeaaaa.... i say hey! whats going on!");
if ((ret = write(fd, buf, strlen(buf))) != strlen(buf))
errx(ret, "write failed");
return 0;
}

@ -0,0 +1,74 @@
#include <litc.h>
static char buf[1024];
void fillbuf(char c)
{
int i;
for (i = 0; i < sizeof(buf); i++)
buf[i] = c;
}
void chk(int fd, char c)
{
if (read(fd, buf, sizeof(buf)) != sizeof(buf))
errx(-1, "short read");
int i;
for (i = 0; i < sizeof(buf); i++)
if (buf[i] != c)
errx(-1, "byte mismatch");
}
int main(int argc, char **argv)
{
int fd;
if ((fd = open("/newfile", O_RDWR|O_CREAT, 0755)) < 0)
errx(fd, "create failed");
fillbuf('A');
if (write(fd, buf, sizeof(buf)) != sizeof(buf))
errx(-1, "short write");
if (unlink("/newfile") != 0)
errx(-1, "should have succeeded");
printf("erased...\n");
if ((fd = open("/yetanother", O_RDWR|O_CREAT, 0755)) < 0)
errx(fd, "create failed");
int fd2;
if ((fd2 = open("/evenmore", O_RDWR|O_CREAT, 0755)) < 0)
errx(fd2, "create failed");
printf("filing two...\n");
fillbuf('B');
if (write(fd, buf, sizeof(buf)) != sizeof(buf))
errx(-1, "short write");
printf("first fill...\n");
fillbuf('C');
if (write(fd2, buf, sizeof(buf)) != sizeof(buf))
errx(-1, "short write");
if (close(fd) != 0)
errx(-1, "close");
if (close(fd2) != 0)
errx(-1, "close");
printf("checking contents...\n");
if ((fd = open("/yetanother", O_RDONLY, 0)) < 0)
errx(fd, "open original failed");
chk(fd, 'B');
if ((fd2 = open("/evenmore", O_RDONLY, 0755)) < 0)
errx(fd2, "create failed");
chk(fd2, 'C');
printf("success\n");
return 0;
}

@ -0,0 +1,43 @@
#include <litc.h>
static char buf[1024];
void readprint(int fd)
{
long ret;
if ((ret = read(fd, &buf, sizeof(buf))) < 0) {
err(ret, "read");
exit(-1);
}
printf("FD %d read %ld bytes\n", fd, ret);
if (ret == sizeof(buf))
ret = sizeof(buf) - 1;
buf[ret] = '\0';
printf("FD %d returned: %s\n", fd, buf);
}
int main(int argc, char **argv)
{
if (link("/biscuit", "/spin") >= 0)
errx(-1, "should have failed");
if (link("/boot/uefi/readme.txt", "/crap") != 0)
errx(-1, "should have suceeded");
int fd;
if ((fd = open("/crap", O_RDONLY, 0)) < 0)
errx(-1, "open failed");
readprint(fd);
if (link("/boot/uefi/readme.txt", "/boot/uefi/crap") != 0)
errx(-1, "should have suceeded");
if ((fd = open("/boot/uefi/crap", O_RDONLY, 0)) < 0)
errx(-1, "open failed");
readprint(fd);
if (link("/boot", "/dirhardlink") >= 0)
errx(-1, "dir link should fail");
return 0;
}

@ -0,0 +1,26 @@
#include <litc.h>
static char buf[1024];
int main(int argc, char **argv)
{
int ret;
if ((ret = mkdir("/wtf", 0755)) < 0)
err(ret, "mkdir failed");
if ((ret = mkdir("/wtf/happyday", 0755)) < 0)
err(ret, "mkdir failed");
if ((ret = mkdir("/wtf/happyday/wut", 0755)) < 0)
err(ret, "mkdir failed");
if ((ret = open("/wtf/happyday/wut/afile", O_RDWR|O_CREAT, 0755)) < 0)
err(ret, "open failed");
int fd = ret;
snprintf(buf, sizeof(buf), "we fight for the user!");
if ((ret = write(fd, buf, strlen(buf))) != strlen(buf))
err(ret, "write failed");
return 0;
}

@ -0,0 +1,54 @@
#include <litc.h>
static char buf[1024];
void readprint(int fd)
{
long ret;
if ((ret = read(fd, &buf, sizeof(buf))) < 0) {
err(ret, "read");
exit(-1);
}
printf("FD %d read %ld bytes\n", fd, ret);
if (ret == sizeof(buf))
ret = sizeof(buf) - 1;
buf[ret] = '\0';
printf("FD %d returned: %s\n", fd, buf);
}
int main(int argc, char **argv)
{
int ret;
if ((ret = open("/etc/passwd", O_RDONLY, 0)) >= 0) {
errx(-1, "open should fail");
return -1;
}
if ((ret = open("/hi.txt", O_RDONLY, 0)) < 0) {
err(ret, "open");
return -1;
}
int fd1 = ret;
if ((ret = open("/boot/uefi/readme.txt", O_RDONLY, 0)) < 0) {
err(ret, "open");
return -1;
}
int fd2 = ret;
if ((ret = open("/clouseau.txt", O_RDONLY, 0)) < 0) {
err(ret, "open");
return -1;
}
int fd3 = ret;
if ((ret = open("/boot/bsd", O_RDONLY, 0)) < 0) {
err(ret, "open");
return -1;
}
int fd4 = ret;
readprint(fd1);
readprint(fd2);
readprint(fd3);
readprint(fd4);
printf("FS TESTS PASSED!\n");
return 0;
}

@ -0,0 +1,53 @@
#include <litc.h>
static char buf[1024];
void readprint(int fd)
{
long ret;
if ((ret = read(fd, &buf, sizeof(buf))) < 0) {
err(ret, "read");
exit(-1);
}
printf("FD %d read %ld bytes\n", fd, ret);
if (ret == sizeof(buf))
ret = sizeof(buf) - 1;
buf[ret] = '\0';
printf("FD %d returned: %s\n", fd, buf);
}
int main(int argc, char **argv)
{
if (link("/boot/uefi/readme.txt", "/crap") != 0)
errx(-1, "should have succeeded");
int fd;
if ((fd = open("/crap", O_RDONLY, 0)) < 0)
errx(-1, "open failed");
readprint(fd);
if (unlink("/crap") != 0)
errx(-1, "should have succeeded");
if ((fd = open("/crap", O_RDONLY, 0)) >= 0)
errx(-1, "open of unlinked should have failed");
if ((fd = open("/boot/uefi/readme.txt", O_RDONLY, 0)) < 0)
errx(-1, "open original failed");
readprint(fd);
if (unlink("/boot/uefi/readme.txt") != 0)
errx(-1, "should have succeeded");
if (unlink("/another") >= 0)
errx(-1, "should have failed");
if (unlink("/another/you-found-me") != 0)
errx(-1, "should have succeeded");
if (unlink("/another") != 0)
errx(-1, "should have succeeded");
printf("success\n");
return 0;
}

@ -0,0 +1,54 @@
#include <litc.h>
static char buf[1024];
void readprint(int fd)
{
long ret;
if ((ret = read(fd, &buf, sizeof(buf))) < 0) {
err(ret, "read");
}
printf("FD %d read %ld bytes\n", fd, ret);
if (ret == sizeof(buf))
ret = sizeof(buf) - 1;
buf[ret] = '\0';
printf("FD %d returned: %s\n", fd, buf);
}
int main(int argc, char **argv)
{
int pid1 = fork();
int pid2 = fork();
int fd;
if ((fd = open("/boot/uefi/readme.txt", O_RDWR, 0)) < 0) {
err(fd, "open");
return -1;
}
if (pid1 && pid2) {
int j;
for (j = 0; j < 100000000; j++)
asm volatile("":::"memory");
readprint(fd);
return 0;
}
char msg[] = "hey yea yea yea yea yea ja ja ja ya ya ya, ho ho ha ha"
" ha! he ya ya ya ya ya ja ja ja ye ye ye, ho ho ho ho hoooooooo"
"ooooooo yo yo yoooooooooooo ya yay aaaaa yaaaaaa ya ya yaaaaa!"
" [%d %d]";
snprintf(buf, sizeof(buf), msg, getpid(), 1);
int ret;
if ((ret = write(fd, buf, strlen(buf))) != strlen(buf)) {
err(ret, "write");
return -1;
}
snprintf(buf, sizeof(buf), msg, getpid(), 2);
if ((ret = write(fd, buf, strlen(buf))) != strlen(buf)) {
err(ret, "write");
return -1;
}
return 0;
}

@ -0,0 +1,120 @@
#include<stdio.h>
#include<unistd.h>
#include<err.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<netinet/in.h>
static ulong nowus()
{
struct timeval t;
if (gettimeofday(&t, NULL))
errx(-1, "gettimeofday");
return t.tv_sec * 1000000 + t.tv_usec;
}
static void profdump(void)
{
int fd = open("/pc.sh", O_RDONLY);
if (fd == -1)
err(-1, "open");
if (dup2(fd, 0) == -1)
err(-1, "dup");
close(fd);
char * const args[] = {"/bin/lsh", NULL};
execv(args[0], args);
err(-1, "exec");
}
static void forkwait(void (*f)(void))
{
switch (fork()) {
case -1:
err(-1, "fork");
case 0:
f();
errx(-1, "child returned");
}
int status;
if (wait(&status) == -1)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
printf("child failed\n");
}
static void req(int s)
{
if (dup2(s, 0) == -1)
err(-1, "dup2");
if (dup2(s, 1) == -1)
err(-1, "dup2");
if (close(s) == -1)
err(-1, "close");
char *args[] = {"./bin/fcgi", NULL};
execv(args[0], args);
err(-1, "execv");
}
int main(int argc, char **argv)
{
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
err(-1, "socket");
int prof = 1;
if (argc != 1) {
printf("profiling\n");
prof = 0;
}
struct sockaddr_in sin;
int lport = 8080;
sin.sin_family = AF_INET;
sin.sin_port = htons(lport);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
err(-1, "bind");
if (listen(s, 8) == -1)
err(-1, "listen");
fprintf(stderr, "listen on %d\n", lport);
srand(time(NULL));
ulong st = nowus();
for (;;) {
if (prof) {
if (sys_prof(PROF_SAMPLE, PROF_EV_UNHALTED_CORE_CYCLES,
//PROF_EVF_OS | PROF_EVF_USR | PROF_EVF_BACKTRACE,
PROF_EVF_OS | PROF_EVF_USR,
2800/2) == -1)
err(-1, "sysprof");
}
socklen_t slen = sizeof(sin);
int fd = accept(s, (struct sockaddr *)&sin, &slen);
if (fd == -1)
err(-1, "accept");
pid_t c = fork();
if (c == -1)
err(-1, "fork");
if (!c)
req(fd);
if (close(fd) == -1)
err(-1, "close");
int status;
if (wait(&status) != c)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errx(-1, "child failed");
if (prof) {
if (sys_prof(PROF_SAMPLE | PROF_DISABLE, 0, 0, 0) == -1)
err(-1, "sysprof");
}
long end = nowus();
long elap = end - st;
st = end;
if (elap >= 1000 && (rand() % 10000) < 1000) {
printf("GOT PROFILE for %ldus\n", elap);
printf("WAIT FOR DUMP...\n");
forkwait(profdump);
st = nowus();
}
}
}

@ -0,0 +1,13 @@
#include <litc.h>
int main()
{
int i;
//fork();
for (i = 0; i < 30000; i++) {
int pid = getpid();
printf("my pid is %d.\n", pid);
}
return 0;
}

@ -0,0 +1,47 @@
#include <litc.h>
void cmb(void)
{
if (mkdir("/mb", 0700) == -1)
err(-1, "mkdir");
if (chdir("/mb") == -1)
err(-1, "chdir");
char * const args[] = {"/bin/cmailbench", "-d", "1", "./", "1", NULL};
execv(args[0], args);
err(-1, "exec");
}
void forkwait(void (*f)(void))
{
switch (fork()) {
case -1:
err(-1, "fork");
case 0:
f();
errx(-1, "child returned");
}
int status;
if (wait(&status) == -1)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errx(-1, "child failed");
}
void cleanup(void)
{
char * const args[] = {"/bin/rmtree", "/mb", NULL};
execv(args[0], args);
err(-1, "exec");
}
int main(int argc, char **argv)
{
for (;;) {
forkwait(cmb);
forkwait(cleanup);
sleep(3);
}
return 0;
}

@ -0,0 +1,322 @@
#include <litc.h>
static void gcrun(char * const *cmd, long *_ngcs, long *_xput, double *_gcfrac)
{
int p[2];
if (pipe(p) == -1)
err(-1, "pipe");
pid_t c = fork();
if (c == -1)
err(-1, "fork");
if (!c) {
close(p[0]);
if (dup2(p[1], 1) == -1)
err(-1, "dup2");
close(p[1]);
const int cmdsz = 62;
char *cmds[62+2] = {"time", "-g"};
int i;
for (i = 0; i < cmdsz; i++) {
cmds[2+i] = cmd[i];
if (cmd[i] == NULL)
break;
}
execvp(cmds[0], cmds);
err(-1, "exec");
}
close(p[1]);
long ngcs = -1;
long xput = 0;
double gcfrac = 0;
char buf[512];
ssize_t r;
int off = 0;
while ((r = read(p[0], &buf[off], sizeof(buf) - off - 1)) > 0) {
char *end = &buf[off+r];
*end = '\0';
if (strchr(buf, '\n') == NULL) {
fprintf(stderr, "warning: ignoring long line\n");
off = 0;
continue;
}
char *nl, *last = buf;
while ((nl = strchr(last, '\n')) != NULL) {
*nl = '\0';
sscanf(last, "GCs: %ld", &ngcs);
sscanf(last, "GC CPU frac: %lf", &gcfrac);
sscanf(last, "\tops: %ld", &xput);
last = nl + 1;
}
off = end - last;
memmove(buf, last, off);
}
if (r == -1)
err(-1, "read");
int status;
if (wait(&status) == -1)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errx(-1, "child failed");
close(p[0]);
if (_ngcs)
*_ngcs = ngcs;
if (_gcfrac)
*_gcfrac = gcfrac;
if (_xput)
*_xput = xput;
}
static void _run(char **cmd)
{
pid_t c = fork();
if (c == -1)
err(-1, "fork");
if (!c) {
int fd = open("/dev/null", O_WRONLY);
if (fd == -1)
err(-1, "open");
if (dup2(fd, 1) == -1)
err(-1, "dup2");
close(fd);
execvp(cmd[0], cmd);
err(-1, "execvp");
}
int status;
if (wait(&status) == -1)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
errx(-1, "child failed");
}
// format the benchmark command given the parameters. only the most recent
// command returned is valid.
static void _mkbmcmd(char **cmd, size_t ncmd, long allocr, long duration)
{
if (ncmd < 6)
errx(-1, "little cmd buf");
// duration in seconds
static char dbuf[32];
snprintf(dbuf, sizeof(dbuf), "-s%ld", duration);
static char abuf[32];
snprintf(abuf, sizeof(abuf), "-A%ld", allocr);
cmd[0] = "sfork";
cmd[1] = dbuf;
cmd[2] = "-ba";
cmd[3] = abuf;
cmd[4] = "1";
cmd[5] = NULL;
}
#define GOGC 100
// find the xput for a run of benchmark at a particular allocation rate
__attribute__((unused))
static long nogcxput(long allocr)
{
errx(-1, "do not use; taints GC costs for smaller heaps");
// set kernel heap size to ~16GB to avoid any gcs
char *hcmd[] = {"bmgc", "-h", "16000", NULL};
char *rcmd2[] = {"bmgc", "-g", NULL};
_run(hcmd);
_run(rcmd2);
const int ncmd = 10;
char *cmd[ncmd];
_mkbmcmd(cmd, ncmd, allocr, 10);
long ngcs, xput;
int i;
for (i = 0; i < 10; i++) {
gcrun(cmd, &ngcs, &xput, NULL);
if (ngcs == 0)
break;
xput = 0;
}
if (!xput)
errx(-1, "failed to get 0 gc xput for allocrate %ld", allocr);
// restore old total heap size
char *rcmd1[] = {"bmgc", "-H", "100", NULL};
_run(rcmd1);
_run(rcmd2);
return xput;
}
// for a given gc cpu fraction upperbound and allocation rate, find total heap
// sizing to keep gc cpu time < that gc cput fraction upperbound. returns the
// total heap size in GOGC terms (all heap sizes are in GOGC terms).
static int findtotalheapsz(double gcfracub, long allocr, const long targetgcs,
const long gc0xput)
{
// first, get the xput of this allocation rate with 0 gcs. we use that
// xput to calculate GC CPU time.
//long gc0xput = nogcxput(allocr);
printf("0gc xput is %ld\n", gc0xput);
// initialize binary search bounds
#define HIGC 700
int higc = HIGC;
int logc = 10;
// minimum heap size increment
#define GCINC 10
const int gcinc = GCINC;
#define TRIEDSZ ((HIGC/GCINC)+1)
// byte array tracking whether we tried a certain heap size yet. when
// we find two adjacents heap sizes that have been tried but had
// different outcomes (i.e. gc fraction was higher than upper bound for
// one and lower than upperbound for the other), we have found the
// target heap size.
const char _nottried = 0;
// this slot resulted in gc frac lower than upperbound
const char _lower = -1;
// this slot resulted in gc frac higher than upperbound
const char _higher = 1;
char tried[TRIEDSZ] = {0};
long duration = 10;
char lastres = _nottried;
while (1) {
int curgc = (higc + logc) / 2;
// round to multiple of incgc
curgc = (curgc/gcinc)*gcinc;
int curslot = curgc / gcinc;
// make sure to round to final slot
if (tried[curslot] != _nottried) {
if (lastres == _lower)
curgc -= gcinc;
else if (lastres == _higher)
curgc += gcinc;
else
errx(-1, "bad lastres: %d", lastres);
curslot = curgc/gcinc;
if (curslot < 0 || curslot >= TRIEDSZ)
errx(-1, "cannot meet goal gc cpu fraction");
if (tried[curslot] != _nottried)
errx(-1, "rounded, but already tried?");
}
printf("=== trying GOGC heap size of %d ===\n", curgc);
char heapszbuf[32];
snprintf(heapszbuf, sizeof(heapszbuf), "%d", curgc);
char *resizecmds[] = {"bmgc", "-H", heapszbuf, NULL};
_run(resizecmds);
// run the benchmark for increasing durations of time until we
// have at least 20 gcs.
long foundxput;
while (1) {
const int ncmds = 32;
char *cmds[32];
_mkbmcmd(cmds, ncmds, allocr, duration);
long xput, ngcs;
printf("trying allocr %ld with heap %d for %ld "
"seconds...\n", allocr, curgc, duration);
gcrun(cmds, &ngcs, &xput, NULL);
if (ngcs >= targetgcs) {
printf("good. got %ld gcs\n", ngcs);
foundxput = xput;
// prevent duration from growing too large too
// quickly
if (ngcs / targetgcs > 1)
duration /= ngcs / targetgcs;
break;
}
printf("only %ld gcs, trying again...\n", ngcs);
double gcps = (double)ngcs/duration;
if (gcps == 0)
duration = 120;
else
duration = targetgcs/gcps + (duration/8);
char *prep[] = {"bmgc", "-g", NULL};
_run(prep);
}
// finally have a run with >20 gcs. calculate gc cpu frac.
double gcfrac = 1.0 - (double)foundxput/gc0xput;
if (gcfrac <= gcfracub)
lastres = _lower;
else
lastres = _higher;
tried[curslot] = lastres;
// adjust binary search bounds and duration
int lastgc = curgc;
if (lastres == _lower)
higc = curgc;
else
logc = curgc;
duration *= (double)curgc/lastgc;
printf(" GC frac: %f\n", gcfrac);
printf(" adjust heap size %s\n",
lastres == _lower ? "SMALLER" : "BIGGER");
// see if we are done
int i;
for (i = 1; i < TRIEDSZ; i++) {
if (tried[i-1] == _nottried || tried[i] == _nottried)
continue;
if (tried[i-1] != tried[i]) {
printf("FOUND\n");
int low = (i-1)*gcinc;
int hi = i*gcinc;
char st = tried[i-1];
printf(" heap %d: %s\n", low,
st == _lower ? "SMALLER" : "BIGGER");
st = tried[i];
printf(" heap %d: %s\n", hi,
st == _lower ? "SMALLER" : "BIGGER");
return hi;
}
}
}
}
__attribute__((unused))
static void usage()
{
fprintf(stderr, "usage: %s [-n target gcs] [-c target gc frac]"
" -x <0gc xput> <allocr>\n", __progname);
exit(-1);
}
int main(int argc, char **argv)
{
long targetgcs = 20;
double gctarget = 0.055;
long gc0x = 0;
int c;
while ((c = getopt(argc, argv, "x:n:mc:")) != -1) {
switch (c) {
case 'c':
gctarget = strtod(optarg, NULL);
if (gctarget < 0 || gctarget > 100.0)
gctarget = 0.055;
break;
case 'n':
targetgcs = strtol(optarg, NULL, 0);
if (targetgcs < 0)
targetgcs = 20;
break;
case 'x':
gc0x = strtol(optarg, NULL, 0);
break;
default:
usage();
break;
}
}
if (argc - optind != 1 || gc0x <= 0)
usage();
long allocr = strtol(argv[optind], NULL, 0);
if (allocr < 0)
allocr = 32;
long idealheap = findtotalheapsz(gctarget, allocr, targetgcs, gc0x);
printf("ideal heap for allocr %ld: %ld\n", allocr, idealheap);
return 0;
}

@ -0,0 +1,31 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BSIZE 4096
char buf[BSIZE];
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("Usage: %s filename n\n", argv[0]);
exit(-1);
}
int n = atoi(argv[2]);
FILE *f = fopen(argv[1], "r");
if (f == NULL)
err(-1, "fopen");
size_t r;
if ((r = fread(buf, 1, n, f)) > 0) {
for (int i = 0; i < r; i++) {
printf("%c", buf[i]);
}
}
printf("\n");
return 0;
}

@ -0,0 +1,14 @@
#include <litc.h>
int main(int argc, char **argv)
{
int i;
for (i = 0; i < 3; i++) {
printf("hello world!\n");
int j;
for (j = 0; j < 100000000; j++)
asm volatile("":::"memory");
}
return 0;
}

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,17 @@
// sadly, assert.h must be its own file so that NDEBUG works
#pragma once
#include <stdlib.h>
#ifdef NDEBUG
#define assert(ignore) ((void) 0)
#else
#define assert(x) __assert(x, __FILE__, __LINE__)
#define __assert(x, y, z) \
do { \
if (!(x)) { \
fprintf(stderr, "assertion failed (" #x ") at %s:%d\n", y, z);\
abort();\
} \
} while (0)
#endif

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,109 @@
#pragma once
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned long size_t;
typedef long ssize_t;
typedef long ptrdiff_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long uint64_t;
typedef char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;
typedef long int_least64_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned long uint_least64_t;
// OpenBSD uses int32_t for all fastN_t except 64
typedef int int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;
typedef long int_fast64_t;
typedef unsigned int uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef unsigned long uint_fast64_t;
typedef long intmax_t;
typedef unsigned long uintmax_t;
typedef unsigned char u8;
typedef long time_t;
typedef unsigned long nfds_t;
typedef unsigned long mode_t;
typedef long dev_t;
typedef ulong ino_t;
typedef long off_t;
typedef long pid_t;
typedef long uid_t;
typedef long gid_t;
typedef unsigned long socklen_t;
typedef unsigned long rlim_t;
typedef unsigned long sigset_t;
typedef volatile long sig_atomic_t;
typedef long blkcnt_t;
typedef char * caddr_t;
#define NULL ((void *)0)
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(d, s) __builtin_va_copy(d, s)
typedef __builtin_va_list va_list;
#define INT8_MIN (-128)
#define INT16_MIN (-32768)
#define INT32_MIN (-2147483648)
#define INT8_MAX 127
#define INT16_MAX 32767
#define INT32_MAX 2147483647
#define INT_MIN (1 << 31)
#define INT_MAX 2147483647
#define UINT_MAX 0xffffffff
#define LONG_MIN (1ll << 63)
#define LLONG_MIN (1ll << 63)
#define LONG_MAX 9223372036854775807ll
#define LLONG_MAX 9223372036854775807ll
#define UCHAR_MAX 0xff
#define UINT16_MAX 0xffff
#define ULONG_MAX 0xffffffffffffffffull
#define ULLONG_MAX 0xffffffffffffffffull
#define INT8_C(x) x
#define INT16_C(x) x
#define INT32_C(x) x
#define INT64_C(x) x ## ll
#define UINT8_C(x) x ## u
#define UINT16_C(x) x ## u
#define UINT32_C(x) x ## u
#define UINT64_C(x) x ## ull

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,3 @@
#pragma once
#include <litc.h>

@ -0,0 +1,93 @@
#include <litc.h>
static void fexec(char * const args[])
{
printf("init exec: ");
for (char * const * p = &args[0]; *p; p++)
printf("%s ", *p);
printf("\n");
switch (fork()) {
case -1:
err(-1, "fork (%s)", args[0]);
case 0:
execv(args[0], args);
err(-1, "exec (%s)", args[0]);
default:
{
int status;
if (wait(&status) == -1)
err(-1, "wait");
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
err(-1, "child failed (%s)", args[0]);
}
}
}
int main(int argc, char **argv)
{
int rshd = 0;
int c;
while ((c = getopt(argc, argv, "r")) != -1) {
switch (c) {
default:
printf("bad option/arg\n");
break;
case 'r':
rshd = 1;
break;
}
}
argc -= optind;
argv += optind;
if (argc > 0)
printf("ignoring extra args\n");
printf("init starting...\n");
// create dev nodes
mkdir("/dev", 0);
int ret;
ret = mknod("/dev/console", 0, MKDEV(1, 0));
if (ret != 0 && errno != EEXIST)
err(-1, "mknod");
ret = mknod("/dev/null", 0, MKDEV(4, 0));
if (ret != 0 && errno != EEXIST)
err(-1, "mknod");
ret = mknod("/dev/rsd0c", 0, MKDEV(5, 0));
if (ret != 0 && errno != EEXIST)
err(-1, "mknod");
ret = mknod("/dev/stats", 0, MKDEV(6, 0));
if (ret != 0 && errno != EEXIST)
err(-1, "mknod");
ret = mknod("/dev/prof", 0, MKDEV(7, 0));
if (ret != 0 && errno != EEXIST)
err(-1, "mknod");
char * const largs [] = {"/bin/bmgc", "-l", "512", NULL};
fexec(largs);
char * const hargs [] = {"/bin/bmgc", "-h", "470", NULL};
fexec(hargs);
if (rshd) {
printf("starting rshd...\n");
pid_t rpid = fork();
if (rpid == 0) {
char * const rargs [] = {"/bin/rshd", NULL};
execv(rargs[0], rargs);
err(-1, "execv");
} else if (rpid == -1)
perror("execv");
}
for (;;) {
int pid = fork();
if (!pid) {
char * const args[] = {"/bin/lsh", NULL};
execv(args[0], args);
err(-1, "execv");
}
wait(NULL);
printf("lsh terminated?\n");
}
return 0;
}

@ -0,0 +1,10 @@
#include <litc.h>
int main(int argc, char **argv)
{
if (argc != 2)
errx(-1, "usage: %s <pid>\n", argv[0]);
int pid = atoi(argv[1]);
return kill(pid, SIGKILL);
}

@ -0,0 +1,17 @@
#include <litc.h>
int main(int argc, char **argv)
{
int pid = fork();
if (pid == 0)
while (1);
printf("killing %d...", pid);
if (kill(pid, SIGKILL) < 0)
err(-1, "kill");
printf("killed. waiting...");
if (wait(NULL) < 0)
err(-1, "wait failed\n");
printf("done\n");
printf("success\n");
return 0;
}

@ -0,0 +1,195 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
/* Measure creating a large file and overwriting that file */
#define WSIZE (4096)
#define FILESIZE 50 * 1024 * 1024
#define NAMESIZE 100
static char name[NAMESIZE];
static char buf[WSIZE];
static char *prog;
static char *dir;
void printstats(int reset)
{
int fd;
int r;
sprintf(name, "dev/stats");
if((fd = open(name, O_RDONLY)) < 0) {
return;
}
memset(buf, 0, WSIZE);
if ((r = read(fd, buf, WSIZE)) < 0) {
perror("read");
exit(1);
}
if (!reset) fprintf(stdout, "=== FS Stats ===\n%s========\n", buf);
if ((r = close(fd)) < 0) {
perror("close");
}
}
void makefile()
{
int i;
int fd;
int n = FILESIZE/WSIZE;
memset(buf, 'a', WSIZE);
sprintf(name, "%s/d/f", dir);
if((fd = open(name, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
printf("%s: create %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
for (i = 0; i < n; i++) {
if (write(fd, buf, WSIZE) != WSIZE) {
printf("%s: write %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
}
if (fsync(fd) < 0) {
printf("%s: fsync %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
fd = open(".", O_DIRECTORY | O_RDONLY);
if (fd < 0) {
perror("open dir");
exit(-1);
}
if (fsync(fd) < 0) {
perror("fsync");
exit(-1);
}
}
void writefile()
{
int i;
int fd;
int n = FILESIZE/WSIZE;
sprintf(name, "%s/d/f", dir);
if((fd = open(name, O_RDWR, S_IRWXU)) < 0) {
printf("%s: open %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
memset(buf, 'b', WSIZE);
for (i = 0; i < n; i++) {
if (write(fd, buf, WSIZE) != WSIZE) {
printf("%s: write %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
if (((i + 1) * WSIZE) % (10 * 1024 * 1024) == 0) {
if (fsync(fd) < 0) {
printf("%s: fsync %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
}
}
if ((i * WSIZE) % (10 * 1024 * 1024) != 0 && fsync(fd) < 0) {
printf("%s: fsync %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
close(fd);
}
void usage(char *name) {
printf("Usage: %s basedir\n", name);
exit(-1);
}
int main(int argc, char *argv[])
{
long time;
struct timeval before;
struct timeval after;
float tput;
int make = 1;
int write = 1;
int ch;
prog = argv[0];
while ((ch = getopt(argc, argv, "mw")) != -1) {
switch (ch) {
case 'm':
make = 0;
break;
case 'w':
write = 0;
break;
default:
usage(argv[0]);
break;
}
}
int rem = argc - optind;
if (rem != 1) {
usage(argv[0]);
}
dir = argv[optind];
sprintf(name, "%s/d", dir);
if (make) {
if (mkdir(name, S_IRWXU) < 0) {
printf("%s: create %s failed %s\n", prog, name, strerror(errno));
exit(1);
}
printstats(1);
gettimeofday ( &before, NULL );
makefile();
gettimeofday ( &after, NULL );
time = (after.tv_sec - before.tv_sec) * 1000000 +
(after.tv_usec - before.tv_usec);
tput = ((float) (FILESIZE/1024) / (time / 1000000.0));
printf("makefile %d MB %ld usec throughput %f KB/s\n", FILESIZE/(1024*1024), time, tput);
printstats(0);
}
if (write) {
printstats(1);
gettimeofday ( &before, NULL );
writefile();
gettimeofday ( &after, NULL );
time = (after.tv_sec - before.tv_sec) * 1000000 +
(after.tv_usec - before.tv_usec);
tput = ((float) (FILESIZE/1024) / (time / 1000000.0));
printf("writefile %d MB %ld usec throughput %f KB/s\n", FILESIZE/(1024*1024), time, tput);
printstats(0);
}
return 0;
}

@ -0,0 +1,36 @@
#include <litc.h>
int main(int argc, char **argv)
{
if (argc < 2)
errx(-1, "usage: %s <file> [<file>...]", argv[0]);
FILE *fout = fdopen(1, "w");
if (!fout)
err(-1, "fdopen");
int i;
for (i = 1; i < argc; i++) {
char *fn = argv[i];
FILE *f = fopen(fn, "r");
if (!f)
err(-1, "fopen");
char buf;
size_t ret;
int nl = 0;
while ((ret = fread(&buf, 1, 1, f)) == 1) {
if (fwrite(&buf, 1, 1, fout) != 1)
err(-1, "fwrite");
// 24 lines at a time
if (buf == '\n')
nl++;
if (nl == 24) {
if (read(0, &buf, 1) != 1)
err(-1, "read stdin");
nl = 0;
}
}
if (ferror(f))
err(-1, "fread");
fclose(f);
}
return 0;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,13 @@
ENTRY(_entry)
SECTIONS
{
. = 0x2c8000001000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
/DISCARD/ : {
*(.eh_frame)
}
}

@ -0,0 +1,176 @@
#include <litc.h>
static char lmss[1ul << 11];
static int mss(int s)
{
printf("MSS sends\n");
int fd = open("/redis.conf", O_RDONLY);
if (fd == -1)
err(-1, "open");
ssize_t r;
if ((r = read(fd, lmss, sizeof(lmss))) == -1)
err(-1, "read");
else if (r != sizeof(lmss))
errx(-1, "short read?");
char *p = &lmss[0];
size_t left = sizeof(lmss);
while (left) {
if ((r = write(s, p, left)) == -1)
err(-1, "write");
if (r == -1)
err(-1, "write");
else if (r == 0)
errx(-1, "wat?");
if (r > left)
errx(-1, "uh oh");
left -= r;
p += r;
}
printf("lnc finished\n");
return 0;
}
static char buf[1460 - 12];
int nc(int s)
{
struct pollfd pfds[2] = {{.fd = 0}, {.fd = s}};
const int nfds = 2;
int closed = 0;
ssize_t wtot = 0;
while (closed != 2) {
pfds[0].events = pfds[1].events = POLLIN;
int ret;
if ((ret = poll(pfds, nfds, -1)) == -1)
err(-1, "poll");
if (ret == 0)
errx(-1, "what");
int i;
for (i = 0; i < nfds; i++) {
if ((pfds[i].revents & POLLIN) == 0)
continue;
ssize_t c = read(pfds[i].fd, buf, sizeof(buf));
if (c == -1) {
err(-1, "read");
} else if (c == 0) {
fprintf(stderr, "fd %d EOF\n", pfds[i].fd);
closed++;
pfds[i].fd = -1;
if (i == 0) {
if (shutdown(s, SHUT_WR) == -1)
err(-1, "shutdown");
}
continue;
}
ssize_t w = write(i == 0 ? s : 1, buf, c);
if (w == -1)
err(-1, "write");
else if (w != c)
errx(-1, "short write");
wtot += w;
}
}
fprintf(stderr, "lnc finished (wrote %zd)\n", wtot);
return 0;
}
static void usage()
{
fprintf(stderr, "usage:\n"
"%s [-M] [-c host] [-p port] [-l listen port]\n", __progname);
exit(-1);
}
static int con(uint32_t dip, uint16_t dport)
{
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
err(-1, "socket");
uint8_t a = dip >> 24;
uint8_t b = dip >> 16;
uint8_t c = dip >> 8;
uint8_t d = dip;
fprintf(stderr, "connecting to %d.%d.%d.%d:%d\n", a, b, c, d, dport);
struct sockaddr_in sin;
sin.sin_port = htons(dport);
sin.sin_addr.s_addr = htonl(dip);
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
err(-1, "connect");
return s;
}
static int lstn(uint16_t lport)
{
fprintf(stderr, "listen on port %d\n", (int)lport);
int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
err(-1, "socket");
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(lport);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1)
err(-1, "bind");
if (listen(s, 10) == -1)
err(-1, "listen");
int ret;
socklen_t slen = sizeof(sin);
if ((ret = accept(s, (struct sockaddr *)&sin, &slen)) == -1)
err(-1, "accept");
if (close(s))
err(-1, "close");
return ret;
}
int main(int argc, char **argv)
{
// bhw
uint32_t dip = 0x121a0530;
uint16_t dport = 31338;
uint16_t lport = 0;
int Mss = 0, usedp = 0;
int c;
while ((c = getopt(argc, argv, "Mp:c:l:")) != -1) {
switch (c) {
case 'M':
Mss = 1;
break;
case 'p':
dport = strtol(optarg, NULL, 0);
usedp = 1;
break;
case 'c': {
int a, b, c, d;
if (sscanf(optarg, "%d.%d.%d.%d", &a, &b, &c, &d) != 4)
errx(-1, "malformed IP (%s)", optarg);
dip = a << 24 | b << 16 | c << 8 | d;
break;
case 'l':
lport = (uint16_t)strtol(optarg, NULL, 0);
break;
}
default:
usage();
}
}
if (usedp && lport) {
fprintf(stderr, "-l and -p are mutually exclusive\n");
usage();
}
int s;
if (lport)
s = lstn(lport);
else
s = con(dip, dport);
fprintf(stderr ,"connected\n");
if (Mss)
return mss(s);
else
return nc(s);
}

@ -0,0 +1,116 @@
#include <litc.h>
void dprint(int fd, char *par, int left, int rec)
{
printf("%s/:\n", par);
char *pend = par + strlen(par);
snprintf(pend, left, "/");
left--;
pend = par + strlen(par);
DIR *dir = fdopendir(fd);
if (!dir)
err(-1, "fdopendir");
struct dirent des, *de;
int ret;
while (1) {
ret = readdir_r(dir, &des, &de);
if (ret)
errx(-1, "readdir_r %s", strerror(ret));
if (!de)
break;
int used = snprintf(pend, left, "%s", de->d_name);
if (used >= left)
errx(-1, "long filenames!");
char *fn = par;
struct stat st;
if (stat(fn, &st))
err(-1, "stat");
char spec;
if (S_ISDIR(st.st_mode))
spec = 'd';
else if (S_ISSOCK(st.st_mode))
spec = 's';
else
spec = '-';
printf("%crwxr-xr-x %ld %s\n", spec, st.st_size, de->d_name);
}
if (!rec) {
if (closedir(dir) == -1)
err(-1, "closedir");
return;
}
// recursive list
*pend = 0;
rewinddir(dir);
while (1) {
ret = readdir_r(dir, &des, &de);
if (ret)
errx(-1, "readdir_r %s", strerror(ret));
if (!de)
break;
char *tn = de->d_name;
if (strncmp(tn, "..", 3) == 0 ||
strncmp(tn, ".", 2) == 0)
continue;
snprintf(pend, left, "%s", tn);
char *fn = par;
struct stat st;
if (stat(fn, &st))
err(-1, "stat");
if (S_ISDIR(st.st_mode)) {
int tfd = open(fn, O_RDONLY | O_DIRECTORY, 0);
if (tfd < 0)
err(-1, "rec open");
dprint(tfd, par, left - strlen(pend), 1);
// dprint closes tfd
}
}
if (closedir(dir) == -1)
err(-1, "closedir");
}
__attribute__((noreturn))
void usage(void)
{
fprintf(stderr, "%s [-R]\n"
"-R recurse subdirectories\n"
"\n", __progname);
exit(-1);
}
int main(int argc, char **argv)
{
int rec = 0;
int ch;
while ((ch = getopt(argc, argv, "R")) != -1) {
switch (ch) {
case 'R':
rec = 1;
break;
default:
usage();
break;
}
}
char *start;
int rem = argc - optind;
if (rem == 0)
start = ".";
else if (rem == 1)
start = argv[optind];
else
usage();
int fd;
if ((fd = open(start, O_RDONLY | O_DIRECTORY, 0)) == -1)
err(-1, "open %s", start);
char pbuf[256];
strncpy(pbuf, start, sizeof(pbuf));
dprint(fd, pbuf, sizeof(pbuf) - strlen(pbuf), rec);
close(fd);
return 0;
}

@ -0,0 +1,208 @@
#include <litc.h>
void mkargs(char *line, char *args[], size_t n)
{
static char boof[1024];
int ai;
char *f = line;
char *bp = boof;
char *be = boof + sizeof(boof);
for (ai = 0; line && ai < n - 1; ai++) {
if (be - bp <= 0)
errx(-1, "no boof");
while (*line == ' ')
line++;
if (*line == 0)
break;
args[ai] = bp;
f = strstr(line, " ");
if (f)
*f++ = '\0';
strncpy(bp, line, be - bp);
bp += strlen(bp) + 1;
line = f;
}
args[ai] = NULL;
//for (ai = 0; args[ai] != NULL; ai++)
// printf("arg %d: %s\n", ai, args[ai]);
}
int builtins(char *args[], size_t n)
{
char *cmd = args[0];
if (strncmp(cmd, "cd", 3) == 0) {
int ret = chdir(args[1]);
if (ret)
printf("chdir to %s failed\n", args[1]);
return 1;
} else if (strncmp(cmd, "ps", 3) == 0) {
if (sys_info(SINFO_PROCLIST) == -1)
err(-1, "sys_info");
return 1;
}
return 0;
}
int removefn(char *line, char *retbuf, size_t retsz)
{
// gobble
while (*line == ' ')
line++;
if (!*line)
return -1;
// get filename end; either nul or space
char *end, *t;
end = strchr(line, ' ');
t = strchr(line, '\0');
if (!end)
end = t;
if (!end)
errx(-1, "how");
if (end - line + 1 > retsz)
errx(-1, "retbuffer too small");
while (line < end) {
*retbuf++ = *line;
*line++ = ' ';
}
*retbuf = '\0';
return 0;
}
int redir(char *line, char **infn, char **outfn, int *append)
{
static char inbuf[64];
static char outbuf[64];
*infn = *outfn = NULL;
*append = 0;
// remove all special tokens before grabbing filenames so that special
// tokens can separate filenames (i.e. "< file1>file2")
char *inp;
if ((inp = strchr(line, '<'))) {
if (strchr(inp + 1, '<')) {
printf("syntax error: two in redirects\n");
return -1;
}
*inp = ' ';
}
char *outp;
if ((outp = strstr(line, ">>"))) {
if (strchr(outp + 2, '>')) {
printf("syntax error: two out redirects\n");
return -1;
}
outp[0] = ' ';
outp[1] = ' ';
*append = 1;
} else if ((outp = strchr(line, '>'))) {
if (strchr(outp + 1, '>')) {
printf("syntax error: two out redirects\n");
return -1;
}
*outp = ' ';
}
if (inp) {
if (removefn(inp, inbuf, sizeof(inbuf))) {
printf("syntax error: no in redirect filename\n");
return -1;
}
*infn = inbuf;
}
if (outp) {
if (removefn(outp, outbuf, sizeof(outbuf))) {
printf("syntax error: no out redirect filename\n");
return -1;
}
*outfn = outbuf;
}
return 0;
}
void doredirs(char *infn, char *outfn, int append)
{
if (infn) {
int fd = open(infn, O_RDONLY);
if (fd < 0)
err(-1, "open in redirect");
if (dup2(fd, 0) < 0)
err(-1, "dup2");
close(fd);
}
if (outfn) {
int flags = O_WRONLY|O_CREAT;
if (append)
flags |= O_APPEND;
else
flags |= O_TRUNC;
int fd = open(outfn, flags);
if (fd < 0)
err(-1, "open out redirect");
if (dup2(fd, 1) < 0)
err(-1, "dup2");
close(fd);
}
}
int main(int argc, char **argv)
{
int nbgs = 0;
while (1) {
// if you change the output of lsh, you need to update
// posixtest() in usertests.c so the test is aware of the new
// changes.
char *args[64];
size_t sz = sizeof(args)/sizeof(args[0]);
char *infile, *outfile;
int append;
char *p = readline("# ");
if (p == NULL)
exit(0);
char *com;
if ((com = strchr(p, '#')))
*com = '\0';
int isbg = 0;
if ((com = strchr(p, '&'))) {
*com = ' ';
isbg = 1;
}
if (redir(p, &infile, &outfile, &append))
continue;
mkargs(p, args, sz);
if (args[0] == NULL)
continue;
if (builtins(args, sz))
continue;
int pid = fork();
if (pid < 0)
err(-1, "fork");
if (pid) {
if (isbg)
nbgs++;
else
while (wait(NULL) != pid)
;
continue;
}
// if background job, fork another child to check the commands
// exit code
int pid2;
if (isbg && (pid2 = fork()) != 0) {
printf("background pid %d\n", pid2);
int status;
wait(&status);
int st = WEXITSTATUS(status);
if (!WIFEXITED(status) || st != 0)
printf("background job %d failed with %d",
pid2, st);
else
printf("background job %d done\n", pid2);
exit(st);
}
doredirs(infile, outfile, append);
execvp(args[0], args);
err(-1, "couldn't exec \"%s\"", args[0]);
}
return 0;
}

@ -0,0 +1,12 @@
#include <litc.h>
int main(int argc, char **argv)
{
if (argc != 2)
errx(-1, "usage: %s <file>\n", argv[0]);
int ret = mkdir(argv[1], 0);
if (ret)
err(ret, "mkdir");
return 0;
}

@ -0,0 +1,19 @@
#include <litc.h>
int main(int argc, char **argv)
{
int ret;
if ((ret = mknod("/tmp/flea", 10, MKDEV(10, 0))) < 0)
err(ret, "mknod");
int fd = open("/tmp/flea", O_RDWR, 0);
if (fd < 0)
err(fd, "open");
char buf[512];
if ((ret = read(fd, buf, sizeof(buf))) < 0)
err(ret, "read");
close(fd);
return 0;
}

@ -0,0 +1,41 @@
#include <litc.h>
static long
nowms(void)
{
struct timeval tv;
if (gettimeofday(&tv, NULL))
errx(-1, "nowms");
return tv.tv_sec*1000 + tv.tv_usec/1000;
}
#define SZ (1 << 22)
#define N 1024
int main(int argc, char **argv)
{
printf("mmapbench\n");
const size_t sz = SZ;
long tot = 0;
for (int i = 0 ; i < N; i++) {
char *p = mmap(NULL, sz, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED)
errx(-1, "mmap failed");
long st = nowms();
for (int j = 0; j < sz; j += 4096) {
p[j] = 0xcc;
}
tot += nowms() - st;
if (munmap(p, sz) != 0)
errx(-1, "munmap failed");
}
printf("mmapbench %ld pgfaults in %ld ms\n", (long) (SZ/4096) * N, tot);
return 0;
}

@ -0,0 +1,35 @@
#include <litc.h>
char *ps[1000];
int main(int argc, char **argv)
{
int times;
for (times = 0; times < 10; times++) {
const size_t sz = 1 << 13;
char *p = mmap(NULL, sz, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED)
errx(-1, "mmap");
int i;
for (i = 0; i < sz; i++)
p[i] = 0xcc;
int ret;
if ((ret = munmap(p, sz)) < 0)
err(ret, "munmap");
}
for (times = 0; times < 10; times++) {
int iters = sizeof(ps)/sizeof(ps[0]);
int i;
for (i = 0; i < iters; i++)
ps[i] = malloc(30);
for (i = 0; i < iters; i++)
free(ps[i]);
}
printf("success\n");
return 0;
}

@ -0,0 +1,15 @@
#include <litc.h>
int main(int argc, char **argv)
{
if (argc != 3)
errx(-1, "%s <old filename> <new filename>\n", argv[0]);
char *old = argv[1];
char *new = argv[2];
int ret;
if ((ret = rename(old, new)) < 0)
err(ret, "rename");
return 0;
}

@ -0,0 +1,69 @@
#include <litc.h>
int main(int argc, char **argv)
{
int pfds[2];
int ret = pipe(pfds);
char *msg1 = "hello, sonny!";
char *msg2 = "hello, laddy!";
const int msglen = strlen(msg1) + 1;
if (ret < 0)
err(ret, "pipe");
printf("pipe fds: %d %d\n", pfds[0], pfds[1]);
int child = 0;
int status;
int pid1 = fork();
int pid2 = fork();
if (pid1 == 0)
child = 1;
if (child) {
close(pfds[1]);
char buf[msglen];
ret = read(pfds[0], buf, sizeof(buf));
if (ret < 0)
err(ret, "read");
printf("got: %s\n", buf);
if (ret != msglen)
errx(-1, "only read %d of %d bytes\n", ret, msglen);
if (pid2 != 0) {
if ((ret = wait(&status)) < 0)
err(ret, "wait1");
if (WEXITSTATUS(status) != 0)
errx(status, "child child failed %d", status);
}
return 0;
}
close(pfds[0]);
char *msg = (pid2 == 0) ? msg1 : msg2;
printf("sending: %s\n", msg);
ret = write(pfds[1], msg, msglen);
printf("sent\n");
if (ret < 0)
err(ret, "write");
if (ret != msglen)
errx(-1, "only wrote %d of %d bytes\n", ret, msglen);
if (pid2 == 0)
return 0;
if ((ret = wait(&status)) < 0)
err(ret, "wait2");
if (WEXITSTATUS(status) != 0)
err(status, "parent child failed %d", status);
if ((ret = wait(&status)) < 0)
err(ret, "wait3");
if (WEXITSTATUS(status) != 0)
err(status, "parent child2 failed %d", status);
// try write on pipe with no readers
if ((ret = write(pfds[1], "fail", 4) >= 0))
errx(-1, "write should have failed %d", ret);
printf("success\n");
return 0;
}

@ -0,0 +1,146 @@
#include <litc.h>
__thread int id;
int nthreads;
int count;
void barrier_init()
{
count = 0;
}
void barrier()
{
// barrier
for (;;) {
int oc = count;
int nc = oc + 1;
if (__sync_bool_compare_and_swap(&count, oc, nc))
break;
}
int volatile *p = &count;
while (*p != nthreads)
;
}
void *fn(void *a)
{
int b = (int)(long)a;
id = b;
// barrier
barrier();
printf("my id is still: %d (%d)\n", id, b);
if (id != b)
errx(-1, "TLS fyuked!");
return NULL;
}
static long volatile go __attribute__((aligned(4096)));
static int blah __attribute__((aligned(4096)));
void *groupfault(void *a)
{
int b = (int)(long)a;
while (!go)
asm volatile("pause");
blah = b;
return NULL;
}
static int volatile observe __attribute__((aligned(4096))) = 10;
void acquire(void)
{
while (__sync_lock_test_and_set(&go, 1) != 0)
;
}
void release(void)
{
go = 0;
}
void *tlbinval(void *a)
{
acquire();
if (observe != 0x31337)
errx(-1, "didn't get tlb invalidate: %d", observe);
release();
return NULL;
}
void joinall(pthread_t t[])
{
int i;
for (i = 0; i < nthreads; i++) {
void *ret;
if (pthread_join(t[i], &ret))
errx(-1, "pthread join");
if (ret)
errx(-1, "bad exit");
}
}
int main(int argc, char **argv)
{
if (argc > 1)
nthreads = atoi(argv[1]);
if (nthreads <= 0)
nthreads = 3;
barrier_init();
printf("making %d threads\n", nthreads);
pthread_t t[nthreads];
int i;
for (i = 0; i < nthreads; i++)
if (pthread_create(&t[i], NULL, fn, (void *)(long)i))
errx(-1, "pthread create");
printf("started\n");
joinall(t);
printf("joined. doing group fault...\n");
// test simultaneous faults
for (i = 0; i < nthreads; i++)
if (pthread_create(&t[i], NULL, groupfault, (void *)(long)i))
errx(-1, "pthread create");
sleep(1);
printf("fork\n");
// make address space copy-on-write by forking
pid_t c = fork();
if (c == -1)
err(-1, "fork");
else if (c == 0)
return 0;
go = 1;
joinall(t);
go = 0;
printf("testing TLB shootdowns...\n");
// test TLB shootdowns
acquire();
for (i = 0; i < nthreads; i++)
if (pthread_create(&t[i], NULL, tlbinval, NULL))
errx(-1, "pthread create");
observe = 0x31337;
release();
joinall(t);
printf("success\n");
return 0;
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save