Created
May 13, 2011 19:21
-
-
Save mheffner/971137 to your computer and use it in GitHub Desktop.
Report gettimeofday, TSC and getrusage(self) periodically while performing I/O workload.
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
/* | |
* Dumps the value of gettimeofday(), the TSC, and | |
* getrusage(RUSAGE_SELF) every two seconds while performing some fake | |
* I/O workload on a /tmp file. | |
* | |
* Build: gcc -o readtsc readtsc.c -lrt | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdint.h> | |
#include <inttypes.h> | |
#include <sys/time.h> | |
#include <sys/resource.h> | |
#include <signal.h> | |
#include <sys/types.h> | |
#include <unistd.h> | |
#include <time.h> | |
static uint64_t | |
get_time(void) | |
{ | |
struct timeval tv; | |
gettimeofday(&tv, NULL); | |
return (tv.tv_sec * 1000000L) + tv.tv_usec; | |
} | |
__inline__ uint64_t | |
get_tsc(void) { | |
uint32_t lo, hi; | |
__asm__ __volatile__ ( /* serialize */ | |
"xorl %%eax,%%eax \n cpuid" | |
::: "%rax", "%rbx", "%rcx", "%rdx"); | |
/* We cannot use "=A", since this would use %rax on x86_64 and | |
* return only the lower 32bits of the TSC | |
*/ | |
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); | |
return (uint64_t)hi << 32 | lo; | |
} | |
static uint64_t | |
get_usage(void) | |
{ | |
struct rusage usage; | |
struct timeval usage_time; | |
uint64_t current_usage; | |
getrusage(RUSAGE_SELF, &usage); | |
usage_time.tv_usec = usage.ru_utime.tv_usec + usage.ru_stime.tv_usec; | |
usage_time.tv_sec = usage.ru_utime.tv_sec + usage.ru_stime.tv_sec; | |
if (usage_time.tv_usec >= 1000000) | |
{ | |
usage_time.tv_usec -= 1000000; | |
usage_time.tv_sec++; | |
} | |
current_usage = (uint64_t)usage_time.tv_sec * 1000000 + | |
(uint64_t)usage_time.tv_usec; | |
return current_usage; | |
} | |
uint64_t base_tod, base_tsc, base_usage; | |
void | |
print_time(int sig) | |
{ | |
int64_t tod, tsc, usage; | |
tod = get_time(); | |
tsc = get_tsc(); | |
usage = get_usage(); | |
tod -= base_tod; | |
tsc -= base_tsc; | |
usage -= base_usage; | |
printf("{ \"timeofday\" : %" PRId64 ", \"tsc\" : %" PRId64 ", \"usage\" : %" PRId64 " }\n", | |
tod, tsc, usage); | |
fflush(stdout); | |
} | |
#define TEMPLATE "/tmp/tempXXXXXXXXXX" | |
int | |
main(int ac, char **av) | |
{ | |
struct sigevent se; | |
timer_t timer; | |
struct itimerspec ts; | |
struct sigaction act; | |
char tmp[] = TEMPLATE; | |
sigfillset(&act.sa_mask); | |
sigdelset(&act.sa_mask, SIGRTMAX - 3); | |
act.sa_flags = SA_RESTART; | |
act.sa_handler = print_time; | |
if (sigaction(SIGRTMAX - 3, &act, NULL) != 0) { | |
perror("sigaction"); | |
exit(1); | |
} | |
memset(&se, 0, sizeof(se)); | |
se.sigev_notify = SIGEV_SIGNAL; | |
se.sigev_signo = SIGRTMAX - 3; | |
se.sigev_value.sival_int = 0; | |
if (timer_create(CLOCK_REALTIME, &se, &timer) != 0) { | |
perror("timer_create"); | |
exit(1); | |
} | |
ts.it_value.tv_sec = 2; | |
ts.it_value.tv_nsec = 0; | |
ts.it_interval.tv_sec = 2; | |
ts.it_interval.tv_nsec = 0; | |
/* Initialize starting. */ | |
base_tod = get_time(); | |
base_tsc = get_tsc(); | |
base_usage = get_usage(); | |
/* Start timer */ | |
timer_settime(timer, 0, &ts, NULL); | |
/* Perform some fake I/O workload. */ | |
while(1) { | |
int fd; | |
size_t size = 1024 * 1024 * 1024; | |
size_t bs = 8192; | |
size_t sync_size = 8192 * 4; | |
char buf[8192] = ""; | |
size_t i; | |
ssize_t w; | |
fd = mkstemp(tmp); | |
unlink(tmp); | |
/* write a size byte file */ | |
for (i = 0; i < size; i += bs) { | |
w = write(fd, buf, bs); | |
if (w < 0 || (size_t)w != bs) { | |
perror("write"); | |
exit(1); | |
} | |
if ((i % sync_size) == 0) | |
fsync(fd); | |
} | |
fsync(fd); | |
lseek(fd, 0, SEEK_SET); | |
/* now read */ | |
for (i = 0; i < size; i += bs) { | |
read(fd, buf, bs); | |
} | |
close(fd); | |
sprintf(tmp, TEMPLATE); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment