Skip to content

Instantly share code, notes, and snippets.

@evincarofautumn
Last active August 29, 2015 14:07
Show Gist options
  • Save evincarofautumn/c0d4f2bf3845880ba465 to your computer and use it in GitHub Desktop.
Save evincarofautumn/c0d4f2bf3845880ba465 to your computer and use it in GitHub Desktop.
SIGSEGV experiments
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <unistd.h>
static char *buffer1;
static char *buffer2;
static const int page_size = 1 << 12;
static void handler (const int sig, siginfo_t *const si, void *const unused) {
mprotect (si->si_addr, page_size, PROT_READ | PROT_WRITE);
*(char *)(si->si_addr) = 1;
}
typedef struct timings {
struct timeval start;
struct timeval mid;
struct timeval end;
} timings;
static double time_difference (
struct timeval *const start,
struct timeval *const end
) {
return (end->tv_sec + end->tv_usec * 1e-6) - (start->tv_sec + start->tv_usec * 1e-6);
}
static const char *SHARED_OBJECT_NAME = "this_is_my_shared_page";
int main () {
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset (&sa.sa_mask);
sa.sa_sigaction = handler;
sigaction (SIGBUS, &sa, NULL); // OS X
sigaction (SIGSEGV, &sa, NULL); // Linux
int sanity = 0;
enum { SAMPLES = 10000 };
timings times[SAMPLES];
for (int i = 0; i < SAMPLES; ++i) {
gettimeofday (&times [i].start, NULL);
int buffer_fd;
buffer_fd = shm_open (SHARED_OBJECT_NAME, O_RDWR | O_CREAT, 0644);
// shm_unlink (SHARED_OBJECT_NAME);
ftruncate (buffer_fd, page_size);
buffer1 = mmap (
NULL,
page_size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
buffer_fd,
(off_t)0
);
buffer2 = mmap (
NULL,
page_size,
PROT_NONE,
MAP_SHARED,
buffer_fd,
(off_t)0
);
gettimeofday (&times [i].mid, NULL);
buffer1 [0] = 0;
sanity += buffer1 [0];
sanity += buffer2 [0];
munmap (buffer1, page_size);
munmap (buffer2, page_size);
close (buffer_fd);
gettimeofday (&times [i].end, NULL);
}
double total_a = 0.0;
double total_b = 0.0;
double total = 0.0;
for (int i = 0; i < SAMPLES; ++i) {
struct timeval start_time = times [i].start;
struct timeval mid_time = times [i].mid;
struct timeval end_time = times [i].end;
double a = time_difference (&times [i].start, &times [i].mid);
double b = time_difference (&times [i].mid, &times [i].end);
total_a += a;
total_b += b;
total += a + b;
}
printf (
"Legend: A = allocate, B = use & free\n"
"Sanity: %d = %d\n"
"Totals:\n"
"A: %f s\n"
"B: %f s\n"
"A+B: %f s\n"
"Means:\n"
"A: %f μs\n"
"B: %f μs\n"
"A+B: %f μs\n",
SAMPLES,
sanity,
total_a, total_b, total,
total_a / SAMPLES * 1e6, total_b / SAMPLES * 1e6, total / SAMPLES * 1e6
);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment