From 6fd06387b39fed6d6854cd8fdd2501b0c06d7650 Mon Sep 17 00:00:00 2001 From: Znort 987 Date: Mon, 15 Aug 2011 12:02:34 +0200 Subject: [PATCH] On unix, make algo benchmark more generic --- main.c | 102 +++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index 78e53722..b44ce25b 100644 --- a/main.c +++ b/main.c @@ -480,78 +480,118 @@ static double bench_algo_stage2( enum sha256_algos algo ) { - #if defined(__linux) - // Make a shared+anonymous mmap - const size_t map_size = 4096; - void *map = mmap( - (void*)NULL, - map_size, - PROT_READ | - PROT_WRITE, - MAP_SHARED | - MAP_ANONYMOUS, - -1, - 0 - ); - if ((void*)-1 == map) { - perror("bench algo, mmap failed"); + // Here, the gig is to safely run a piece of code that potentially + // crashes. Unfortunately, the Right Way (tm) to do this is rather + // heavily platform dependent :( + + double rate = -1.23457; + + #if defined(unix) + + // Make a pipe: [readFD, writeFD] + int pfd[2]; + int r = pipe(pfd); + if (r<0) { + perror("pipe - failed to create pipe for --algo auto"); exit(1); } - // Load a canary rate in the map - double rate = -1.23457; - memcpy(map, &rate, sizeof(rate)); + // Make pipe non blocking + set_non_blocking(pfd[0], 1); + set_non_blocking(pfd[1], 1); + + // Don't allow a crashing child to kill the main process + sighandler_t sr0 = signal(SIGPIPE, SIG_IGN); + sighandler_t sr1 = signal(SIGPIPE, SIG_IGN); + if (SIG_ERR==sr0 || SIG_ERR==sr1) { + perror("signal - failed to edit signal mask for --algo auto"); + exit(1); + } // Fork a child to do the actual benchmarking pid_t child_pid = fork(); + if (child_pid<0) { + perror("fork - failed to create a child process for --algo auto"); + exit(1); + } + + // Do the dangerous work in the child, knowing we might crash if (0==child_pid) { - // Do the dangerous work in the child + // TODO: some umask trickery to prevent coredumps + + // Benchmark this algorithm double r = bench_algo_stage3(algo); - // Load result in shared map and bail - memcpy(map, &r, sizeof(r)); + // We survived, send result to parent and bail + int loop_count = 0; + while (1) { + ssize_t bytes_written = write(pfd[1], &r, sizeof(r)); + int try_again = (0==bytes_written || (bytes_written<0 && EAGAIN==errno)); + int success = (sizeof(r)==(size_t)bytes_written); + + if (success) + break; + + if (!try_again) { + perror("write - child failed to write benchmark result to pipe"); + exit(1); + } + + if (5