All pastes #2475810 Raw Edit

Mine

public unlisted c v1 · immutable
#2475810 ·published 2013-11-13 11:56 UTC
rendered paste body
#include <stdio.h>#include <time.h>#include <signal.h>#include <string.h>#include <sys/select.h>#include <unistd.h>#include <stdint.h>uint64_t my_get_time_us(){    struct timespec ts;    clock_gettime(CLOCK_MONOTONIC, &ts);    return ts.tv_sec * 1000000 + ts.tv_nsec / 1000;}uint64_t *records;int pos = 0;int iterations = 0;void record_time(){    if (pos < iterations)        records[pos ++] = my_get_time_us();}void report(const char *name){    printf("'%s': [", name);    int i;    for (i = 0; i < iterations; ++i)    {        printf("%llu, ", (unsigned long long)records[i]);    }    printf("],\n");    memset(records, 0, iterations * sizeof(uint64_t));    pos = 0;}void my_sleep_1(uint64_t us){    struct timespec ts;    ts.tv_sec = 0;    ts.tv_nsec = us * 1000;    clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);}void my_sleep_2(uint64_t us){    struct timespec ts;    ts.tv_sec = 0;    ts.tv_nsec = us * 1000;    nanosleep(&ts, NULL);}void my_sleep_3(uint64_t us){    usleep(us);}void my_sleep_4(uint64_t us){    struct timeval tv;    tv.tv_sec = 0;    tv.tv_usec = us;    select(0, NULL, NULL, NULL, &tv);}struct timespec abs_start;void my_sleep_abs_init(){    clock_gettime(CLOCK_MONOTONIC, &abs_start);}void my_sleep_abs(uint64_t us){    struct timespec ts = abs_start;    ts.tv_sec += (us / 1000000);    ts.tv_nsec += (us % 1000000 * 1000);    if (ts.tv_nsec >= 1000000000)    {        ts.tv_sec += 1;        ts.tv_nsec -= 1000000000;    }    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);}timer_t timer_id;void my_timer_handler(int sig, siginfo_t *si, void *uc){    record_time();}void my_timer_init(){    struct sigaction sa;    sa.sa_flags = SA_SIGINFO;    sa.sa_sigaction = my_timer_handler;    sigemptyset(&sa.sa_mask);    sigaction(SIGRTMIN, &sa, NULL);    struct sigevent sig;    sig.sigev_notify = SIGEV_SIGNAL;    sig.sigev_signo = SIGRTMIN;    sig.sigev_value.sival_ptr = &timer_id;    timer_create(CLOCK_MONOTONIC, &sig, &timer_id);}void my_timer_set(uint64_t us){    struct itimerspec its;    its.it_value.tv_sec = 0;    its.it_value.tv_nsec = us * 1000;    its.it_interval.tv_sec = its.it_value.tv_sec;    its.it_interval.tv_nsec = its.it_value.tv_nsec;    timer_settime(timer_id, 0, &its, NULL);}void run_sleep(void (* sleep_func)(uint64_t us), uint64_t us){    uint64_t ts = my_get_time_us();    int i;    for (i = 0; i < iterations; ++i)    {        ts += us;        uint64_t now = my_get_time_us();        if (ts > now)            sleep_func(ts - now);        record_time();    }}void run_sleep_abs(uint64_t us){    uint64_t ts = 0;    int i;    my_sleep_abs_init();    for (i = 0; i < iterations; ++i)    {        ts += us;        my_sleep_abs(ts);        record_time();    }}void run_timer(uint64_t us){    my_timer_init();    my_timer_set(us);    int i;    for (i = 0; i < iterations; ++i)    {        pause();    }    my_timer_set(0);}void run(int us){    run_sleep(my_sleep_1, us);    report("clock_nanosleep");    run_sleep(my_sleep_2, us);    report("nanosleep");    run_sleep(my_sleep_4, us);    report("select");    run_sleep_abs(us);    report("clock_nanosleep_TIMER_ABSTIME");    run_timer(us);    report("signal");}int main(int argc, char **argv){    uint64_t interval = argc > 1 ? atoi(argv[1]) : 1000;    iterations = argc > 2 ? atoi(argv[2]) : 1000;    records = calloc(iterations, sizeof(uint64_t));    run(interval);    return 0;}