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…
Reference in new issue