Created
February 12, 2019 16:14
-
-
Save joaomlneto/4a52bbdada5a93d092963ef1cf857616 to your computer and use it in GitHub Desktop.
linux signals benchmarking
This file contains hidden or 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
#include <stdlib.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <time.h> | |
#include <unistd.h> | |
#include <signal.h> | |
#include <ucontext.h> | |
#include <fcntl.h> | |
#include <execinfo.h> | |
#include <sys/mman.h> | |
#define PAGE_SIZE sysconf(_SC_PAGESIZE) | |
#define PAGE_MASK (PAGE_SIZE - 1) | |
#define PAGE_ALIGN_DOWN(x) (((intptr_t) (x)) & ~PAGE_MASK) | |
#define N (PAGE_SIZE/sizeof(uint64_t)) | |
#define NTIMES 1ULL<<22 | |
static uint64_t remaining; | |
void initialize(uint64_t *a, size_t size) { | |
printf("initializing... "); | |
fflush(stdout); | |
clock_t start = clock(); | |
a[0] = 123; | |
for (size_t i=1; i < size; i++) { | |
a[i] = a[i-1] * a[i-1] % 100000; | |
} | |
clock_t end = clock(); | |
double seconds = (double)(end - start) / CLOCKS_PER_SEC; | |
printf("done in %lf seconds\n", seconds); | |
} | |
void segv_handler(int signum, siginfo_t *siginfo, void *ctx) { | |
if (--remaining == 0) { | |
mprotect((void*) PAGE_ALIGN_DOWN(siginfo->si_addr), | |
PAGE_SIZE, PROT_READ | PROT_WRITE); | |
} | |
} | |
void install_sighandler() { | |
stack_t sigstk; | |
sigstk.ss_sp = malloc(SIGSTKSZ); | |
sigstk.ss_size = SIGSTKSZ; | |
sigstk.ss_flags = 0; | |
sigaltstack(&sigstk, NULL); | |
struct sigaction siga; | |
sigemptyset(&siga.sa_mask); | |
sigaddset(&siga.sa_mask, SIGSEGV); | |
// block signals temporarily | |
sigprocmask(SIG_BLOCK, &siga.sa_mask, NULL); | |
siga.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART | SA_NODEFER; | |
// install segv handler | |
siga.sa_sigaction = segv_handler; | |
if (sigaction(SIGSEGV, &siga, NULL) == -1) { | |
fprintf(stderr, "error installing sigsegv handler\n"); | |
exit(-1); | |
} | |
sigprocmask(SIG_UNBLOCK, &siga.sa_mask, NULL); | |
} | |
void time_signals(uint64_t *a, size_t size, size_t ntimes) { | |
remaining = ntimes; | |
mprotect(a, PAGE_SIZE, PROT_READ); | |
clock_t start = clock(); | |
a[1] = a[2] + a[3]; | |
clock_t end = clock(); | |
double seconds = (double)(end - start) / CLOCKS_PER_SEC; | |
printf("%zu signals -> %lf seconds\n", ntimes, seconds); | |
} | |
int main() { | |
uint64_t *a = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, | |
MAP_SHARED | MAP_ANONYMOUS, -1, 0); | |
install_sighandler(); | |
initialize(a, N); | |
for (int i=1; i <= NTIMES; i *= 2) { | |
time_signals(a, 100, i); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment