mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 11:37:35 +00:00
140 lines
4.2 KiB
C
140 lines
4.2 KiB
C
|
#if 0
|
||
|
/*─────────────────────────────────────────────────────────────────╗
|
||
|
│ To the extent possible under law, Justine Tunney has waived │
|
||
|
│ all copyright and related or neighboring rights to this file, │
|
||
|
│ as it is written in the following disclaimers: │
|
||
|
│ • http://unlicense.org/ │
|
||
|
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||
|
╚─────────────────────────────────────────────────────────────────*/
|
||
|
#endif
|
||
|
#include "libc/atomic.h"
|
||
|
#include "libc/calls/calls.h"
|
||
|
#include "libc/calls/struct/timespec.h"
|
||
|
#include "libc/calls/weirdtypes.h"
|
||
|
#include "libc/mem/mem.h"
|
||
|
#include "libc/proc/posix_spawn.h"
|
||
|
#include "libc/runtime/runtime.h"
|
||
|
#include "libc/stdio/stdio.h"
|
||
|
#include "libc/str/str.h"
|
||
|
#include "libc/sysv/consts/clock.h"
|
||
|
#include "libc/sysv/consts/map.h"
|
||
|
#include "libc/sysv/consts/prot.h"
|
||
|
|
||
|
#define ITERATIONS 10
|
||
|
|
||
|
_Alignas(128) int a;
|
||
|
_Alignas(128) int b;
|
||
|
_Alignas(128) atomic_int lock;
|
||
|
|
||
|
static struct timespec SubtractTime(struct timespec a, struct timespec b) {
|
||
|
a.tv_sec -= b.tv_sec;
|
||
|
if (a.tv_nsec < b.tv_nsec) {
|
||
|
a.tv_nsec += 1000000000;
|
||
|
a.tv_sec--;
|
||
|
}
|
||
|
a.tv_nsec -= b.tv_nsec;
|
||
|
return a;
|
||
|
}
|
||
|
|
||
|
static time_t ToNanoseconds(struct timespec ts) {
|
||
|
return ts.tv_sec * 1000000000 + ts.tv_nsec;
|
||
|
}
|
||
|
|
||
|
static char *Ithoa(char p[27], unsigned long x) {
|
||
|
char m[26];
|
||
|
unsigned i;
|
||
|
i = 0;
|
||
|
do {
|
||
|
m[i++] = x % 10 + '0';
|
||
|
x = x / 10;
|
||
|
} while (x);
|
||
|
for (;;) {
|
||
|
*p++ = m[--i];
|
||
|
if (!i) break;
|
||
|
if (!(i % 3)) *p++ = ',';
|
||
|
}
|
||
|
*p = '\0';
|
||
|
return p;
|
||
|
}
|
||
|
|
||
|
#define BENCH(name, x) \
|
||
|
{ \
|
||
|
int i; \
|
||
|
char ibuf[27]; \
|
||
|
struct timespec t1, t2; \
|
||
|
clock_gettime(CLOCK_REALTIME, &t1); \
|
||
|
for (i = 0; i < ITERATIONS; ++i) { \
|
||
|
x; \
|
||
|
} \
|
||
|
clock_gettime(CLOCK_REALTIME, &t2); \
|
||
|
Ithoa(ibuf, ToNanoseconds(SubtractTime(t2, t1)) / ITERATIONS); \
|
||
|
printf("%-50s %16s ns\n", name, ibuf); \
|
||
|
}
|
||
|
|
||
|
void PosixSpawnWait(const char *prog) {
|
||
|
int ws, err, pid;
|
||
|
char *args[] = {(char *)prog, 0};
|
||
|
char *envs[] = {0};
|
||
|
if ((err = posix_spawn(&pid, prog, NULL, NULL, args, envs))) {
|
||
|
perror(prog);
|
||
|
exit(1);
|
||
|
}
|
||
|
if (waitpid(pid, &ws, 0) == -1) {
|
||
|
perror("waitpid");
|
||
|
exit(1);
|
||
|
}
|
||
|
if (!(WIFEXITED(ws) && WEXITSTATUS(ws) == 42)) {
|
||
|
puts("bad exit status");
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ForkExecWait(const char *prog) {
|
||
|
int ws;
|
||
|
if (!fork()) {
|
||
|
execve(prog, (char *[]){(char *)prog, 0}, (char *[]){0});
|
||
|
_Exit(127);
|
||
|
}
|
||
|
if (wait(&ws) == -1) {
|
||
|
perror("wait");
|
||
|
exit(1);
|
||
|
}
|
||
|
if (!(WIFEXITED(ws) && WEXITSTATUS(ws) == 42)) {
|
||
|
puts("bad exit status");
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
char *FillMemory(char *p, long n) {
|
||
|
return memset(p, -1, n);
|
||
|
}
|
||
|
char *(*pFillMemory)(char *, long) = FillMemory;
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
long n;
|
||
|
void *p;
|
||
|
const char *prog;
|
||
|
|
||
|
if (argc <= 1) {
|
||
|
prog = "tiny64";
|
||
|
} else {
|
||
|
prog = argv[1];
|
||
|
}
|
||
|
|
||
|
BENCH("fork() + exec(tiny)", ForkExecWait(prog));
|
||
|
BENCH("posix_spawn(tiny)", PosixSpawnWait(prog));
|
||
|
|
||
|
n = 128L * 1024 * 1024;
|
||
|
p = pFillMemory(
|
||
|
mmap(0, n, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0), n);
|
||
|
BENCH("mmap(128mb, MAP_SHARED) + fork() + exec(tiny)", ForkExecWait(prog));
|
||
|
BENCH("mmap(128mb, MAP_SHARED) + posix_spawn(tiny)", PosixSpawnWait(prog));
|
||
|
munmap(p, n);
|
||
|
|
||
|
n = 128L * 1024 * 1024;
|
||
|
p = pFillMemory(malloc(n), n);
|
||
|
BENCH("malloc(128mb) + fork() + exec(tiny)", ForkExecWait(prog));
|
||
|
BENCH("malloc(128mb) + posix_spawn(tiny)", PosixSpawnWait(prog));
|
||
|
free(p);
|
||
|
}
|