Last active
February 27, 2023 23:22
-
-
Save tlively/fb2f2522bf80a6d73e0eed8cd83337f7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <fcntl.h> | |
#include <pthread.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <time.h> | |
#include <unistd.h> | |
#include <errno.h> | |
#include <string.h> | |
#ifdef __EMSCRIPTEN__ | |
#include <emscripten/wasmfs.h> | |
#endif | |
#define ITERATIONS 10000 | |
#define WARMUP_RUNS 5 | |
_Atomic int nready = 0; | |
_Atomic int start = 0; | |
_Atomic int iterations = 0; | |
void do_work(int fd) { | |
#ifndef NULLFS | |
struct stat stat_buf; | |
int err = fstat(fd, &stat_buf); | |
assert(err == 0 && stat_buf.st_size == 0); | |
#endif | |
} | |
void* run_thread(void* arg) { | |
int id = (int)arg; | |
char path[3] = {}; | |
int path_len = snprintf(path, sizeof(path), "%d", id); | |
assert(path_len > 0 && path_len < sizeof(path)); | |
// Open file | |
int fd = creat(path, 0777); | |
if (fd < 0) { | |
abort(); | |
} | |
nready++; | |
// Wait for start | |
while (start == 0) {} | |
// Go go go! | |
while (iterations++ < ITERATIONS) { | |
do_work(fd); | |
} | |
// Finish | |
close(fd); | |
return NULL; | |
} | |
void benchmark(int nthreads, int nruns) { | |
int64_t cumulative_nanos = 0; | |
printf("Running %d runs with %d threads\n", nruns, nthreads); | |
for (int run = 0; run < nruns + WARMUP_RUNS; run++) { | |
printf("Run %d: ", run - WARMUP_RUNS); | |
if (run < WARMUP_RUNS) { | |
printf("\n"); | |
} | |
pthread_t threads[nthreads]; | |
struct timespec start_time, end_time; | |
// Start threads | |
nready = start = iterations = 0; | |
for (int i = 0; i < nthreads; ++i) { | |
if (pthread_create(&threads[i], NULL, run_thread, (void*)i) != 0) { | |
abort(); | |
} | |
} | |
// Wait for all threads to be ready. | |
while (nready < nthreads) {} | |
// Start | |
clock_gettime(CLOCK_REALTIME, &start_time); | |
start = 1; | |
// End | |
while (iterations < ITERATIONS) {} | |
clock_gettime(CLOCK_REALTIME, &end_time); | |
// Join threads | |
for (int i = 0; i < nthreads; ++i) { | |
pthread_join(threads[i], NULL); | |
} | |
if (run >= WARMUP_RUNS) { | |
// Report the time. | |
int64_t nanos = | |
(int64_t)(end_time.tv_sec - start_time.tv_sec) * 1000000000ll + | |
(end_time.tv_nsec - start_time.tv_nsec); | |
printf("%f ms\n", (double)nanos / 1000000); | |
cumulative_nanos += nanos; | |
} | |
} | |
printf("%d threads: %f ms\n", | |
nthreads, | |
(double)cumulative_nanos / (nruns * 1000000)); | |
} | |
#ifdef PROXYFS | |
backend_t make_mem_backend(void* arg) { | |
return wasmfs_create_memory_backend(); | |
} | |
#endif | |
int main() { | |
#if defined(__EMSCRIPTEN__) && !defined(NULLFS) | |
#ifdef MEMFS | |
backend_t backend = wasmfs_get_backend_by_path("/"); | |
#else | |
#ifdef JSFS | |
backend_t backend = wasmfs_create_js_file_backend(); | |
#else | |
#ifdef NODEFS | |
backend_t backend = wasmfs_create_node_backend("."); | |
#else | |
#ifdef OPFS | |
backend_t backend = wasmfs_create_opfs_backend(); | |
#else | |
#ifdef PROXYFS | |
backend_t backend = wasmfs_create_proxied_backend(make_mem_backend, NULL); | |
#endif | |
#endif | |
#endif | |
#endif | |
#endif | |
int err = wasmfs_create_directory("working", 0777, backend); | |
assert(err == 0); | |
err = chdir("working"); | |
assert(err == 0); | |
#endif | |
// TODO: set up WasmFS backend, etc. | |
for (int nthreads = 1; nthreads <= 16; nthreads <<= 1) { | |
benchmark(nthreads, 10); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment