<commit_before>
#ifdef HAVE_CONFIG
#include "config.h"
#endif //HAVE_CONFIG

#include "ipcbench.h"
#include "util.h"




static void send(struct ipcbench_vtab *vtab) {
    //make_realtime(99);
    usleep(0.25e6);
    if( vtab->init_send ) vtab->init_send();

    while(1) {
        struct timespec ts = get_ticks();
        clock_gettime( CLOCK_MONOTONIC, &ts );
        vtab->send(&ts);
        usleep(1e3);
    }

    if( vtab->destroy_send ) vtab->destroy_send();
}

static void recv(struct ipcbench_vtab *vtab) {
    //make_realtime(99);
    if( vtab->init_recv ) vtab->init_recv();

    /* warm up */
    //for( size_t i = 0; i < 10; i ++ ) {
        //struct timespec ts;
        //vtab->recv(&ts );
    //}

    while(1) {
        struct timespec ts;
        vtab->recv(&ts );
        struct timespec now = get_ticks();
        printf("delta: %lf us\n", ticks_delta( ts, now ) * 1e6);
    }

    if( vtab->destroy_recv ) vtab->destroy_recv();
}

int main( int argc, char **argv ) {
    (void)argc;
    (void)argv;

    /* Parse args */
    const char *type = "ach";
    int c;
    while( (c = getopt( argc, argv, "v?V")) != -1 ) {
        switch(c) {
        case 'V':   /* version     */
            puts("ipcbench 0.0");
            exit(EXIT_SUCCESS);
        case '?':   /* version     */
            puts("Usage: ipcbench [OPTION....] TYPE\n"
                 "Benchmark IPC\n"
                 "\n"
                 "Options:\n"
                 "  -V                Version\n"
                 "  -?                Help\n"
                );
            exit(EXIT_SUCCESS);
        default:
            type = optarg;
        }
    }
    while( optind < argc ) {
        type = argv[optind++];
    }


    fprintf(stderr, "type: %s\n", type );

    /* Lookup vtab */
    struct {
        const char *name;
        struct ipcbench_vtab *vtab;
    } sym_vtabs[] = {
        {"ach", &ipc_bench_vtab_ach},
        {"lcm", &ipc_bench_vtab_lcm},
        {"pipe", &ipc_bench_vtab_pipe},
        {"mq", &ipc_bench_vtab_mq},
        {"tcp", &ipc_bench_vtab_tcp},
        {"local", &ipc_bench_vtab_local},
        {"udp", &ipc_bench_vtab_udp},
        {"localdgram", &ipc_bench_vtab_local_dgram},
        {NULL, NULL},
    };
    struct ipcbench_vtab *vtab;
    {
        size_t i = 0;
        while( sym_vtabs[i].name && 0 != strcasecmp( type, sym_vtabs[i].name ) ) i++;
        if( NULL == sym_vtabs[i].name ) {
            fprintf(stderr, "Invalid type: %s\n", type );
            exit(EXIT_FAILURE);
        }
        vtab = sym_vtabs[i].vtab;
    }

    /* Make realtime */
    make_realtime(30);
    calibrate();
    fprintf(stderr, "overhead: %f us\n", overhead * 1e6);


    /* Execute */
    if( vtab->init ) vtab->init();

    pid_t pid_send = fork();
    if( 0 == pid_send ) {
        send(vtab);
        return 0;
    } else if ( pid_send < 0 ) {
        abort();
    }

    pid_t pid_listen = fork();
    if( 0 == pid_listen ) {
        recv(vtab);
        return 0;
    } else if ( pid_listen < 0 ) {
        abort();
    }

    sleep(100);


    if( vtab->destroy ) vtab->destroy();

    return 0;

}
<commit_msg>Add options for frequency and duration<commit_after>
#ifdef HAVE_CONFIG
#include "config.h"
#endif //HAVE_CONFIG

#include <signal.h>
#include <sys/wait.h>
#include "ipcbench.h"
#include "util.h"


sig_atomic_t sig_canceled = 0;
double opt_freq = 1000;
double opt_sec = 1;


static void sighandler( int sig ) {
    (void) sig;
    sig_canceled = 1;
}


static void register_handler( ) {
    struct sigaction act;
    memset(&act, 0, sizeof(act));
    act.sa_handler = &sighandler;
    if( sigaction(SIGUSR1, &act, NULL) ) {
        perror("couldn't register signal handler");
        abort();
    }
}


static void send(struct ipcbench_vtab *vtab) {
    //make_realtime(99);
    struct timespec relsleep;
    double period = 1.0 / opt_freq;
    relsleep.tv_sec = period;
    relsleep.tv_nsec = (period - (time_t)period) * 1e9;

    usleep(0.25e6);
    if( vtab->init_send ) vtab->init_send();

    while( !sig_canceled ) {
        struct timespec ts = get_ticks();
        clock_gettime( CLOCK_MONOTONIC, &ts );
        vtab->send(&ts);
        clock_nanosleep( CLOCK_MONOTONIC, 0, &relsleep, NULL ); // TODO, handle eintr
    }

    if( vtab->destroy_send ) vtab->destroy_send();
}

static void kill_wait(pid_t pid) {
    if( kill(pid, SIGUSR1) ) {
        perror("Couldn't kill");
        abort();
    }

    int status;
    if( waitpid( pid, &status, 0 ) < 0 ) {
        perror("Couldn't wait");
        abort();

    }
}

static void recv(struct ipcbench_vtab *vtab) {
    //make_realtime(99);
    if( vtab->init_recv ) vtab->init_recv();

    /* warm up */
    for( size_t i = 0; i < 10; i ++ ) {
        struct timespec ts;
        vtab->recv(&ts );
    }

    while(! sig_canceled ) {
        struct timespec ts;
        vtab->recv(&ts );
        struct timespec now = get_ticks();
        printf("%lf\n", ticks_delta( ts, now ) * 1e6);
    }

    if( vtab->destroy_recv ) vtab->destroy_recv();
    exit(EXIT_SUCCESS);
}

int main( int argc, char **argv ) {
    (void)argc;
    (void)argv;

    /* Parse args */
    const char *type = "ach";
    char *endptr = 0;
    int c;
    while( (c = getopt( argc, argv, "s:f:v?V")) != -1 ) {
        switch(c) {
        case 'V':   /* version     */
            puts("ipcbench 0.0");
            exit(EXIT_SUCCESS);
        case 'f':
            opt_freq = strtod(optarg, &endptr);
            if( NULL == endptr )  {
                fprintf( stderr, "Invalid frequency: %s\n", optarg );
                exit(EXIT_FAILURE);
            }
            break;
        case 's':
            opt_sec = strtod(optarg, &endptr);
            if( NULL == endptr )  {
                fprintf( stderr, "Invalid duration: %s\n", optarg );
                exit(EXIT_FAILURE);
            }
            break;
        case '?':   /* version     */
            puts("Usage: ipcbench [OPTION....] TYPE\n"
                 "Benchmark IPC\n"
                 "\n"
                 "Options:\n"
                 "  -f FREQUENCY,     Frequency in Hertz (1000)\n"
                 "  -s SECONDS,       Duration in seconds (1)\n"
                 "  -V                Version\n"
                 "  -?                Help\n"
                );
            exit(EXIT_SUCCESS);
        default:
            type = optarg;
        }
    }
    while( optind < argc ) {
        type = argv[optind++];
    }


    fprintf(stderr, "type: %s\n", type );

    /* Lookup vtab */
    struct {
        const char *name;
        struct ipcbench_vtab *vtab;
    } sym_vtabs[] = {
        {"ach", &ipc_bench_vtab_ach},
        {"lcm", &ipc_bench_vtab_lcm},
        {"pipe", &ipc_bench_vtab_pipe},
        {"mq", &ipc_bench_vtab_mq},
        {"tcp", &ipc_bench_vtab_tcp},
        {"local", &ipc_bench_vtab_local},
        {"udp", &ipc_bench_vtab_udp},
        {"localdgram", &ipc_bench_vtab_local_dgram},
        {NULL, NULL},
    };
    struct ipcbench_vtab *vtab;
    {
        size_t i = 0;
        while( sym_vtabs[i].name && 0 != strcasecmp( type, sym_vtabs[i].name ) ) i++;
        if( NULL == sym_vtabs[i].name ) {
            fprintf(stderr, "Invalid type: %s\n", type );
            exit(EXIT_FAILURE);
        }
        vtab = sym_vtabs[i].vtab;
    }

    /* Make realtime */
    make_realtime(30);
    calibrate();
    fprintf(stderr, "overhead: %f us\n", overhead * 1e6);


    /* Execute */
    if( vtab->init ) vtab->init();

    pid_t pid_send = fork();
    if( 0 == pid_send ) {
        register_handler();
        send(vtab);
        return 0;
    } else if ( pid_send < 0 ) {
        abort();
    }

    pid_t pid_listen = fork();
    if( 0 == pid_listen ) {
        register_handler();
        recv(vtab);
        return 0;
    } else if ( pid_listen < 0 ) {
        abort();
    }

    sleep(opt_sec);
    kill_wait(pid_listen);
    kill_wait(pid_send);

    if( vtab->destroy ) vtab->destroy();

    return 0;

}

{'fraction_non_alphanumeric': 0.1521875391751285, 'fraction_numerical': 0.011031716184029084, 'mean_word_length': 1.7682165163081194, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6460651', 'n_tokens_mistral': 2931, 'n_tokens_neox': 2844, 'n_words': 602}