From ebfe5c88da4403cd45ea27c2189957ad7362feae Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Sat, 13 Jan 2024 19:15:35 -0700 Subject: [PATCH 1/4] Add fork_func.{c,h} --- liball/Makefile.BSD | 1 + util/fork_func.c | 77 +++++++++++++++++++++++++++++++++++++++++++++ util/fork_func.h | 19 +++++++++++ 3 files changed, 97 insertions(+) create mode 100644 util/fork_func.c create mode 100644 util/fork_func.h diff --git a/liball/Makefile.BSD b/liball/Makefile.BSD index 117ddad6..426d289d 100644 --- a/liball/Makefile.BSD +++ b/liball/Makefile.BSD @@ -102,6 +102,7 @@ SRCS += asprintf.c SRCS += b64encode.c SRCS += daemonize.c SRCS += entropy.c +SRCS += fork_func.c SRCS += getopt.c SRCS += hexify.c SRCS += humansize.c diff --git a/util/fork_func.c b/util/fork_func.c new file mode 100644 index 00000000..77d7bd1c --- /dev/null +++ b/util/fork_func.c @@ -0,0 +1,77 @@ +#include + +#include +#include + +#include "warnp.h" + +#include "fork_func.h" + +/** + * fork_func(func, cookie): + * Fork and run ${func} in a new process, with ${cookie} as the sole argument. + */ +pid_t +fork_func(int (* func)(void *), void * cookie) +{ + pid_t pid; + + /* Fork */ + switch (pid = fork()) { + case -1: + /* Error in fork system call. */ + warnp("fork"); + goto err0; + case 0: + /* In child process: Run the provided function, then exit. */ + _exit(func(cookie)); + default: + /* In parent process: do nothing else. */ + break; + } + + /* Success! */ + return (pid); + +err0: + /* Failure! */ + return (-1); +} + +/** + * fork_func_wait(pid): + * Wait for the process ${pid} to finish. Print any error arising from ${pid}. + * If ${pid} exited cleanly, return its exit code; otherwise, return -1. + */ +int +fork_func_wait(pid_t pid) +{ + int status; + int rc = -1; + + /* Wait for the process to finish. */ + if (waitpid(pid, &status, 0) == -1) { + warnp("waitpid"); + goto err0; + } + + /* Print the error status, if applicable. */ + if (WIFEXITED(status)) { + /* Child ${pid} exited cleanly. */ + rc = WEXITSTATUS(status); + } else { + /* + * Child ${pid} did not exit cleanly; warn about the reason + * for the unclean exit. + */ + if (WIFSIGNALED(status)) + warn0("pid %jd: terminated with signal %d", + (intmax_t)pid, WTERMSIG(status)); + else + warn0("pid %jd: exited for an unknown reason"); + } + +err0: + /* Done! */ + return (rc); +} diff --git a/util/fork_func.h b/util/fork_func.h new file mode 100644 index 00000000..5440a7e8 --- /dev/null +++ b/util/fork_func.h @@ -0,0 +1,19 @@ +#ifndef FORK_FUNC_H_ +#define FORK_FUNC_H_ + +#include + +/** + * fork_func(func, cookie): + * Fork and run ${func} in a new process, with ${cookie} as the sole argument. + */ +pid_t fork_func(int (*)(void *), void *); + +/** + * fork_func_wait(pid): + * Wait for the process ${pid} to finish. Print any error arising from ${pid}. + * If ${pid} exited cleanly, return its exit code; otherwise, return -1. + */ +int fork_func_wait(pid_t); + +#endif /* !FORK_FUNC_H_ */ From 19efda2fc3a303d1888468722ad526ba88e69ca4 Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Sat, 13 Jan 2024 19:15:36 -0700 Subject: [PATCH 2/4] tests: add fork_func --- .gitignore | 1 + Makefile | 1 + Makefile.BSD | 1 + tests/24-fork-func.sh | 37 +++++ tests/fork_func/Makefile.BSD | 23 +++ tests/fork_func/check.h | 28 ++++ tests/fork_func/check_exec.c | 45 ++++++ tests/fork_func/check_exit.c | 45 ++++++ tests/fork_func/check_order.c | 103 ++++++++++++ tests/fork_func/check_order_spawning.good | 5 + tests/fork_func/check_order_waited.good | 5 + tests/fork_func/check_perftest.c | 181 ++++++++++++++++++++++ tests/fork_func/main.c | 124 +++++++++++++++ 13 files changed, 599 insertions(+) create mode 100644 tests/24-fork-func.sh create mode 100644 tests/fork_func/Makefile.BSD create mode 100644 tests/fork_func/check.h create mode 100644 tests/fork_func/check_exec.c create mode 100644 tests/fork_func/check_exit.c create mode 100644 tests/fork_func/check_order.c create mode 100644 tests/fork_func/check_order_spawning.good create mode 100644 tests/fork_func/check_order_waited.good create mode 100644 tests/fork_func/check_perftest.c create mode 100644 tests/fork_func/main.c diff --git a/.gitignore b/.gitignore index bbfabe01..788963a8 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ /tests/daemonize/test_daemonize /tests/elasticarray/test_elasticarray /tests/events/test_events +/tests/fork_func/test_fork_func /tests/getopt-longjmp/test_getopt_longjmp /tests/getopt/test_getopt /tests/heap/test_heap diff --git a/Makefile b/Makefile index be7987d3..b376aa50 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ TESTS= perftests/http \ tests/daemonize \ tests/elasticarray \ tests/events \ + tests/fork_func \ tests/getopt \ tests/getopt-longjmp \ tests/heap \ diff --git a/Makefile.BSD b/Makefile.BSD index e8e3fb6c..a1876f0a 100644 --- a/Makefile.BSD +++ b/Makefile.BSD @@ -17,6 +17,7 @@ TESTS= perftests/http \ tests/daemonize \ tests/elasticarray \ tests/events \ + tests/fork_func \ tests/getopt \ tests/getopt-longjmp \ tests/heap \ diff --git a/tests/24-fork-func.sh b/tests/24-fork-func.sh new file mode 100644 index 00000000..d0cbd0d8 --- /dev/null +++ b/tests/24-fork-func.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +### Constants +c_valgrind_min=1 +spawning="${s_basename}-spawning.txt" +waited="${s_basename}-waited.txt" + +### Actual command +scenario_cmd() { + cd "${scriptdir}/fork_func" || exit + + setup_check "test_fork_func -x" + # Special handling for multiple forks. + c_valgrind_cmd=$(valgrind_setup "valgrind-parent") + ${c_valgrind_cmd} ./test_fork_func -x + echo "$?" > "${c_exitfile}" + + setup_check "test_fork_func -e" + # Special handling for multiple forks. + c_valgrind_cmd=$(valgrind_setup "valgrind-parent") + ${c_valgrind_cmd} ./test_fork_func -e + echo "$?" > "${c_exitfile}" + + setup_check "test_fork_func -c" + # Special handling for multiple forks. + c_valgrind_cmd=$(valgrind_setup "valgrind-parent") + ${c_valgrind_cmd} ./test_fork_func -c >"${spawning}" 2>"${waited}" + echo "$?" > "${c_exitfile}" + + setup_check "test_fork_func -c spawning" + cmp "${spawning}" "${scriptdir}/fork_func/check_order_spawning.good" + echo "$?" > "${c_exitfile}" + + setup_check "test_fork_func -c waited" + cmp "${waited}" "${scriptdir}/fork_func/check_order_waited.good" + echo "$?" > "${c_exitfile}" +} diff --git a/tests/fork_func/Makefile.BSD b/tests/fork_func/Makefile.BSD new file mode 100644 index 00000000..204e2cfb --- /dev/null +++ b/tests/fork_func/Makefile.BSD @@ -0,0 +1,23 @@ +# Program name. +PROG = test_fork_func + +# Don't install it. +NOINST = 1 + +# Library code required +LDADD_REQ = -lpthread + +# Useful relative directories +LIBCPERCIVA_DIR = ../.. + +# Main test code +SRCS = main.c +SRCS += check_exec.c +SRCS += check_exit.c +SRCS += check_order.c +SRCS += check_perftest.c + +# libcperciva includes +IDIRS += -I${LIBCPERCIVA_DIR}/util + +.include diff --git a/tests/fork_func/check.h b/tests/fork_func/check.h new file mode 100644 index 00000000..ac8df5d3 --- /dev/null +++ b/tests/fork_func/check.h @@ -0,0 +1,28 @@ +#ifndef CHECK_H_ +#define CHECK_H_ + +/** + * check_exit(void): + * Check that fork_func() works with exit codes. + */ +int check_exit(void); + +/** + * check_exec(void): + * Check that fork_func() works with an exec* function. + */ +int check_exec(void); + +/** + * check_order(void): + * Check that fork_func() doesn't impose any order on multiple functions. + */ +int check_order(void); + +/** + * check_perftest(void): + * Check the amount of delay added by func_fork() and func_fork_wait(). + */ +int check_perftest(int child_ms, int num_reps); + +#endif /* !CHECK_H_ */ diff --git a/tests/fork_func/check_exec.c b/tests/fork_func/check_exec.c new file mode 100644 index 00000000..037d387a --- /dev/null +++ b/tests/fork_func/check_exec.c @@ -0,0 +1,45 @@ +#include + +#include "fork_func.h" +#include "warnp.h" + +#include "check.h" + +static int +func_exec(void * cookie) +{ + + (void)cookie; /* UNUSED */ + + /* Execute the "true" binary found in the $PATH. */ + if (execlp("true", "true", NULL)) + warnp("execvp"); + + /* We should never reach this. */ + return (127); +} + +/** + * check_exec(void): + * Check that fork_func() works with an exec* function. + */ +int +check_exec(void) +{ + pid_t pid; + + /* Fork. */ + if ((pid = fork_func(func_exec, NULL) == -1)) + goto err0; + + /* Check that it didn't fail. */ + if (fork_func_wait(pid) != 0) + goto err0; + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} diff --git a/tests/fork_func/check_exit.c b/tests/fork_func/check_exit.c new file mode 100644 index 00000000..f8d9994a --- /dev/null +++ b/tests/fork_func/check_exit.c @@ -0,0 +1,45 @@ +#include + +#include "fork_func.h" + +#include "check.h" + +static int +func_exit(void * cookie) +{ + int * exitcode_p = (int *)cookie; + + /* Return the specified exit code. */ + return (*exitcode_p); +} + +/** + * check_exit(void): + * Check that fork_func() works with exit codes. + */ +int +check_exit(void) +{ + pid_t pid; + int i; + int rc; + + for (i = 0; i < 4; i++) { + /* Fork. */ + if ((pid = fork_func(func_exit, &i)) == -1) + goto err0; + + /* Check the result. */ + if ((rc = fork_func_wait(pid)) == -1) + goto err0; + if (rc != i) + goto err0; + } + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} diff --git a/tests/fork_func/check_order.c b/tests/fork_func/check_order.c new file mode 100644 index 00000000..b20cfc22 --- /dev/null +++ b/tests/fork_func/check_order.c @@ -0,0 +1,103 @@ +#include + +#include + +#include "fork_func.h" +#include "millisleep.h" +#include "warnp.h" + +#include "check.h" + +/** + * Do a "sleep sort". This isn't guaranteed to sort successfully, but it's + * very unlikely that any processes will be delayed by enough for it to fail. + * + * We want to output two different lists: the "spawning" messages, and the + * "waited" messages. This allows the test to be more resistant to systems + * having different overheads for fork(). + * + * To achieve this, the "spawning" messages go to stdout, while the "waited" + * messages go to stderr. + */ + +#define NUM_PROCESSES 5 +static int SLEEP_SORT_MS[5] = {200, 800, 0, 600, 400}; + +/* Wait X milliseconds, then print to stderr. */ +static int +sleep_print_func(void * cookie) +{ + int ms = *((int *)cookie); + + /* Wait. */ + millisleep((size_t)ms); + + /* Write the "waited" messages to stderr. */ + if (fprintf(stderr, "waited %i ms\n", ms) < 0) { + warnp("fprintf"); + goto err0; + } + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} + +/** + * check_order(void): + * Check that fork_func() doesn't impose any order on multiple functions. + */ +int +check_order(void) +{ + pid_t pids[NUM_PROCESSES]; + int i; + + /*- + * We want to output two different lists: the "spawning" + * messages, and the "waited" messages. This allows the test + * to be more resistant to systems having different overheads + * for fork(). + * + * To achieve this, the "spawning" messages go to stdout, + * while the "waited" messages go to stderr. + */ + + /* Write the "spawning" messages to stdout. */ + for (i = 0; i < NUM_PROCESSES; i++) { + if (fprintf(stdout, "spawning a process to wait %i ms\n", + SLEEP_SORT_MS[i]) < 0) { + warnp("fprintf"); + goto err0; + } + } + + /* Flush stdout so that its buffer isn't duplicated in the forks. */ + if (fflush(stdout)) { + warnp("fflush"); + goto err0; + } + + /* Spawn the processes. */ + for (i = 0; i < NUM_PROCESSES; i++) { + if ((pids[i] = fork_func(sleep_print_func, + &SLEEP_SORT_MS[i])) == -1) + goto err0; + } + + /* Wait for the processes to finish. */ + for (i = 0; i < NUM_PROCESSES; i++) { + if (fork_func_wait(pids[i])) + goto err0; + } + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} diff --git a/tests/fork_func/check_order_spawning.good b/tests/fork_func/check_order_spawning.good new file mode 100644 index 00000000..4f44fe26 --- /dev/null +++ b/tests/fork_func/check_order_spawning.good @@ -0,0 +1,5 @@ +spawning a process to wait 200 ms +spawning a process to wait 800 ms +spawning a process to wait 0 ms +spawning a process to wait 600 ms +spawning a process to wait 400 ms diff --git a/tests/fork_func/check_order_waited.good b/tests/fork_func/check_order_waited.good new file mode 100644 index 00000000..429fe24f --- /dev/null +++ b/tests/fork_func/check_order_waited.good @@ -0,0 +1,5 @@ +waited 0 ms +waited 200 ms +waited 400 ms +waited 600 ms +waited 800 ms diff --git a/tests/fork_func/check_perftest.c b/tests/fork_func/check_perftest.c new file mode 100644 index 00000000..73f19670 --- /dev/null +++ b/tests/fork_func/check_perftest.c @@ -0,0 +1,181 @@ +#include + +#include + +#include +#include + +#include "fork_func.h" +#include "millisleep.h" +#include "monoclock.h" +#include "warnp.h" + +#include "check.h" + +/* Wait X milliseconds. */ +static int +millisleep_func(void * cookie) +{ + int ms = *((int *)cookie); + + /* Wait. */ + millisleep((size_t)ms); + + /* Success! */ + return (0); +} + +static void * +millisleep_func_pthread(void * cookie) +{ + int ms = *((int *)cookie); + + /* Wait. */ + millisleep((size_t)ms); + + return (NULL); +} + +static inline void +print_timediff(int type, struct timeval tv_orig, struct timeval tv_now, int ms) +{ + + printf("%i\t%.4f\n", type, + 1000.0 * timeval_diff(tv_orig, tv_now) - (double)ms); +} + +static int +benchmark_only_millisleep(int ms) +{ + struct timeval tv_orig, tv_now; + + /* Get the original time. */ + if (monoclock_get(&tv_orig)) { + warnp("monoclock_get"); + goto err0; + } + + /* Wait. */ + millisleep_func(&ms); + + /* Get the current time, and print the difference. */ + if (monoclock_get(&tv_now)) { + warnp("monoclock_get"); + goto err0; + } + print_timediff(0, tv_orig, tv_now, ms); + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} + +static int +benchmark_pthread_millisleep(int ms) +{ + struct timeval tv_orig, tv_now; + pthread_t thr; + + /* Get the original time. */ + if (monoclock_get(&tv_orig)) { + warnp("monoclock_get"); + goto err0; + } + + /* Create a new thread and wait for it to finish. */ + if (pthread_create(&thr, NULL, millisleep_func_pthread, &ms)) { + warn0("pthread"); + goto err0; + } + if (pthread_join(thr, NULL)) { + warn0("pthread_join"); + goto err0; + } + + /* Get the current time, and print the difference. */ + if (monoclock_get(&tv_now)) { + warnp("monoclock_get"); + goto err0; + } + print_timediff(1, tv_orig, tv_now, ms); + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} + +static int +benchmark_fork_func_millisleep(int ms) +{ + struct timeval tv_orig, tv_now; + pid_t pid; + + /* Get the original time. */ + if (monoclock_get(&tv_orig)) { + warnp("monoclock_get"); + goto err0; + } + + /* Create a new process, and wait for it to finish. */ + if ((pid = fork_func(millisleep_func, &ms)) == -1) { + warn0("fork_func"); + goto err0; + } + if (fork_func_wait(pid)) + goto err0; + + /* Get the current time, and print the difference. */ + if (monoclock_get(&tv_now)) { + warnp("monoclock_get"); + goto err0; + } + print_timediff(2, tv_orig, tv_now, ms); + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} + +/** + * check_perftest(void): + * Check the amount of delay added by func_fork() and func_fork_wait(). + */ +int +check_perftest(int child_ms, int num_reps) +{ + int i; + + /* Explain columns. */ + printf("# type\textra_delay\n"); + + /* Baseline: time the delay without any threads or processes. */ + for (i = 0; i < num_reps; i++) + if (benchmark_only_millisleep(child_ms)) + goto err0; + + /* Time the delay with pthread. */ + for (i = 0; i < num_reps; i++) + if (benchmark_pthread_millisleep(child_ms)) + goto err0; + + /* Time the delay with fork_func. */ + for (i = 0; i < num_reps; i++) + if (benchmark_fork_func_millisleep(child_ms)) + goto err0; + + /* Success! */ + return (0); + +err0: + /* Failure! */ + return (-1); +} diff --git a/tests/fork_func/main.c b/tests/fork_func/main.c new file mode 100644 index 00000000..3745c3e1 --- /dev/null +++ b/tests/fork_func/main.c @@ -0,0 +1,124 @@ +#include +#include + +#include "getopt.h" +#include "parsenum.h" +#include "warnp.h" + +#include "check.h" + +enum modes { + UNSET, + CHECK_ORDER, + CHECK_EXEC, + CHECK_EXIT, + PERFTEST +}; + +static void +usage(void) +{ + + fprintf(stderr, "usage: test_fork_func [-c|-e|-x]\n"); + fprintf(stderr, " test_fork_func -t -d CHILD_MS -n NUM_REPS\n"); + exit(1); +} + +int +main(int argc, char ** argv) +{ + int child_ms = -1; + int num_reps = -1; + const char * ch; + enum modes mode = UNSET; + + WARNP_INIT; + + /* Process arguments. */ + while ((ch = GETOPT(argc, argv)) != NULL) { + GETOPT_SWITCH(ch) { + GETOPT_OPT("-c"): + mode = CHECK_ORDER; + break; + GETOPT_OPTARG("-d"): + if (PARSENUM(&child_ms, optarg, 0, 10000)) { + warnp("parsenum"); + goto err0; + } + break; + GETOPT_OPT("-e"): + mode = CHECK_EXEC; + break; + GETOPT_OPTARG("-n"): + if (PARSENUM(&num_reps, optarg, 0, 10000)) { + warnp("parsenum"); + goto err0; + } + break; + GETOPT_OPT("-t"): + mode = PERFTEST; + break; + GETOPT_OPT("-x"): + mode = CHECK_EXIT; + break; + GETOPT_DEFAULT: + usage(); + } + } + argc -= optind; + argv += optind; + + /* We should have processed all the arguments. */ + if (argc != 0) + usage(); + (void)argv; /* argv is not used beyond this point. */ + + /* Run test. */ + switch (mode) { + case CHECK_ORDER: + /* Sanity test. */ + if ((child_ms != -1) || (num_reps != -1)) + usage(); + + /* Run check. */ + if (check_order()) + goto err0; + break; + case CHECK_EXEC: + /* Sanity test. */ + if ((child_ms != -1) || (num_reps != -1)) + usage(); + + /* Run check. */ + if (check_exec()) + goto err0; + break; + case CHECK_EXIT: + /* Sanity test. */ + if ((child_ms != -1) || (num_reps != -1)) + usage(); + + /* Run check. */ + if (check_exit()) + goto err0; + break; + case PERFTEST: + /* Sanity test. */ + if ((child_ms == -1) || (num_reps == -1)) + usage(); + + /* Run perftest. */ + if (check_perftest(child_ms, num_reps)) + goto err0; + break; + case UNSET: + usage(); + } + + /* Success! */ + exit(0); + +err0: + /* Failure! */ + exit(1); +} From 7a8aa0fa1648707abf5e3b8551e97ab8da172789 Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Sat, 13 Jan 2024 19:15:37 -0700 Subject: [PATCH 3/4] tests: add perftest for fork_func --- tests/fork_func/fork-perftest.plot | 35 ++++++++++++++++++++++++++ tests/fork_func/fork-perftest.sh | 14 +++++++++++ tests/fork_func/freebsd-begin-tests.sh | 7 ++++++ tests/fork_func/freebsd-end-tests.sh | 9 +++++++ 4 files changed, 65 insertions(+) create mode 100644 tests/fork_func/fork-perftest.plot create mode 100755 tests/fork_func/fork-perftest.sh create mode 100755 tests/fork_func/freebsd-begin-tests.sh create mode 100755 tests/fork_func/freebsd-end-tests.sh diff --git a/tests/fork_func/fork-perftest.plot b/tests/fork_func/fork-perftest.plot new file mode 100644 index 00000000..fcb41385 --- /dev/null +++ b/tests/fork_func/fork-perftest.plot @@ -0,0 +1,35 @@ +# Run with: +# gnuplot -c fork-perftest.plot + +list = "0 1 30 90" +YMIN = -0.05 +YMAX = 1.0 + +set style data boxplot +set ylabel "extra delay ms" +set xlabel "type of operation" +set key left + +set xtics ("no multi" 0, "pthread" 1, "fork\\\_func" 2) +set xrange [-1:3] +set yrange [YMIN:YMAX] + +# Sanity check for YMAX. +do for [i in list] { + stats "perftest-".i.".txt" using 2 prefix "S" nooutput + if (S_max > YMAX) { + print "Y max too small: ", S_max, YMAX + exit 1 + } +} + +# Do the actual plotting. +do for [i in list] { + set title "Extra delay when waiting ".i." ms" + + plot "perftest-".i.'-0.txt' title "no multi" + replot "perftest-".i.'-1.txt' title "pthread" + replot "perftest-".i.'-2.txt' title "fork\\\_func" + + pause -1 +} diff --git a/tests/fork_func/fork-perftest.sh b/tests/fork_func/fork-perftest.sh new file mode 100755 index 00000000..1d726549 --- /dev/null +++ b/tests/fork_func/fork-perftest.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +NUM_REPS=31 +LIST="0 1 30 90" + +for sec in ${LIST}; do + ./test_fork_func -t -d "${sec}" -n "${NUM_REPS}" > "perftest-${sec}.txt" +done + +for sec in ${LIST}; do + for n in 0 1 2; do + grep "^${n}" "perftest-${sec}.txt" > "perftest-${sec}-${n}.txt" + done +done diff --git a/tests/fork_func/freebsd-begin-tests.sh b/tests/fork_func/freebsd-begin-tests.sh new file mode 100755 index 00000000..9cdf2e85 --- /dev/null +++ b/tests/fork_func/freebsd-begin-tests.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# Configure with /usr/local/etc/doas.conf containing: +# permit nopass USERNAME as root cmd /sbin/sysctl +# where USERNAME is the your user name. + +doas /sbin/sysctl kern.timecounter.alloweddeviation=0 diff --git a/tests/fork_func/freebsd-end-tests.sh b/tests/fork_func/freebsd-end-tests.sh new file mode 100755 index 00000000..5d30ac71 --- /dev/null +++ b/tests/fork_func/freebsd-end-tests.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# Configure with /usr/local/etc/doas.conf containing: +# permit nopass USERNAME as root cmd /sbin/sysctl +# where USERNAME is the your user name. +# +# In freebsd 12.4, the default value is 5; it could change in future versions. + +doas /sbin/sysctl kern.timecounter.alloweddeviation=5 From 5fe2b4f33307f8bc3d2ae2d0ea287f1442ff64f1 Mon Sep 17 00:00:00 2001 From: Graham Percival Date: Sat, 13 Jan 2024 19:15:38 -0700 Subject: [PATCH 4/4] build: run `make Makefiles` --- liball/Makefile | 4 +++- tests/fork_func/Makefile | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 tests/fork_func/Makefile diff --git a/liball/Makefile b/liball/Makefile index 476b92e1..31cc0a74 100644 --- a/liball/Makefile +++ b/liball/Makefile @@ -1,7 +1,7 @@ .POSIX: # AUTOGENERATED FILE, DO NOT EDIT LIB=liball.a -SRCS=crc32c.c crc32c_arm.c crc32c_sse42.c md5.c sha1.c sha256.c sha256_arm.c sha256_shani.c sha256_sse2.c aws_readkeys.c aws_sign.c cpusupport_arm_aes.c cpusupport_arm_crc32_64.c cpusupport_arm_sha256.c cpusupport_x86_aesni.c cpusupport_x86_rdrand.c cpusupport_x86_shani.c cpusupport_x86_sse2.c cpusupport_x86_sse42.c cpusupport_x86_ssse3.c crypto_aes.c crypto_aes_aesni.c crypto_aes_arm.c crypto_aesctr.c crypto_aesctr_aesni.c crypto_aesctr_arm.c crypto_dh.c crypto_dh_group14.c crypto_entropy.c crypto_entropy_rdrand.c crypto_verify_bytes.c elasticarray.c elasticqueue.c ptrheap.c seqptrmap.c timerqueue.c events.c events_immediate.c events_network.c events_network_selectstats.c events_timer.c http.c https.c netbuf_read.c netbuf_ssl.c netbuf_write.c network_accept.c network_connect.c network_read.c network_write.c network_ssl.c network_ssl_compat.c asprintf.c b64encode.c daemonize.c entropy.c getopt.c hexify.c humansize.c insecure_memzero.c json.c monoclock.c noeintr.c perftest.c readpass.c readpass_file.c setgroups_none.c setuidgid.c sock.c sock_util.c ttyfd.c warnp.c +SRCS=crc32c.c crc32c_arm.c crc32c_sse42.c md5.c sha1.c sha256.c sha256_arm.c sha256_shani.c sha256_sse2.c aws_readkeys.c aws_sign.c cpusupport_arm_aes.c cpusupport_arm_crc32_64.c cpusupport_arm_sha256.c cpusupport_x86_aesni.c cpusupport_x86_rdrand.c cpusupport_x86_shani.c cpusupport_x86_sse2.c cpusupport_x86_sse42.c cpusupport_x86_ssse3.c crypto_aes.c crypto_aes_aesni.c crypto_aes_arm.c crypto_aesctr.c crypto_aesctr_aesni.c crypto_aesctr_arm.c crypto_dh.c crypto_dh_group14.c crypto_entropy.c crypto_entropy_rdrand.c crypto_verify_bytes.c elasticarray.c elasticqueue.c ptrheap.c seqptrmap.c timerqueue.c events.c events_immediate.c events_network.c events_network_selectstats.c events_timer.c http.c https.c netbuf_read.c netbuf_ssl.c netbuf_write.c network_accept.c network_connect.c network_read.c network_write.c network_ssl.c network_ssl_compat.c asprintf.c b64encode.c daemonize.c entropy.c fork_func.c getopt.c hexify.c humansize.c insecure_memzero.c json.c monoclock.c noeintr.c perftest.c readpass.c readpass_file.c setgroups_none.c setuidgid.c sock.c sock_util.c ttyfd.c warnp.c IDIRS=-I../alg -I../aws -I../cpusupport -I../crypto -I../datastruct -I../events -I../http -I../netbuf -I../network -I../network_ssl -I../util -I../external/queue SUBDIR_DEPTH=.. RELATIVE_DIR=liball @@ -133,6 +133,8 @@ daemonize.o: ../util/daemonize.c ../util/noeintr.h ../util/warnp.h ../util/daemo ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c ../util/daemonize.c -o daemonize.o entropy.o: ../util/entropy.c ../util/warnp.h ../util/entropy.h ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c ../util/entropy.c -o entropy.o +fork_func.o: ../util/fork_func.c ../util/warnp.h ../util/fork_func.h + ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c ../util/fork_func.c -o fork_func.o getopt.o: ../util/getopt.c ../util/getopt.h ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c ../util/getopt.c -o getopt.o hexify.o: ../util/hexify.c ../util/hexify.h diff --git a/tests/fork_func/Makefile b/tests/fork_func/Makefile new file mode 100644 index 00000000..478d36e6 --- /dev/null +++ b/tests/fork_func/Makefile @@ -0,0 +1,35 @@ +.POSIX: +# AUTOGENERATED FILE, DO NOT EDIT +PROG=test_fork_func +SRCS=main.c check_exec.c check_exit.c check_order.c check_perftest.c +IDIRS=-I../../util +LDADD_REQ=-lpthread +SUBDIR_DEPTH=../.. +RELATIVE_DIR=tests/fork_func +LIBALL=../../liball/liball.a ../../liball/optional_mutex_pthread/liball_optional_mutex_pthread.a + +all: + if [ -z "$${HAVE_BUILD_FLAGS}" ]; then \ + cd ${SUBDIR_DEPTH}; \ + ${MAKE} BUILD_SUBDIR=${RELATIVE_DIR} \ + BUILD_TARGET=${PROG} buildsubdir; \ + else \ + ${MAKE} ${PROG}; \ + fi + +clean: + rm -f ${PROG} ${SRCS:.c=.o} + +${PROG}:${SRCS:.c=.o} ${LIBALL} + ${CC} -o ${PROG} ${SRCS:.c=.o} ${LIBALL} ${LDFLAGS} ${LDADD_EXTRA} ${LDADD_REQ} ${LDADD_POSIX} + +main.o: main.c ../../util/getopt.h ../../util/parsenum.h ../../util/warnp.h check.h + ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I../.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c main.c -o main.o +check_exec.o: check_exec.c ../../util/fork_func.h ../../util/warnp.h check.h + ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I../.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c check_exec.c -o check_exec.o +check_exit.o: check_exit.c ../../util/fork_func.h check.h + ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I../.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c check_exit.c -o check_exit.o +check_order.o: check_order.c ../../util/fork_func.h ../../util/millisleep.h ../../util/warnp.h check.h + ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I../.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c check_order.c -o check_order.o +check_perftest.o: check_perftest.c ../../util/fork_func.h ../../util/millisleep.h ../../util/monoclock.h ../../util/warnp.h check.h + ${CC} ${CFLAGS_POSIX} -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DCPUSUPPORT_CONFIG_FILE=\"cpusupport-config.h\" -DAPISUPPORT_CONFIG_FILE=\"apisupport-config.h\" -I../.. ${IDIRS} ${CPPFLAGS} ${CFLAGS} -c check_perftest.c -o check_perftest.o