From: Laurent Mazet Date: Fri, 31 Oct 2025 09:32:34 +0000 (+0100) Subject: add process mode X-Git-Tag: v1.1~12 X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=ddfa1e8a5f473f5a0375a8059770e2a265cd0d46;p=benchmarks.git add process mode --- diff --git a/clock.c b/clock.c index 6a18d93..5a05ef5 100644 --- a/clock.c +++ b/clock.c @@ -1,37 +1,36 @@ /* depend: */ /* cflags: */ -/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */ +/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */ #include #include #include #include +#include "main.h" #include "mtime.h" -#include "test.h" /* global variables */ dts_t *deltas = NULL; int nb_measurements = 0; +int current_mode = 0; char *message = "Clock resolution"; void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; -int try = 0; -int rc = 0; - #define MAXDUR 1000 #define MINDUR 100 -int init (dts_t *buffer, int nb, __attribute__((unused)) pthread_barrier_t *synchro) +int init (dts_t *buffer, int nb, int mode) { /* set global variables */ deltas = buffer; nb_measurements = nb; + current_mode = mode; return 0; } @@ -41,7 +40,7 @@ void *ping (__attribute__((unused)) void *arg) for (int i = -1; i < nb_measurements; i++) { - int duration = MINDUR * ((MAXDUR / MINDUR) * rand () / RAND_MAX); + int duration = MINDUR * (1 + (rand () % (MAXDUR / MINDUR))); usleep (duration); ts_t ts1, ts2; @@ -50,12 +49,12 @@ void *ping (__attribute__((unused)) void *arg) if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); } - pthread_exit (NULL); + RETURN (current_mode, 0); } void *pong (__attribute__((unused)) void *arg) { - pthread_exit (NULL); + RETURN (current_mode, 0); } int finish () diff --git a/cycle.c b/cycle.c index 1b0204b..77976d4 100644 --- a/cycle.c +++ b/cycle.c @@ -1,37 +1,36 @@ /* depend: */ /* cflags: */ -/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */ +/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */ #include #include #include #include +#include "main.h" #include "mtime.h" -#include "test.h" /* global variables */ dts_t *deltas = NULL; int nb_measurements = 0; +int current_mode = 0; char *message = "Cycle accuracy"; void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; -int try = 0; -int rc = 0; - #define MAXDUR 1000 #define MINDUR 100 -int init (dts_t *buffer, int nb, __attribute__((unused)) pthread_barrier_t *synchro) +int init (dts_t *buffer, int nb, int mode) { /* set global variables */ deltas = buffer; nb_measurements = nb; + current_mode = mode; return 0; } @@ -50,12 +49,12 @@ void *ping (__attribute__((unused)) void *arg) if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1) - duration * 1000; } - pthread_exit (NULL); + RETURN (current_mode, 0); } void *pong (__attribute__((unused)) void *arg) { - pthread_exit (NULL); + RETURN (current_mode, 0); } int finish () diff --git a/generic.c b/generic.c new file mode 100644 index 0000000..d180bcb --- /dev/null +++ b/generic.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "main.h" +#include "msg.h" +#include "mtime.h" + +#include "generic.h" + +/* global variables */ + +dts_t *deltas = NULL; +int nb_measurements = 0; +int current_mode = 0; + +#define TIMER 1000 + +sem_t _synchro; +sem_t *synchro; +#define SEMSYNC "/test_sync" +#define MQCOM "/test_com" +ts_t ts1, ts2; + +int init (dts_t *buffer, int nb, int mode) +{ + + /* set global variables */ + + deltas = buffer; + nb_measurements = nb; + current_mode = mode; + + /* synchronization by semaphore */ + + if (current_mode == 0) { + synchro = &_synchro; + if (sem_init (synchro, (current_mode > 0), 0) != 0) { + fprintf (stderr, "error: sem_init\n"); + return 1; + } + } else { + synchro = sem_open (SEMSYNC, O_CREAT, S_IRUSR|S_IWUSR, 0); + if (synchro == NULL) { + fprintf (stderr, "error: sem_open\n"); + return 1; + } + } + + /* communication through mq */ + + if (current_mode == 1) { + struct mq_attr mq_attr = { 0 }; + mq_attr.mq_flags = 0; + mq_attr.mq_maxmsg = 1; + mq_attr.mq_msgsize = sizeof (ts_t); + mq_attr.mq_curmsgs = 0; + + if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { + fprintf (stderr, "error: mq_unlink\n"); + return 1; + } + mqd_t mq = mq_open (MQCOM, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR, &mq_attr); + if (mq == -1) { + fprintf (stderr, "error: mq_open\n"); + return 1; + } + mq_close (mq); + } + + return common_init (); +} + +void *ping (__attribute__((unused)) void *arg) +{ + + if (ping_init ()) { + fprintf (stderr, "ping error: init\n"); + RETURN (current_mode, 1); + } + + /* open mq for communication betwen process */ + + mqd_t mq = (current_mode == 1) ? mq_open (MQCOM, O_RDONLY) : -2; + if (mq == -1) { + fprintf (stderr, "ping error: mq_open\n"); + RETURN (current_mode, 1); + } + + /* main loop */ + + printf ("Sending ping...\n"); + + + for (int i = -1; i < nb_measurements; i++) { + + char *msg = get_msg (MSGLEN); + + sem_wait (synchro); + usleep (TIMER); + + sys_timestamp (&ts1); + if (ping_test (msg, MSGLEN)) { + fprintf (stderr, "ping error: test(send) (%d)\n", i); + RETURN (current_mode, 1); + } + + switch (current_mode) { + case 0: + /* done by thread pong */ + break; + case 1: + if (mq_receive (mq, (char *)&ts2, sizeof (ts2), NULL) == -1) { + fprintf (stderr, "pong error: mq_receive (%d)\n", i); + RETURN (current_mode, 1); + } + if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); + break; + case 2: + /* to do */ + break; + case 3: + /* can't append */ + break; + } + } + + /* close communication between process */ + + if (current_mode == 1) { + mq_close (mq); + } + + ping_finish (); + + RETURN (current_mode, 0); +} + +void *pong (__attribute__((unused)) void *arg) +{ + + if (pong_init ()) { + fprintf (stderr, "pong error: init\n"); + RETURN (current_mode, 1); + } + + /* open mq for communication betwen process */ + + mqd_t mq = (current_mode == 1) ? mq_open (MQCOM, O_WRONLY) : -2; + if (mq == -1) { + fprintf (stderr, "pong error: mq_open\n"); + RETURN (current_mode, 1); + } + + /* main loop */ + + printf ("Receiving pong...\n"); + + for (int i = -1; i < nb_measurements; i++) { + + usleep (TIMER); + sem_post (synchro); + + char buffer[MSGLEN] = { 0 }; + if (pong_test (buffer, sizeof (buffer))) { + fprintf (stderr, "pong error: test(rec) (%d) [%s]\n", i, strerror (errno)); + RETURN (current_mode, 1); + } + sys_timestamp (&ts2); + + switch (current_mode) { + case 0: + if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); + break; + case 1: + if (mq_send (mq, (char *)&ts2, sizeof (ts2), 0) == -1) { + fprintf (stderr, "ping error: mq_send (%d)\n", i); + RETURN (current_mode, 1); + } + break; + case 2: + /* can't append */ + break; + case 3: + /* to do */ + break; + } + } + + /* close communication between process */ + + if (current_mode == 1) { + mq_close (mq); + } + + pong_finish (); + + RETURN (current_mode, 0); +} + +int finish () +{ + + common_finish (); + + /* close semaphore */ + + if (current_mode) { + sem_destroy (synchro); + } else { + sem_close (synchro); + sem_unlink (SEMSYNC); + } + + /* close queue */ + + if (current_mode == 1) { + if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { + fprintf (stderr, "error: mq_unlink\n"); + } + } + + return rc; +} diff --git a/generic.h b/generic.h new file mode 100644 index 0000000..130eb70 --- /dev/null +++ b/generic.h @@ -0,0 +1,23 @@ +#ifndef __GENERIC_H__ +#define __GENERIC_H__ + +#define MAXBUF 1024 +#define MSGLEN 128 + +int common_init (void); + +int ping_init (void); + +int ping_test (char *buffer, int len); + +void ping_finish (void); + +int pong_init (void); + +int pong_test (char *buffer, int len); + +void pong_finish (void); + +void common_finish (void); + +#endif /* __GENERIC_H__ */ diff --git a/main.c b/main.c new file mode 100644 index 0000000..3387156 --- /dev/null +++ b/main.c @@ -0,0 +1,370 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stat.h" + +#include "main.h" + +/* constants */ + +#define RT_PRIO 80 + +/* static variables */ + +char *progname = NULL; +char *version = "1.2"; + +double abe_per = 0; +int delay = 0; +int do_stat = 0; +int excl_first = 0; +int hist_bin = 10; +int mode = 0; +int nb = 1000; +int nb_cores = 0; +char *output = NULL; + +extern char *message; +extern void (*usage_ext) (FILE *); +extern int (*parse_arg_ext) (char *); + +/* usage function */ + +int usage (int ret) +{ + FILE *fd = ret ? stderr : stdout; + fprintf (fd, "usage: %s [-a int] [-b int] [-d int] [-e int] [-h] [-k int] [-m int] [-n int] [-o file] [-s]\n", progname); + fprintf (fd, " -a: avoid aberrand valies (%g%%)\n", abe_per); + fprintf (fd, " -d: delay process start for (%ds)\n", delay); + fprintf (fd, " -b: nb bins for histogram (%d)\n", hist_bin); + fprintf (fd, " -e: exclude %d first tests\n", excl_first); + fprintf (fd, " -h: help message\n"); + fprintf (fd, " -k: nb dedicated cores (%d)\n", nb_cores); + fprintf (fd, " -m: 0 for threads, 1 ping-pong process, 2 ping process, 3 pong process (%d)\n", mode); + fprintf (fd, " -n: nb measurements (%d)\n", nb); + fprintf (fd, " -o: output raw data (%s)\n", (output) ? output : "none"); + fprintf (fd, " -s: display statistics (%s)\n", (do_stat) ? "yes" : "no"); + if (usage_ext) { + fprintf (fd, "extension:\n"); + usage_ext (fd); + } + fprintf (fd, "%s version %s\n", progname, version); + + return ret; +} + +/* launch ping and pong */ + +#define SEMSIG "/test_sig" +#define SEMACT "/test_act" +sem_t _sem_sig, _sem_act; +sem_t *sem_sig, *sem_act; + +typedef struct { + int synchro; + int target; + void *(*func)(void *arg); +} launch_param_t; + +void *launch (void *arg) +{ + launch_param_t *param = (launch_param_t *)arg; + int cpu = (nb_cores == 1) ? 0 : (nb_cores == 2) ? param->target : -1; + if (cpu != -1) { + cpu_set_t cpu_mask; + CPU_ZERO (&cpu_mask); + CPU_SET (cpu, &cpu_mask); + if (sched_setaffinity (0, sizeof (cpu_set_t), &cpu_mask) != 0) { + fprintf (stderr, "error: sched_setaffinity (%d)\n", cpu); + RETURN (mode, 1); + } + } + if (param->synchro) { + switch (param->target) { + case 0: + sem_wait (sem_sig); + sem_post (sem_act); + break; + case 1: + sem_post (sem_sig); + sem_wait (sem_act); + break; + } + } + return param->func (arg); +} + +/* main function */ + +int main (int argc, char *argv[]) +{ + + /* get basename */ + + char *pt = progname = argv[0]; + while (*pt) { + if ((*pt == '/') || (*pt == '\\')) { + progname = pt + 1; + } + pt++; + } + + /* process arguments */ + + while (argc-- > 1) { + char *arg = *(++argv); + if (arg[0] != '-') { + if ((!parse_arg_ext) || (parse_arg_ext (arg))) { + fprintf (stderr, "%s: invalid option -- %s\n", progname, arg); + return usage (1); + } + continue; + } + char c = arg[1]; + switch (c) { + case 'a': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no aberrant percent specified\n", progname); + return usage (1); + } + abe_per = strtod (arg, NULL); + break; + case 'b': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no number of bins specified\n", progname); + return usage (1); + } + hist_bin = atoi (arg); + break; + case 'd': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no delay specified\n", progname); + return usage (1); + } + delay = atoi (arg); + break; + case 'e': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no number of first to exclude specified\n", progname); + return usage (1); + } + excl_first = atoi (arg); + break; + case 'k': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no number of dedicated cores specified\n", progname); + return usage (1); + } + nb_cores = atoi (arg); + break; + case 'm': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no mode specified\n", progname); + return usage (1); + } + mode = atoi (arg); + break; + case 'n': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no number of measurements specified\n", progname); + return usage (1); + } + nb = atoi (arg); + break; + case 'o': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + fprintf (stderr, "%s: no output file specified\n", progname); + return usage (1); + } + output = arg; + break; + case 's': + do_stat = 1; + break; + case 'v': + printf ("version: %s\n", version); + break; + case 'h': + default: + return usage (c != 'h'); + } + } + + /* real-time process */ + + struct sched_param param = {0}; + if (sched_getparam (0, ¶m) != 0) { + fprintf (stderr, "error: sched_getparam\n"); + return 1; + } + param.sched_priority = RT_PRIO; + int rc = sched_setscheduler (0, SCHED_FIFO, ¶m); /* non-preemptive */ + // int rc = sched_setscheduler (0, SCHED_RR, ¶m); /* preemptive */ + if (rc != 0) { + fprintf (stderr, "error: sched_setscheduler\n"); + return 1; + } + + /* main process */ + + dts_t *buffer = (dts_t *) calloc (nb, sizeof (dts_t)); + assert (buffer); + + if (delay > 0) { + printf ("Delay start for %ds\n", delay); + for (int i = 0; i < 100 * delay; i++) { + usleep (10 * 1000); + } + } + + printf ("Test: %s\n", (message) ? message : "unknown"); + printf ("Dedicated core(s): %d\n", nb_cores); + + if (init (buffer, nb, mode)) { + fprintf (stderr, "error on init\n"); + return 1; + } + + launch_param_t sync_ping = { 1, 0, ping }; + launch_param_t sync_pong = { 1, 1, pong }; + launch_param_t async_ping = { 0, 0, ping }; + launch_param_t async_pong = { 0, 0, pong }; + switch (mode){ + case 0: + printf ("thread mode\n"); + if ((sem_init (sem_sig = &_sem_sig, 0, 0) != 0) || (sem_init (sem_act = &_sem_act, 0, 0) != 0)) { + fprintf (stderr, "error: sem_init\n"); + return 1; + } else { + pthread_t tid1, tid2; + if (pthread_create (&tid1, NULL, launch, &sync_ping) != 0) { + fprintf (stderr, "error on pthread_create\n"); + return 1; + } + if (pthread_create (&tid2, NULL, launch, &sync_pong) != 0) { + fprintf (stderr, "error on pthread_create\n"); + return 1; + } + pthread_join (tid1, NULL); + pthread_join (tid2, NULL); + sem_destroy (sem_act); + sem_destroy (sem_sig); + } + break; + case 1: + printf ("process mode\n"); + sem_sig = sem_open (SEMSIG, O_CREAT, S_IRUSR|S_IWUSR, 0); + sem_act = sem_open (SEMACT, O_CREAT, S_IRUSR|S_IWUSR, 0); + if ((sem_sig == NULL) || (sem_act == NULL)) { + fprintf (stderr, "error: sem_open\n"); + return 1; + } else { + pid_t pid = fork (); + if (pid == -1) { + fprintf (stderr, "error: fork\n"); + return 1; + } else if (pid > 0) { + launch (&sync_ping); + } else { + launch (&sync_pong); + } + sem_close (sem_act); + sem_unlink (SEMACT); + sem_close (sem_sig); + sem_unlink (SEMSIG); + if (pid == 0) { + return finish (); + } + if (kill (pid, SIGTERM) == 0) { + int wstatus; + if (waitpid (pid, &wstatus, WUNTRACED | WCONTINUED) == -1) { + fprintf (stderr, "error: waitpid\n"); + } + } + } + break; + case 2: + printf ("ping mode\n"); + launch (&async_ping); + break; + case 3: + printf ("pong mode\n"); + launch (&async_pong); + return finish (); + } + + if (finish ()) { + printf ("\033[1;31mKO\033[0;0m\n"); + return 1; + } else { + printf ("\033[1;32mOK\033[0;0m\n"); + } + + if (output) { + FILE *fd = fopen (output, "w"); + assert (fd); + for (int i = 0; i < nb; i++) { + fprintf (fd, "%ld\n", buffer[i]); + } + fclose (fd); + } + + if (do_stat) { + + if (excl_first) { + for (int i = 0; i < nb - excl_first; i++) { + buffer[i] = buffer[i + excl_first]; + } + nb -= excl_first; + } + + if (abe_per != 0) { + int n = nb * abe_per / 100; + for (int j = 0; j < n / 2; j++) { + int imax = 0; + int imin = 0; + for (int i = 1; i < nb; i++) { + if (buffer[i] > buffer[imax]) { + imax = i; + } + if (buffer[i] < buffer[imin]) { + imin = i; + } + } + for (int i = 0, jump = 0; i < nb; i++) { + if ((i == imax) || (i == imin)) { + jump++; + } else { + buffer[i - jump] = buffer[i]; + } + } + nb -= 2; + } + } + + compute_statistics (buffer, nb, hist_bin); + } + + free (buffer); + + return 0; +} diff --git a/main.h b/main.h new file mode 100644 index 0000000..f40e2ae --- /dev/null +++ b/main.h @@ -0,0 +1,17 @@ +#ifndef __MAIN_H__ +#define __MAIN_H__ + +#include "mtime.h" + +static int rc = 0; +#define RETURN(m, v) do { rc = (v); if ((m) == 0) pthread_exit (NULL); else return NULL; } while (0) + +int init (dts_t *buffer, int nb, int mode); + +void *ping (void *arg); + +void *pong (void *arg); + +int finish (); + +#endif /* __MAIN_H__ */ diff --git a/mq.c b/mq.c new file mode 100644 index 0000000..7004013 --- /dev/null +++ b/mq.c @@ -0,0 +1,83 @@ +/* depend: */ +/* cflags: */ +/* linker: generic.o main.o msg.o mtime.o stat.o -lm -lpthread -lrt */ + +#include +#include +#include +#include +#include + +#include "generic.h" + +/* global variables */ + +char *message = "Message queue latency"; +void (*usage_ext) (FILE *) = NULL; +int (*parse_arg_ext) (char *) = NULL; + +#define QNAME "/test_queue" +mqd_t mqin, mqout; + +/* test functions */ + +int common_init (void) +{ + struct mq_attr mq_attr = { 0 }; + mq_attr.mq_flags = 0; + mq_attr.mq_maxmsg = 5; + mq_attr.mq_msgsize = MSGLEN; + mq_attr.mq_curmsgs = 0; + + if ((mq_unlink (QNAME) != 0) && errno != ENOENT) { + fprintf (stderr, "error: mq_unlink\n"); + return 1; + } + mqd_t mq = mq_open (QNAME, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR, &mq_attr); + if (mq == -1) { + fprintf (stderr, "error: mq_open\n"); + return 1; + } + mq_close (mq); + + return 0; +} + +int ping_init (void) +{ + mqout = mq_open (QNAME, O_WRONLY); + return (mqout == -1); +} + +int ping_test (char *buffer, int len) +{ + return (mq_send (mqout, buffer, len, 0) == -1); +} + +void ping_finish (void) +{ + mq_close (mqout); +} + +int pong_init (void) +{ + mqin = mq_open (QNAME, O_RDONLY); + return (mqin == -1); +} + +int pong_test (char *buffer, int len) +{ + return ((len != MSGLEN) || (mq_receive (mqin, buffer, MSGLEN, NULL) == -1)); +} + +void pong_finish (void) +{ + mq_close (mqin); +} + +void common_finish (void) +{ + if ((mq_unlink (QNAME) != 0) && errno != ENOENT) { + fprintf (stderr, "error: mq_unlink\n"); + } +} diff --git a/mq_lat.c b/mq_lat.c deleted file mode 100644 index b1cffd6..0000000 --- a/mq_lat.c +++ /dev/null @@ -1,155 +0,0 @@ -/* depend: */ -/* cflags: */ -/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */ - -#include -#include -#include -#include - -#include /* For O_* constants */ -#include /* For mode constants */ -#include - -#include -#include - -#include "msg.h" -#include "mtime.h" -#include "test.h" - -/* global variables */ - -dts_t *deltas = NULL; -int nb_measurements = 0; - -char *message = "Message queue latency"; -void (*usage_ext) (FILE *) = NULL; -int (*parse_arg_ext) (char *) = NULL; - -#define QNAME "/test_queue" -#define MSGLEN 128 -#define MAXBUF 1024 -#define TIMER 1000 - -pthread_barrier_t *barrier = NULL; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;; -ts_t ts1, ts2; -int rc = 0; - -void *ping (__attribute__((unused)) void *arg) -{ - - mqd_t mq_out = mq_open (QNAME, O_WRONLY); - if (mq_out == -1) { - fprintf (stderr, "ping error: mq_open\n"); - rc = 1; - pthread_exit (NULL); - } - - /* main loop */ - - pthread_barrier_wait (barrier); - printf ("Sending ping...\n"); - - usleep (TIMER); - - for (int i = -1; i < nb_measurements; i++) { - - char *msg = get_msg (MSGLEN); - - pthread_mutex_lock (&mutex); - pthread_mutex_unlock (&mutex); - - usleep (TIMER / 2); - - sys_timestamp (&ts1); - if (mq_send (mq_out, msg, MSGLEN, 0) == -1) { - fprintf (stderr, "ping error: mq_send (%d)\n", i); - rc = 1; - pthread_exit (NULL); - } - usleep (TIMER); - } - - mq_close (mq_out); - - pthread_exit (NULL); -} - -void *pong (__attribute__((unused)) void *arg) -{ - - mqd_t mq_in = mq_open (QNAME, O_RDONLY); - if (mq_in == -1) { - fprintf (stderr, "error pong: mq_open\n"); - rc = 1; - pthread_exit (NULL); - } - - pthread_barrier_wait (barrier); - printf ("Receiving pong...\n"); - - for (int i = -1; i < nb_measurements; i++) { - - pthread_mutex_lock (&mutex); - usleep (TIMER); - pthread_mutex_unlock (&mutex); - - char buffer[MAXBUF] = { 0 }; - if (mq_receive (mq_in, buffer, sizeof (buffer), NULL) == -1) { - fprintf (stderr, "pong error: mq_receive (%d)\n", i); - rc = 1; - pthread_exit (NULL); - } - - sys_timestamp (&ts2); - if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); - } - - mq_close (mq_in); - - pthread_exit (NULL); -} - -int init (dts_t *buffer, int nb, pthread_barrier_t *synchro) -{ - - /* set global variables */ - - deltas = buffer; - nb_measurements = nb; - barrier = synchro; - - /* open mq */ - - struct mq_attr mq_attr = { 0 }; - mq_attr.mq_flags = 0; - mq_attr.mq_maxmsg = 5; - mq_attr.mq_msgsize = MAXBUF; - mq_attr.mq_curmsgs = 0; - - if ((mq_unlink (QNAME) != 0) && errno != ENOENT) { - fprintf (stderr, "error: mq_unlink\n"); - return 1; - } - mqd_t mq = mq_open (QNAME, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR, &mq_attr); - if (mq == -1) { - fprintf (stderr, "error: mq_open\n"); - return 1; - } - mq_close (mq); - - return 0; -} - -int finish () -{ - - if ((mq_unlink (QNAME) != 0) && errno != ENOENT) { - fprintf (stderr, "error: mq_unlink\n"); - return 1; - } - - return rc; -} diff --git a/mutex.c b/mutex.c index 8470b97..a804a1f 100644 --- a/mutex.c +++ b/mutex.c @@ -1,61 +1,79 @@ /* depend: */ /* cflags: */ -/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */ +/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */ #include #include #include +#include #include +#include "main.h" #include "mtime.h" -#include "test.h" /* global variables */ dts_t *deltas = NULL; int nb_measurements = 0; +int current_mode = 0; char *message = "Mutex latency"; void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; -pthread_barrier_t *barrier = NULL; -sem_t sem; +sem_t synchro; pthread_mutex_t test = PTHREAD_MUTEX_INITIALIZER; volatile int shared_flag = 0; ts_t ts1={0}, ts2={0}; -int rc = 0; #define TIMER 1000 -void *ping (__attribute__((unused)) void *arg) +int init (dts_t *buffer, int nb, int mode) { - pthread_barrier_wait (barrier); + if (mode != 0) { + fprintf (stderr, "only avaible in thread mode\n"); + return 1; + } + + /* set global variables */ + + deltas = buffer; + nb_measurements = nb; + current_mode = mode; + + if (sem_init (&synchro, 0, 0) != 0) { + fprintf (stderr, "error: sem_init\n"); + return 1; + } + + return 0; +} + +void *ping (__attribute__((unused)) void *arg) +{ for (int i = -1; i < nb_measurements; i++) { usleep (TIMER); pthread_mutex_lock (&test); - sem_post (&sem); + sem_post (&synchro); usleep (TIMER); sys_timestamp (&ts1); pthread_mutex_unlock (&test); } - pthread_exit (NULL); + RETURN (current_mode, 0); } void *pong (__attribute__((unused)) void *arg) { - pthread_barrier_wait (barrier); - for (int i = -1; i < nb_measurements; i++) { - sem_wait (&sem); + sem_wait (&synchro); pthread_mutex_lock (&test); sys_timestamp (&ts2); @@ -63,27 +81,13 @@ void *pong (__attribute__((unused)) void *arg) pthread_mutex_unlock (&test); } - pthread_exit (NULL); -} - -int init (dts_t *buffer, int nb, pthread_barrier_t *synchro) -{ - - /* set global variables */ - - deltas = buffer; - nb_measurements = nb; - barrier = synchro; - - sem_init (&sem, 0, 0); - - return 0; + RETURN (current_mode, 0); } int finish () { - sem_destroy (&sem); + sem_destroy (&synchro); return rc; } diff --git a/pipe.c b/pipe.c new file mode 100644 index 0000000..f3bd50f --- /dev/null +++ b/pipe.c @@ -0,0 +1,62 @@ +/* depend: */ +/* cflags: */ +/* linker: generic.o main.o msg.o mtime.o stat.o -lm -lpthread -lrt */ + +#include +#include + +#include "generic.h" + +/* global variables */ + +char *message = "Pipe latency"; +void (*usage_ext) (FILE *) = NULL; +int (*parse_arg_ext) (char *) = NULL; + +int fdin, fdout; + +/* test functions */ + +int common_init (void) +{ + int pipefd[2] = { 0 }; + if (pipe (pipefd) == -1) { + fprintf (stderr, "error: pipe\n"); + return 1; + } + + fdin = pipefd[0]; + fdout = pipefd[1]; + + return 0; +} + +int ping_init (void) +{ + return 0; +} + +int ping_test (char *buffer, int len) +{ + return (write (fdout, buffer, len) == -1); +} + +void ping_finish (void) { } + +int pong_init (void) +{ + return 0; +} + +int pong_test (char *buffer, int len) +{ + return (read (fdin, buffer, len) == -1); +} + +void pong_finish (void) { } + +void common_finish (void) +{ + close (fdin); + close (fdout); +} diff --git a/pipe_lat.c b/pipe_lat.c deleted file mode 100644 index 669975d..0000000 --- a/pipe_lat.c +++ /dev/null @@ -1,237 +0,0 @@ -/* depend: */ -/* cflags: */ -/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msg.h" -#include "mtime.h" -#include "test.h" - -/* global variables */ - -dts_t *deltas = NULL; -int nb_measurements = 0; -int current_mode = 0; - -char *message = "Pipe latency"; -void (*usage_ext) (FILE *) = NULL; -int (*parse_arg_ext) (char *) = NULL; - -#define MSGLEN 128 -#define MAXBUF 1024 -#define TIMER 1000 - -sem_t _synchro; -sem_t *synchro; -#define SEMSYNC "/sem_sync" -#define MQCOM "/test_com" -ts_t ts1, ts2; -int pipefd[2] = { 0 }; -int rc = 0; - -#define RETURN(v) do { rc = (v); if (current_mode == 0) pthread_exit (NULL); else return NULL; } while (0) - -void *ping (__attribute__((unused)) void *arg) -{ - - /* select pipe */ - - int fdout = pipefd[1]; - - /* open mq for communication betwen process */ - mqd_t mq = (current_mode == 1) ? mq_open (MQCOM, O_RDONLY) : -2; - if (mq == -1) { - fprintf (stderr, "ping error: mq_open\n"); - RETURN (1); - } - - /* main loop */ - - printf ("Sending ping...\n"); - - - for (int i = -1; i < nb_measurements; i++) { - - char *msg = get_msg (MSGLEN); - - sem_wait (synchro); - usleep (TIMER); - - sys_timestamp (&ts1); - if (write (fdout, msg, MSGLEN) == -1) { - fprintf (stderr, "ping error: write (%d)\n", i); - RETURN (1); - } - - switch (current_mode) { - case 0: - /* done by thread pong */ - break; - case 1: - if (mq_receive (mq, (char *)&ts2, sizeof (ts2), NULL) == -1) { - fprintf (stderr, "pong error: mq_receive (%d)\n", i); - RETURN (1); - } - if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); - break; - case 2: - /* to do */ - break; - case 3: - /* can't append */ - break; - } - } - - /* close communication between process */ - - if (current_mode == 1) { - mq_close (mq); - } - - RETURN (0); -} - -void *pong (__attribute__((unused)) void *arg) -{ - - /* select pipe */ - - int fdin = pipefd[0]; - - /* open mq for communication betwen process */ - mqd_t mq = (current_mode == 1) ? mq_open (MQCOM, O_WRONLY) : -2; - if (mq == -1) { - fprintf (stderr, "pong error: mq_open\n"); - RETURN (1); - } - - /* main loop */ - - printf ("Receiving pong...\n"); - - for (int i = -1; i < nb_measurements; i++) { - - usleep (TIMER); - sem_post (synchro); - - char buffer[MAXBUF] = { 0 }; - if (read (fdin, buffer, sizeof(buffer)) == -1) { - fprintf (stderr, "pong error: read (%d)\n", i); - RETURN (1); - } - sys_timestamp (&ts2); - - switch (current_mode) { - case 0: - if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); - break; - case 1: - if (mq_send (mq, (char *)&ts2, sizeof (ts2), 0) == -1) { - fprintf (stderr, "ping error: mq_send (%d)\n", i); - RETURN (1); - } - break; - case 2: - /* can't append */ - break; - case 3: - /* to do */ - break; - } - } - - /* close communication between process */ - - if (current_mode == 1) { - mq_close (mq); - } - - RETURN (0); -} - -int init (dts_t *buffer, int nb, int mode) -{ - - /* set global variables */ - - deltas = buffer; - nb_measurements = nb; - current_mode = mode; - - /* synchronization by semaphore */ - - if (current_mode == 0) { - synchro = &_synchro; - if (sem_init (synchro, (current_mode > 0), 0) != 0) { - fprintf (stderr, "error: sem_init\n"); - return 1; - } - } else { - synchro = sem_open (SEMSYNC, O_CREAT, S_IRUSR|S_IWUSR, 0); - if (synchro == NULL) { - fprintf (stderr, "error: sem_open\n"); - return 1; - } - } - - /* communication through mq */ - - if (current_mode == 1) { - struct mq_attr mq_attr = { 0 }; - mq_attr.mq_flags = 0; - mq_attr.mq_maxmsg = 1; - mq_attr.mq_msgsize = sizeof (ts_t); - mq_attr.mq_curmsgs = 0; - - if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { - fprintf (stderr, "error: mq_unlink\n"); - return 1; - } - mqd_t mq = mq_open (MQCOM, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR, &mq_attr); - if (mq == -1) { - fprintf (stderr, "error: mq_open\n"); - return 1; - } - mq_close (mq); - } - - /* open pipe */ - - if (pipe (pipefd) == -1) { - fprintf (stderr, "error: pipe\n"); - return 1; - } - - return 0; -} - -int finish () -{ - - /* close pipe */ - - close (pipefd[0]); - close (pipefd[1]); - - /* close semaphore */ - - if (current_mode) { - sem_destroy (synchro); - } else { - sem_close (synchro); - sem_unlink (SEMSYNC); - } - - return rc; -} diff --git a/pipe_lat_multi.c b/pipe_lat_multi.c deleted file mode 100644 index 4977a8e..0000000 --- a/pipe_lat_multi.c +++ /dev/null @@ -1,197 +0,0 @@ -/* depend: */ -/* cflags: */ -/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "msg.h" -#include "mtime.h" -#include "test_multi.h" - -/* global variables */ - -dts_t *deltas = NULL; -int nb_measurements = 0; - -char *message = "Pipe latency"; -void (*usage_ext) (FILE *) = NULL; -int (*parse_arg_ext) (char *) = NULL; - -#define MSGLEN 128 -#define MAXBUF 1024 -#define TIMER 1000 - -sem_t synchro; -#define MQCOM "/test_com" -ts_t ts1, ts2; -int pipefd[2] = { 0 }; -int rc = 0; - -int ping (void) -{ - - /* open mq for communication betwen process */ - - mqd_t mq = mq_open (MQCOM, O_RDONLY); - if (mq == -1) { - fprintf (stderr, "ping error: mq_open\n"); - return 1; - } - - /* select pipe */ - - int fdin = pipefd[0]; - int fdout = pipefd[1]; - - /* main loop */ - - printf ("Sending ping...\n"); - - - for (int i = -1; i < nb_measurements; i++) { - - char *msg = get_msg (MSGLEN); - - sem_wait (&synchro); - usleep (TIMER); - - sys_timestamp (&ts1); - if (write (fdout, msg, MSGLEN) == -1) { - fprintf (stderr, "ping error: write (%d)\n", i); - return 1; - } - - if (mq_receive (mq, (char *)&ts2, sizeof (ts2), NULL) == -1) { - fprintf (stderr, "pong error: mq_receive (%d)\n", i); - return 1; - } - - if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); - } - - /* close pipe */ - - close (fdin); - close (fdout); - - /* close communication between process */ - - mq_close (mq); - - return 0; -} - -int pong (void) -{ - - /* open mq for communication betwen process */ - - mqd_t mq = mq_open (MQCOM, O_WRONLY); - if (mq == -1) { - fprintf (stderr, "ping error: mq_open\n"); - return 1; - } - - /* select pipe */ - - int fdin = pipefd[0]; - int fdout = pipefd[1]; - - /* main loop */ - - printf ("Receiving pong...\n"); - - for (int i = -1; i < nb_measurements; i++) { - - usleep (TIMER); - sem_post (&synchro); - - char buffer[MAXBUF] = { 0 }; - if (read (fdin, buffer, sizeof(buffer)) == -1) { - fprintf (stderr, "pong error: read (%d)\n", i); - return 1; - } - - sys_timestamp (&ts2); - if (mq_send (mq, (char *)&ts2, sizeof (ts2), 0) == -1) { - fprintf (stderr, "ping error: mq_send (%d)\n", i); - return 1; - } - } - - /* close pipe */ - - close (fdin); - close (fdout); - - /* close communication between process */ - - mq_close (mq); - - return 0; -} - -int init (dts_t *buffer, int nb) -{ - - /* set global variables */ - - deltas = buffer; - nb_measurements = nb; - - /* synchronization by semaphore */ - - if (sem_init (&synchro, 1, 0) != 0) { - fprintf (stderr, "error: sem_init\n"); - return 1; - } - - /* communication through mq */ - - struct mq_attr mq_attr = { 0 }; - mq_attr.mq_flags = 0; - mq_attr.mq_maxmsg = 1; - mq_attr.mq_msgsize = sizeof (ts_t); - mq_attr.mq_curmsgs = 0; - - if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { - fprintf (stderr, "error: mq_unlink\n"); - return 1; - } - mqd_t mq = mq_open (MQCOM, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR, &mq_attr); - if (mq == -1) { - fprintf (stderr, "error: mq_open\n"); - return 1; - } - mq_close (mq); - - /* open pipe */ - - if (pipe (pipefd) == -1) { - fprintf (stderr, "error: pipe\n"); - return 1; - } - - return 0; -} - -int finish () -{ - - /* erase message queue */ - - if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { - fprintf (stderr, "error: mq_unlink\n"); - return 1; - } - - return 0; -} diff --git a/semaphore.c b/semaphore.c index 3b48fec..2721489 100644 --- a/semaphore.c +++ b/semaphore.c @@ -1,85 +1,204 @@ /* depend: */ /* cflags: */ -/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */ +/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */ +#include +#include +#include +#include +#include #include #include - -#include - -#include +#include #include +#include "main.h" #include "mtime.h" -#include "test.h" /* global variables */ dts_t *deltas = NULL; int nb_measurements = 0; +int current_mode = 0; char *message = "Semaphore latency"; void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; -pthread_barrier_t *barrier = NULL; volatile int shared_flag = 0; ts_t ts1, ts2; -sem_t sem; -int rc = 0; +#define SEMTEST "/test_sem" +#define MQCOM "/test_com" +sem_t _sem; +sem_t *sem; #define TIMER 1000 +int init (dts_t *buffer, int nb, int mode) +{ + + /* set global variables */ + + deltas = buffer; + nb_measurements = nb; + current_mode = mode; + + /* semaphore test */ + + if (current_mode == 0) { + sem = &_sem; + if (sem_init (sem, (current_mode > 0), 0) != 0) { + fprintf (stderr, "error: sem_init\n"); + return 1; + } + } else { + sem = sem_open (SEMTEST, O_CREAT, S_IRUSR|S_IWUSR, 0); + if (sem == NULL) { + fprintf (stderr, "error: sem_open\n"); + return 1; + } + } + + /* communication through mq */ + + if (current_mode == 1) { + struct mq_attr mq_attr = { 0 }; + mq_attr.mq_flags = 0; + mq_attr.mq_maxmsg = 1; + mq_attr.mq_msgsize = sizeof (ts_t); + mq_attr.mq_curmsgs = 0; + + if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { + fprintf (stderr, "error: mq_unlink\n"); + return 1; + } + mqd_t mq = mq_open (MQCOM, O_CREAT | O_RDWR, S_IWUSR | S_IRUSR, &mq_attr); + if (mq == -1) { + fprintf (stderr, "error: mq_open\n"); + return 1; + } + mq_close (mq); + } + + return 0; +} + void *ping (__attribute__((unused)) void *arg) { - pthread_barrier_wait (barrier); + /* open mq for communication betwen process */ + mqd_t mq = (current_mode == 1) ? mq_open (MQCOM, O_RDONLY) : -2; + if (mq == -1) { + fprintf (stderr, "ping error: mq_open\n"); + RETURN (current_mode, 1); + } + + /* main loop */ + + printf ("Sending ping...\n"); for (int i = -1; i < nb_measurements; i++) { usleep (TIMER); sys_timestamp (&ts1); - sem_post (&sem); + sem_post (sem); + + switch (current_mode) { + case 0: + /* done by thread pong */ + break; + case 1: + if (mq_receive (mq, (char *)&ts2, sizeof (ts2), NULL) == -1) { + fprintf (stderr, "pong error: mq_receive (%d)\n", i); + RETURN (current_mode, 1); + } + if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); + break; + case 2: + /* to do */ + break; + case 3: + /* can't append */ + break; + } + } + + /* close communication between process */ + + if (current_mode == 1) { + mq_close (mq); } - pthread_exit (NULL); + RETURN (current_mode, 0); } void *pong (__attribute__((unused)) void *arg) { - pthread_barrier_wait (barrier); - - for (int i = -1; i < nb_measurements; i++) { + /* open mq for communication betwen process */ - sem_wait (&sem); - sys_timestamp (&ts2); - if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); + mqd_t mq = (current_mode == 1) ? mq_open (MQCOM, O_WRONLY) : -2; + if (mq == -1) { + fprintf (stderr, "pong error: mq_open\n"); + RETURN (current_mode, 1); } - pthread_exit (NULL); -} + /* main loop */ -int init (dts_t *buffer, int nb, pthread_barrier_t *synchro) -{ + printf ("Receiving pong...\n"); - /* set global variables */ + for (int i = -1; i < nb_measurements; i++) { - deltas = buffer; - nb_measurements = nb; - barrier = synchro; + sem_wait (sem); + sys_timestamp (&ts2); - /* semaphore test */ + switch (current_mode) { + case 0: + if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); + break; + case 1: + if (mq_send (mq, (char *)&ts2, sizeof (ts2), 0) == -1) { + fprintf (stderr, "ping error: mq_send (%d)\n", i); + RETURN (current_mode, 1); + } + break; + case 2: + /* can't append */ + break; + case 3: + /* to do */ + break; + } + } - sem_init (&sem, 0, 0); + /* close communication between process */ - return 0; + if (current_mode == 1) { + mq_close (mq); + } + + RETURN (current_mode, 0); } int finish () { - sem_destroy (&sem); + /* close semaphore */ + + if (current_mode) { + sem_destroy (sem); + } else { + sem_close (sem); + sem_unlink (SEMTEST); + } + + /* close queue */ + + if (current_mode == 1) { + if ((mq_unlink (MQCOM) != 0) && errno != ENOENT) { + fprintf (stderr, "error: mq_unlink\n"); + } + } return rc; } diff --git a/test.c b/test.c deleted file mode 100644 index e82d5a1..0000000 --- a/test.c +++ /dev/null @@ -1,371 +0,0 @@ -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "stat.h" -#include "test.h" - -/* constants */ - -#define RT_PRIO 80 - -/* static variables */ - -char *progname = NULL; -char *version = "1.2"; - -double abe_per = 0; -int delay = 0; -int do_stat = 0; -int excl_first = 0; -int hist_bin = 10; -int mode = 0; -int nb = 1000; -int nb_cores = 0; -char *output = NULL; - -extern char *message; -extern void (*usage_ext) (FILE *); -extern int (*parse_arg_ext) (char *); -extern int rc; - -/* usage function */ - -int usage (int ret) -{ - FILE *fd = ret ? stderr : stdout; - fprintf (fd, "usage: %s [-a int] [-b int] [-d int] [-e int] [-h] [-k int] [-m int] [-n int] [-o file] [-s]\n", progname); - fprintf (fd, " -a: avoid aberrand valies (%g%%)\n", abe_per); - fprintf (fd, " -d: delay process start for (%ds)\n", delay); - fprintf (fd, " -b: nb bins for histogram (%d)\n", hist_bin); - fprintf (fd, " -e: exclude %d first tests\n", excl_first); - fprintf (fd, " -h: help message\n"); - fprintf (fd, " -k: nb dedicated cores (%d)\n", nb_cores); - fprintf (fd, " -m: 0 for threads, 1 ping-pong process, 2 ping process, 3 pong process (%d)\n", mode); - fprintf (fd, " -n: nb measurements (%d)\n", nb); - fprintf (fd, " -o: output raw data (%s)\n", (output) ? output : "none"); - fprintf (fd, " -s: display statistics (%s)\n", (do_stat) ? "yes" : "no"); - if (usage_ext) { - fprintf (fd, "extension:\n"); - usage_ext (fd); - } - fprintf (fd, "%s version %s\n", progname, version); - - return ret; -} - -/* launch ping and pong */ - -#define SEMSIG "/sem_sig" -#define SEMACT "/sem_act" -sem_t _sem_sig, _sem_act; -sem_t *sem_sig, *sem_act; - -typedef struct { - int synchro; - int target; - void *(*func)(void *arg); -} launch_param_t; - -void *launch (void *arg) -{ - launch_param_t *param = (launch_param_t *)arg; - int cpu = (nb_cores == 1) ? 0 : (nb_cores == 2) ? param->target : -1; - if (cpu != -1) { - cpu_set_t cpu_mask; - CPU_ZERO (&cpu_mask); - CPU_SET (cpu, &cpu_mask); - if (sched_setaffinity (0, sizeof (cpu_set_t), &cpu_mask) != 0) { - fprintf (stderr, "error: sched_setaffinity (%d)\n", cpu); - rc = 1; - if (mode == 0) pthread_exit (NULL); else return NULL; - } - } - if (param->synchro) { - switch (param->target) { - case 0: - sem_wait (sem_sig); - sem_post (sem_act); - break; - case 1: - sem_post (sem_sig); - sem_wait (sem_act); - break; - } - } - return param->func (arg); -} - -/* main function */ - -int main (int argc, char *argv[]) -{ - - /* get basename */ - - char *pt = progname = argv[0]; - while (*pt) { - if ((*pt == '/') || (*pt == '\\')) { - progname = pt + 1; - } - pt++; - } - - /* process arguments */ - - while (argc-- > 1) { - char *arg = *(++argv); - if (arg[0] != '-') { - if ((!parse_arg_ext) || (parse_arg_ext (arg))) { - fprintf (stderr, "%s: invalid option -- %s\n", progname, arg); - return usage (1); - } - continue; - } - char c = arg[1]; - switch (c) { - case 'a': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no aberrant percent specified\n", progname); - return usage (1); - } - abe_per = strtod (arg, NULL); - break; - case 'b': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of bins specified\n", progname); - return usage (1); - } - hist_bin = atoi (arg); - break; - case 'd': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no delay specified\n", progname); - return usage (1); - } - delay = atoi (arg); - break; - case 'e': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of first to exclude specified\n", progname); - return usage (1); - } - excl_first = atoi (arg); - break; - case 'k': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of dedicated cores specified\n", progname); - return usage (1); - } - nb_cores = atoi (arg); - break; - case 'm': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no mode specified\n", progname); - return usage (1); - } - mode = atoi (arg); - break; - case 'n': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of measurements specified\n", progname); - return usage (1); - } - nb = atoi (arg); - break; - case 'o': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no output file specified\n", progname); - return usage (1); - } - output = arg; - break; - case 's': - do_stat = 1; - break; - case 'v': - printf ("version: %s\n", version); - break; - case 'h': - default: - return usage (c != 'h'); - } - } - - /* real-time process */ - - struct sched_param param = {0}; - if (sched_getparam (0, ¶m) != 0) { - fprintf (stderr, "error: sched_getparam\n"); - return 1; - } - param.sched_priority = RT_PRIO; - int rc = sched_setscheduler (0, SCHED_FIFO, ¶m); /* non-preemptive */ - // int rc = sched_setscheduler (0, SCHED_RR, ¶m); /* preemptive */ - if (rc != 0) { - fprintf (stderr, "error: sched_setscheduler\n"); - return 1; - } - - /* main process */ - - dts_t *buffer = (dts_t *) calloc (nb, sizeof (dts_t)); - assert (buffer); - - if (delay > 0) { - printf ("Delay start for %ds\n", delay); - for (int i = 0; i < 100 * delay; i++) { - usleep (10 * 1000); - } - } - - printf ("Test: %s\n", (message) ? message : "unknown"); - printf ("Dedicated core(s): %d\n", nb_cores); - - if (init (buffer, nb, mode)) { - fprintf (stderr, "error on init\n"); - return 1; - } - - launch_param_t sync_ping = { 1, 0, ping }; - launch_param_t sync_pong = { 1, 1, pong }; - launch_param_t async_ping = { 0, 0, ping }; - launch_param_t async_pong = { 0, 0, pong }; - switch (mode){ - case 0: - printf ("thread mode\n"); - if ((sem_init (sem_sig = &_sem_sig, 0, 0) != 0) || (sem_init (sem_act = &_sem_act, 0, 0) != 0)) { - fprintf (stderr, "error: sem_init\n"); - return 1; - } else { - pthread_t tid1, tid2; - if (pthread_create (&tid1, NULL, launch, &sync_ping) != 0) { - fprintf (stderr, "error on pthread_create\n"); - return 1; - } - if (pthread_create (&tid2, NULL, launch, &sync_pong) != 0) { - fprintf (stderr, "error on pthread_create\n"); - return 1; - } - pthread_join (tid1, NULL); - pthread_join (tid2, NULL); - sem_destroy (sem_act); - sem_destroy (sem_sig); - } - break; - case 1: - printf ("process mode\n"); - sem_sig = sem_open (SEMSIG, O_CREAT, S_IRUSR|S_IWUSR, 0); - sem_act = sem_open (SEMACT, O_CREAT, S_IRUSR|S_IWUSR, 0); - if ((sem_sig == NULL) || (sem_act == NULL)) { - fprintf (stderr, "error: sem_open\n"); - return 1; - } else { - pid_t pid = fork (); - if (pid == -1) { - fprintf (stderr, "error: fork\n"); - return 1; - } else if (pid > 0) { - launch (&sync_ping); - } else { - launch (&sync_pong); - } - sem_close (sem_act); - sem_unlink (SEMACT); - sem_close (sem_sig); - sem_unlink (SEMSIG); - if (pid == 0) { - return finish (); - } - if (kill (pid, SIGTERM) == 0) { - int wstatus; - if (waitpid (pid, &wstatus, WUNTRACED | WCONTINUED) == -1) { - fprintf (stderr, "error: waitpid\n"); - } - } - } - break; - case 2: - printf ("ping mode\n"); - launch (&async_ping); - break; - case 3: - printf ("pong mode\n"); - launch (&async_pong); - return finish (); - } - - if (finish ()) { - printf ("\033[1;31mKO\033[0;0m\n"); - return 1; - } else { - printf ("\033[1;32mOK\033[0;0m\n"); - } - - if (output) { - FILE *fd = fopen (output, "w"); - assert (fd); - for (int i = 0; i < nb; i++) { - fprintf (fd, "%ld\n", buffer[i]); - } - fclose (fd); - } - - if (do_stat) { - - if (excl_first) { - for (int i = 0; i < nb - excl_first; i++) { - buffer[i] = buffer[i + excl_first]; - } - nb -= excl_first; - } - - if (abe_per != 0) { - int n = nb * abe_per / 100; - for (int j = 0; j < n / 2; j++) { - int imax = 0; - int imin = 0; - for (int i = 1; i < nb; i++) { - if (buffer[i] > buffer[imax]) { - imax = i; - } - if (buffer[i] < buffer[imin]) { - imin = i; - } - } - for (int i = 0, jump = 0; i < nb; i++) { - if ((i == imax) || (i == imin)) { - jump++; - } else { - buffer[i - jump] = buffer[i]; - } - } - nb -= 2; - } - } - - compute_statistics (buffer, nb, hist_bin); - } - - free (buffer); - - return 0; -} diff --git a/test.h b/test.h deleted file mode 100644 index 914d82d..0000000 --- a/test.h +++ /dev/null @@ -1,18 +0,0 @@ -/* test module */ - -#ifndef __TEST_H__ -#define __TEST_H__ - -#include - -#include "mtime.h" - -int init (dts_t *buffer, int nb, int mode); - -void *ping (void *arg); - -void *pong (void *arg); - -int finish (); - -#endif /* __TEST_H__ */ diff --git a/test.sh b/test.sh index ee36afd..1acffe9 100755 --- a/test.sh +++ b/test.sh @@ -7,6 +7,7 @@ run() { dcore=$1 lcpu=$2 nbcpu=$3 + mode=$4 load=$(expr $lcpu \* 100 / $nbcpu) for exe in *.exe; do test=$(echo $exe | sed 's/\.exe//') @@ -29,6 +30,8 @@ rm -f purge *.log *.dat for d in 0 1 2; do for c in $(seq 0 $nbcpu); do - run $d $c $nbcpu + for m in 0 1; do + run $d $c $nbcpu $m + done done done diff --git a/test_multi.c b/test_multi.c deleted file mode 100644 index 4719314..0000000 --- a/test_multi.c +++ /dev/null @@ -1,305 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "stat.h" -#include "test.h" - -/* constants */ - -#define RT_PRIO 80 - -/* static variables */ - -char *progname = NULL; -char *version = "1.2"; - -double abe_per = 0; -int delay = 0; -int do_stat = 0; -int excl_first = 0; -int hist_bin = 10; -int mode = 0; -int nb = 1000; -int nb_cores = 0; -char *output = NULL; - -extern char *message; -extern void (*usage_ext) (FILE *); -extern int (*parse_arg_ext) (char *); -extern int rc; - -/* usage function */ - -int usage (int ret) -{ - FILE *fd = ret ? stderr : stdout; - fprintf (fd, "usage: %s [-a int] [-b int] [-d int] [-e int] [-h] [-k int] [-m int] [-n int] [-o file] [-s]\n", progname); - fprintf (fd, " -a: avoid aberrand valies (%g%%)\n", abe_per); - fprintf (fd, " -d: delay process start for (%ds)\n", delay); - fprintf (fd, " -b: nb bins for histogram (%d)\n", hist_bin); - fprintf (fd, " -e: exclude %d first tests\n", excl_first); - fprintf (fd, " -h: help message\n"); - fprintf (fd, " -k: nb dedicated cores (%d)\n", nb_cores); - fprintf (fd, " -m: 0 for ping-pong, 1 ping, 2 pong (%d)\n", mode); - fprintf (fd, " -n: nb measurements (%d)\n", nb); - fprintf (fd, " -o: output raw data (%s)\n", (output) ? output : "none"); - fprintf (fd, " -s: display statistics (%s)\n", (do_stat) ? "yes" : "no"); - if (usage_ext) { - fprintf (fd, "extension:\n"); - usage_ext (fd); - } - fprintf (fd, "%s version %s\n", progname, version); - - return ret; -} - -/* launch ping and pong */ - -int launch (int target, int (*func)(void *arg)) -{ - int cpu = (nb_cores == 1) ? 0 : (nb_cores == 2) ? target : -1; - if (cpu != -1) { - cpu_set_t cpu_mask; - CPU_ZERO (&cpu_mask); - CPU_SET (cpu, &cpu_mask); - if (sched_setaffinity (0, sizeof (cpu_set_t), &cpu_mask) != 0) { - fprintf (stderr, "error: sched_setaffinity (%d)\n", cpu); - return 1; - } - } - - /* synchronize two process */ - - return func (arg); -} - -/* main function */ - -int main (int argc, char *argv[]) -{ - - /* get basename */ - - char *pt = progname = argv[0]; - while (*pt) { - if ((*pt == '/') || (*pt == '\\')) { - progname = pt + 1; - } - pt++; - } - - /* process arguments */ - - while (argc-- > 1) { - char *arg = *(++argv); - if (arg[0] != '-') { - if ((!parse_arg_ext) || (parse_arg_ext (arg))) { - fprintf (stderr, "%s: invalid option -- %s\n", progname, arg); - return usage (1); - } - continue; - } - char c = arg[1]; - switch (c) { - case 'a': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no aberrant percent specified\n", progname); - return usage (1); - } - abe_per = strtod (arg, NULL); - break; - case 'b': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of bins specified\n", progname); - return usage (1); - } - hist_bin = atoi (arg); - break; - case 'd': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no delay specified\n", progname); - return usage (1); - } - delay = atoi (arg); - break; - case 'e': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of first to exclude specified\n", progname); - return usage (1); - } - excl_first = atoi (arg); - break; - case 'k': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of dedicated cores specified\n", progname); - return usage (1); - } - nb_cores = atoi (arg); - break; - case 'm': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no mode specified\n", progname); - return usage (1); - } - mode = atoi (arg); - break; - case 'n': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no number of measurements specified\n", progname); - return usage (1); - } - nb = atoi (arg); - break; - case 'o': - arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; - if (arg == NULL) { - fprintf (stderr, "%s: no output file specified\n", progname); - return usage (1); - } - output = arg; - break; - case 's': - do_stat = 1; - break; - case 'v': - printf ("version: %s\n", version); - break; - case 'h': - default: - return usage (c != 'h'); - } - } - - /* real-time process */ - - struct sched_param param = {0}; - if (sched_getparam (0, ¶m) != 0) { - fprintf (stderr, "error: sched_getparam\n"); - return 1; - } - param.sched_priority = RT_PRIO; - int rc = sched_setscheduler (0, SCHED_FIFO, ¶m); /* non-preemptive */ - // int rc = sched_setscheduler (0, SCHED_RR, ¶m); /* preemptive */ - if (rc != 0) { - fprintf (stderr, "error: sched_setscheduler\n"); - return 1; - } - - /* main process */ - - dts_t *buffer = (dts_t *) calloc (nb, sizeof (dts_t)); - assert (buffer); - - if (delay > 0) { - printf ("Delay start for %ds\n", delay); - for (int i = 0; i < 100 * delay; i++) { - usleep (10 * 1000); - } - } - - printf ("Test: %s\n", (message) ? message : "unknown"); - printf ("Dedicated core(s): %d\n", nb_cores); - - if (init (buffer, nb)) { - fprintf (stderr, "error on init\n"); - return 1; - } - - sem_t sem_sig, sem_act; - if ((sem_init (&sem_sig, 1, 0) != 0) || (sem_init (&sem_sig, 1, 0) != 0)) { - fprintf (stderr, "error: sem_init\n"); - return 1; - } - - pid_t pid = (mode == 0 ) ? fork () : -2; - if (pid == -1) { - sem_wait (sem_sig); - sem_post (sem_act); - fprintf (stderr, "error: fork\n"); - return 1; - } else if ((pid == 0) || (mode == 2)) { - return launch (1, pong); - } - if (pid > 0) { - sem_post (sem_sig); - sem_wait (sem_act); - } - int rc = launch (0, ping); - - if ((pid > 0) && (kill (pid, SIGTERM) == 0)) { - int wstatus; - if (waitpid (pid, &wstatus, WUNTRACED | WCONTINUED) == -1) { - fprintf (stderr, "error: waitpid\n"); - } - } - - if (finish ()) { - printf ("\033[1;31mKO\033[0;0m\n"); - return 1; - } else { - printf ("\033[1;32mOK\033[0;0m\n"); - } - - if (output) { - FILE *fd = fopen (output, "w"); - assert (fd); - for (int i = 0; i < nb; i++) { - fprintf (fd, "%ld\n", buffer[i]); - } - fclose (fd); - } - - if (do_stat) { - - if (excl_first) { - for (int i = 0; i < nb - excl_first; i++) { - buffer[i] = buffer[i + excl_first]; - } - nb -= excl_first; - } - - if (abe_per != 0) { - int n = nb * abe_per / 100; - for (int j = 0; j < n / 2; j++) { - int imax = 0; - int imin = 0; - for (int i = 1; i < nb; i++) { - if (buffer[i] > buffer[imax]) { - imax = i; - } - if (buffer[i] < buffer[imin]) { - imin = i; - } - } - for (int i = 0, jump = 0; i < nb; i++) { - if ((i == imax) || (i == imin)) { - jump++; - } else { - buffer[i - jump] = buffer[i]; - } - } - nb -= 2; - } - } - - compute_statistics (buffer, nb, hist_bin); - } - - free (buffer); - - return 0; -} diff --git a/test_multi.h b/test_multi.h deleted file mode 100644 index 4124c30..0000000 --- a/test_multi.h +++ /dev/null @@ -1,16 +0,0 @@ -/* test module */ - -#ifndef __TEST_MULTI_H__ -#define __TEST_MULTI_H__ - -#include "mtime.h" - -int init (dts_t *buffer, int nb); - -int ping (void); - -int pong (void); - -int finish (); - -#endif /* __TEST_MULTI_H__ */ diff --git a/thread_c+j.c b/thread_c+j.c index bd5d0a7..0eec36a 100644 --- a/thread_c+j.c +++ b/thread_c+j.c @@ -1,31 +1,41 @@ /* depend: */ /* cflags: */ -/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */ +/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */ #include +#include #include +#include "main.h" #include "mtime.h" -#include "test.h" /* global variables */ dts_t *deltas = NULL; int nb_measurements = 0; +int current_mode = 0; char *message = "Thread (create and join) latency"; void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; -int rc = 0; +sem_t synchro; -int init (dts_t *buffer, int nb, __attribute__((unused)) pthread_barrier_t *synchro) +#define TIMER 1000 + +int init (dts_t *buffer, int nb, int mode) { + if (mode != 0) { + fprintf (stderr, "only avaible in thread mode\n"); + return 1; + } + /* set global variables */ deltas = buffer; nb_measurements = nb; + current_mode = mode; return 0; } @@ -46,8 +56,7 @@ void *ping (__attribute__((unused)) void *arg) pthread_t posix_t; if (pthread_create(&posix_t, NULL, dummy_thread, NULL) != 0) { fprintf (stderr, "error on pthread_create\n"); - rc = 1; - pthread_exit (NULL); + RETURN (current_mode, 1); } pthread_join(posix_t, NULL); @@ -58,15 +67,18 @@ void *ping (__attribute__((unused)) void *arg) if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); } - pthread_exit (NULL); + RETURN (current_mode, 0); } void *pong (__attribute__((unused)) void *arg) { - pthread_exit (NULL); + RETURN (current_mode, 0); } int finish () { + + sem_destroy (&synchro); + return rc; } diff --git a/thread_c.c b/thread_c.c index 603015d..ae3be76 100644 --- a/thread_c.c +++ b/thread_c.c @@ -1,32 +1,42 @@ /* depend: */ /* cflags: */ -/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */ +/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */ #include +#include #include +#include "main.h" #include "mtime.h" -#include "test.h" /* global variables */ dts_t *deltas = NULL; int nb_measurements = 0; +int current_mode = 0; char *message = "Thread (create) latency"; void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; +sem_t synchro; ts_t ts1, ts2; -int rc = 0; -int init (dts_t *buffer, int nb, __attribute__((unused)) pthread_barrier_t *synchro) +#define TIMER 1000 + +int init (dts_t *buffer, int nb, int mode) { + if (mode != 0) { + fprintf (stderr, "only avaible in thread mode\n"); + return 1; + } + /* set global variables */ deltas = buffer; nb_measurements = nb; + current_mode = mode; return 0; } @@ -34,7 +44,7 @@ int init (dts_t *buffer, int nb, __attribute__((unused)) pthread_barrier_t *sync void* dummy_thread (__attribute__((unused)) void *arg) { sys_timestamp (&ts2); - pthread_exit (NULL); + RETURN (current_mode, 0); } void *ping (__attribute__((unused)) void *arg) @@ -47,8 +57,7 @@ void *ping (__attribute__((unused)) void *arg) pthread_t posix_t; if (pthread_create(&posix_t, NULL, dummy_thread, NULL) != 0) { fprintf (stderr, "error on pthread_create\n"); - rc = 1; - pthread_exit (NULL); + RETURN (current_mode, 1); } pthread_join(posix_t, NULL); @@ -56,15 +65,18 @@ void *ping (__attribute__((unused)) void *arg) if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); } - pthread_exit (NULL); + RETURN (current_mode, 0); } void *pong (__attribute__((unused)) void *arg) { - pthread_exit (NULL); + RETURN (current_mode, 0); } int finish () { + + sem_destroy (&synchro); + return rc; } diff --git a/udp.c b/udp.c new file mode 100644 index 0000000..1985426 --- /dev/null +++ b/udp.c @@ -0,0 +1,120 @@ +/* depend: */ +/* cflags: */ +/* linker: generic.o main.o msg.o mtime.o stat.o -lm -lpthread -lrt */ + +#include +#include +#include +#include +#include +#include + +#include "generic.h" + +/* global variables */ + +int localhost_ip = 0x7f000001; +int port = 1024; + +int sockin = -1; +int sockout = -1; +struct sockaddr_in local = { 0 }; +struct sockaddr_in remote = { 0 }; + +char *message = "UDP socket latency"; + +void _usage_ext (FILE *fd) +{ + fprintf (fd, "... port\n"); + fprintf (fd, " port: port number (%d)\n", port); +} +void (*usage_ext) (FILE *) = _usage_ext; + +int _parse_arg_ext (char *arg) +{ + static int narg = 0; + + int rc = 0; + switch (narg) { + case 0: port = atoi (arg); if (port < 0) rc = 1; break; + default: rc = 1; + } + narg++; + + return rc; +} +int (*parse_arg_ext) (char *) = _parse_arg_ext; + +int common_init (void) +{ + return 0; +} + +int ping_init (void) +{ + + /* open socket */ + + sockout = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sockout == -1) { + fprintf (stderr, "ping error: socket\n"); + return 1; + } + + /* init remote address */ + + remote.sin_family = AF_INET; + remote.sin_port = htons (port); + remote.sin_addr.s_addr = htonl (localhost_ip); + + return 0; +} + +int ping_test (char *buffer, int len) +{ + return (sendto (sockout, buffer, len, 0, (struct sockaddr *)&remote, sizeof (remote)) == -1); +} + +void ping_finish (void) +{ + close (sockout); +} + +int pong_init (void) +{ + + /* open socket */ + + sockin = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sockin == -1) { + fprintf (stderr, "pong error: socket\n"); + return 1; + } + + /* init local address */ + + local.sin_family = AF_INET; + local.sin_port = htons (port); + local.sin_addr.s_addr = htonl (INADDR_ANY); + + if (bind (sockin, (struct sockaddr *)&local, sizeof (local)) == -1) { + fprintf (stderr, "pong error: bind\n"); + return 1; + } + + return 0; +} + +int pong_test (char *buffer, int len) +{ + struct sockaddr_in src = { 0 }; + socklen_t alen = sizeof (src); + return (recvfrom (sockin, buffer, len, 0, (struct sockaddr *)&src, &alen) == -1); +} + +void pong_finish (void) +{ + close (sockin); +} + +void common_finish (void) { } diff --git a/udp_lat.c b/udp_lat.c deleted file mode 100644 index 7271455..0000000 --- a/udp_lat.c +++ /dev/null @@ -1,178 +0,0 @@ -/* depend: */ -/* cflags: */ -/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */ - -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "msg.h" -#include "mtime.h" -#include "test.h" - -/* global variables */ - -dts_t *deltas = NULL; -int nb_measurements = 0; - -int port = 1024; - -char *message = "UDP socket latency"; - -void _usage_ext (FILE *fd) -{ - fprintf (fd, "... port\n"); - fprintf (fd, " port: port number (%d)\n", port); -} -void (*usage_ext) (FILE *) = _usage_ext; - -int _parse_arg_ext (char *arg) -{ - static int narg = 0; - - int rc = 0; - switch (narg) { - case 0: port = atoi (arg); if (port < 0) rc = 1; break; - default: rc = 1; - } - narg++; - - return rc; -} -int (*parse_arg_ext) (char *) = _parse_arg_ext; - -#define MSGLEN 128 -#define MAXBUF 1024 -#define TIMER 1000 - -pthread_barrier_t *barrier = NULL; -pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;; -ts_t ts1, ts2; -int rc = 0; -int localhost_ip = 0x7f000001; - -void *ping (__attribute__((unused)) void *arg) -{ - - int sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock == -1) { - fprintf (stderr, "ping error: socket\n"); - rc = 1; - pthread_exit (NULL); - } -/* - struct sockaddr_in local = { 0 }; - local.sin_family = AF_INET; - local.sin_port = htons (port); - local.sin_addr.s_addr = htonl (INADDR_ANY); - - if (bind (sock, (struct sockaddr *)&local, sizeof (local)) == -1) { - fprintf (stderr, "ping error: bind\n"); - rc = 1; - pthread_exit (NULL); - } -*/ - struct sockaddr_in remote = { 0 }; - remote.sin_family = AF_INET; - remote.sin_port = htons (port); - remote.sin_addr.s_addr = htonl (localhost_ip); - - pthread_barrier_wait (barrier); - printf ("Sending ping...\n"); - - usleep (TIMER); - - for (int i = -1; i < nb_measurements; i++) { - - char *msg = get_msg (MSGLEN); - - pthread_mutex_lock (&mutex); - pthread_mutex_unlock (&mutex); - - usleep (TIMER / 2); - - sys_timestamp (&ts1); - if (sendto (sock, msg, MSGLEN, 0, (struct sockaddr *)&remote, sizeof (remote)) == -1) { - fprintf (stderr, "ping error: sendto (%d)\n", i); - rc = 1; - pthread_exit (NULL); - } - - usleep (TIMER); - } - - close (sock); - - pthread_exit (NULL); -} - -void *pong (__attribute__((unused)) void *arg) -{ - - int sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (sock == -1) { - fprintf (stderr, "pong error: socket\n"); - rc = 1; - pthread_exit (NULL); - } - - struct sockaddr_in local = { 0 }; - local.sin_family = AF_INET; - local.sin_port = htons (port); - local.sin_addr.s_addr = htonl (INADDR_ANY); - - if (bind (sock, (struct sockaddr *)&local, sizeof (local)) == -1) { - fprintf (stderr, "pong error: bind\n"); - rc = 1; - pthread_exit (NULL); - } - - pthread_barrier_wait (barrier); - printf ("Receiving pong...\n"); - - for (int i = -1; i < nb_measurements; i++) { - - pthread_mutex_lock (&mutex); - usleep (TIMER); - pthread_mutex_unlock (&mutex); - - char buffer[MAXBUF] = { 0 }; - struct sockaddr_in src = { 0 }; - socklen_t alen = sizeof (src); - if (recvfrom (sock, buffer, MAXBUF, 0, (struct sockaddr *)&src, &alen) == -1) { - fprintf (stderr, "pong error: recv_from (%d)\n", i); - rc = 1; - pthread_exit (NULL); - } - sys_timestamp (&ts2); - if (i != -1) deltas[i] = diff_timestamp (&ts2, &ts1); - } - - close (sock); - - pthread_exit (NULL); -} - -int init (dts_t *buffer, int nb, pthread_barrier_t *synchro) -{ - - /* set global variables */ - - deltas = buffer; - nb_measurements = nb; - barrier = synchro; - - return 0; -} - -int finish () -{ - return rc; -}