Lots of global pointers
#include <mach/mach_time.h> | |
#include <mach-o/dyld.h> | |
#include <inttypes.h> | |
#include <signal.h> | |
#include <spawn.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/param.h> | |
#include <sys/wait.h> | |
struct class { | |
const char *name; | |
void (*method1)(void); | |
void (*method2)(void); | |
void (*method3)(void); | |
void (*method4)(void); | |
void (*method5)(void); | |
void (*method6)(void); | |
void (*method7)(void); | |
}; | |
void fake_method() {} | |
#if !defined(VARIATION) || VARIATION < 0 || VARIATION > 2 | |
#error "Please pass -DVARIATION=[012] to the compiler. " \ | |
"0 = no globals; 1 = 256K non-pointer globals; 2 = 256K pointer globals" | |
#endif | |
#if VARIATION >= 1 | |
// Create 4096 class records | |
#define LOTS(x) \ | |
x(__COUNTER__) x(__COUNTER__) x(__COUNTER__) x(__COUNTER__) \ | |
x(__COUNTER__) x(__COUNTER__) x(__COUNTER__) x(__COUNTER__) | |
#define LOTS_AND_LOTS(x) \ | |
LOTS(x) LOTS(x) LOTS(x) LOTS(x) \ | |
LOTS(x) LOTS(x) LOTS(x) LOTS(x) | |
#define LOTS_AND_LOTS_AND_LOTS(x) \ | |
LOTS_AND_LOTS(x) LOTS_AND_LOTS(x) LOTS_AND_LOTS(x) LOTS_AND_LOTS(x) \ | |
LOTS_AND_LOTS(x) LOTS_AND_LOTS(x) LOTS_AND_LOTS(x) LOTS_AND_LOTS(x) | |
#define LOTS_AND_LOTS_AND_LOTS_AND_LOTS(x) \ | |
LOTS_AND_LOTS_AND_LOTS(x) LOTS_AND_LOTS_AND_LOTS(x) LOTS_AND_LOTS_AND_LOTS(x) LOTS_AND_LOTS_AND_LOTS(x) \ | |
LOTS_AND_LOTS_AND_LOTS(x) LOTS_AND_LOTS_AND_LOTS(x) LOTS_AND_LOTS_AND_LOTS(x) LOTS_AND_LOTS_AND_LOTS(x) | |
#if VARIATION == 1 | |
#define CLASS_(nam) \ | |
const struct class nam = { \ | |
.name = (void*)1, \ | |
.method1 = (void*)2, \ | |
.method2 = (void*)3, \ | |
.method3 = (void*)4, \ | |
.method4 = (void*)5, \ | |
.method5 = (void*)6, \ | |
.method6 = (void*)7, \ | |
.method7 = (void*)8 \ | |
}; | |
#else | |
#define CLASS_(nam) \ | |
const struct class nam = { \ | |
.name = #nam, \ | |
.method1 = fake_method, \ | |
.method2 = fake_method, \ | |
.method3 = fake_method, \ | |
.method4 = fake_method, \ | |
.method5 = fake_method, \ | |
.method6 = fake_method, \ | |
.method7 = fake_method \ | |
}; | |
#endif | |
#define CLASS(nam) CLASS_(nam) | |
#define CAT_(a, b) a ## b | |
#define CAT(a, b) CAT_(a, b) | |
#define OF_CLASSES(n) CLASS(CAT(class, n)) | |
LOTS_AND_LOTS_AND_LOTS_AND_LOTS(OF_CLASSES) | |
#endif | |
int main(int argc, char *argv[], char *envp[]) { | |
if (argc < 3) { | |
// Respawn ourselves to measure the pre-main startup time. | |
char time_buffer[22]; | |
char path_buffer[MAXPATHLEN+1]; | |
uint32_t path_buffer_size = MAXPATHLEN+1; | |
if (_NSGetExecutablePath(path_buffer, &path_buffer_size)) { | |
perror(argv[0]); | |
return 1; | |
} | |
char *sub_argv[] = { | |
argv[0], | |
argv[1] ? argv[1] : "-", | |
time_buffer, | |
0 | |
}; | |
// Measure the time right before posix_spawning the child process. | |
uint64_t time = mach_absolute_time(); | |
sprintf(time_buffer, "%" PRIu64, time); | |
pid_t pid; | |
if (posix_spawn(&pid, path_buffer, 0, 0, sub_argv, envp)) { | |
perror(argv[0]); | |
return 1; | |
} | |
int stat; | |
waitpid(pid, &stat, WUNTRACED); | |
// Stop so we can inspect the process memory usage. | |
if (argv[1] && strcmp(argv[1], "-stop") == 0) { | |
pid_t pid = getpid(); | |
printf("pid %u\n", (unsigned)pid); | |
raise(SIGSTOP); | |
} | |
return 0; | |
} else { | |
// We should have been passed the pre-spawn time in argv[2]. | |
// Measure the time immediately after entering main. | |
uint64_t time = mach_absolute_time(); | |
unsigned long long start_time = strtoull(argv[2], 0, 10); | |
uint64_t elapsed = time - start_time; | |
// Convert mach time units to nanoseconds. | |
mach_timebase_info_data_t timebase; | |
mach_timebase_info(&timebase); | |
typedef unsigned __int128 uint128_t; | |
uint64_t nanoseconds = (uint128_t)elapsed * (uint128_t)timebase.numer / timebase.denom; | |
printf("%" PRIu64 " nanoseconds from spawn to main() entry\n", nanoseconds); | |
return 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment