Created
March 12, 2020 08:59
-
-
Save unmanned-player/2e0d471d4912f68975ff28988416db71 to your computer and use it in GitHub Desktop.
A simple test case to benchmark fork() and posix_spawn()
This file contains 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
/* Configurations. */ | |
#define WITH_VFORK | |
// #define TRY_FORK | |
#define TRY_SPAWN | |
#define WAIT_PID | |
#define RUNS 1000 | |
/* Code. */ | |
#ifdef WITH_VFORK | |
#define _GNU_SOURCE 1 | |
#define _BSD_SOURCE 1 | |
#define _DEFAULT_SOURCE 1 | |
#endif | |
#ifdef TRY_FORK | |
#ifdef WITH_VFORK | |
#define FORK_FMT "vfork,%" PRIu64 ",%u\n" | |
#else | |
#define FORK_FMT "nfork,%" PRIu64 ",%u\n" | |
#endif | |
#endif | |
#ifdef TRY_SPAWN | |
#ifdef WITH_VFORK | |
#define SPAWN_FMT "vspwan,%" PRIu64 ",%u\n" | |
#else | |
#define SPAWN_FMT "nspwan,%" PRIu64 ",%u\n" | |
#endif | |
#endif | |
#include <stdint.h> | |
#include <stddef.h> | |
#include <inttypes.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <sys/wait.h> | |
#include <time.h> | |
#include <unistd.h> | |
#include <spawn.h> | |
static char exe[] = "/bin/true"; | |
static char *const ARGV[] = { exe, NULL }; | |
#define SEC_US ((uint64_t)(1000 * 1000 * 1000)) | |
#define NSEC_US ((uint64_t)1000) | |
static inline uint64_t clk_get_ts(void) | |
{ | |
struct timespec tv; | |
if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0) { | |
return ((uint64_t)tv.tv_sec * SEC_US) + ((uint64_t)tv.tv_nsec / NSEC_US); | |
} | |
return 0; | |
} | |
#ifdef TRY_FORK | |
static void test_fork(void) | |
{ | |
pid_t pid; | |
#ifdef WITH_VFORK | |
pid = vfork(); | |
#else | |
pid = fork(); | |
#endif | |
if (pid == -1) { | |
perror("fork"); | |
_exit(EXIT_FAILURE); | |
} else if (pid > 0) { | |
#ifdef WAIT_PID | |
int r; | |
waitpid(pid, &r, 0); | |
#endif | |
} else { | |
execv(ARGV[0], ARGV); | |
_exit(EXIT_FAILURE); | |
} | |
} | |
#endif | |
#ifdef TRY_SPAWN | |
static void test_posix_spawn(void) | |
{ | |
posix_spawnattr_t attr; | |
int r; | |
pid_t pid; | |
memset(&attr, 0, sizeof(posix_spawnattr_t)); | |
if ((r = posix_spawnattr_init(&attr)) != 0) _exit(EXIT_FAILURE); | |
#if defined(WITH_VFORK) && defined(POSIX_SPAWN_USEVFORK) | |
posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK); | |
#endif | |
if ((r = posix_spawn(&pid, ARGV[0], NULL, &attr, ARGV, NULL)) == 0) { | |
#ifdef WAIT_PID | |
waitpid(pid, &r, 0); | |
#endif | |
} | |
posix_spawnattr_destroy(&attr); | |
} | |
#endif | |
int main(int argc, char **argv) | |
{ | |
unsigned i, max; | |
uint64_t time; | |
max = (argc > 1)? (unsigned)atoi(argv[1]): RUNS; | |
#ifdef TRY_FORK | |
time = clk_get_ts(); | |
for (i = 0; i < max; i++) { | |
test_fork(); | |
} | |
time = clk_get_ts() - time; | |
printf(FORK_FMT, time, max); | |
#endif | |
#ifdef TRY_SPAWN | |
time = clk_get_ts(); | |
for (i = 0; i < max; i++) { | |
test_posix_spawn(); | |
} | |
time = clk_get_ts() - time; | |
printf(SPAWN_FMT, time, max); | |
#endif | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment