/* depend: */
/* cflags: */
-/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */
+/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#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;
}
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;
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 ()
/* depend: */
/* cflags: */
-/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */
+/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#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;
}
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 ()
--- /dev/null
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#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;
+}
--- /dev/null
+#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__ */
--- /dev/null
+#define _GNU_SOURCE
+#include <assert.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#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;
+}
--- /dev/null
+#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__ */
--- /dev/null
+/* depend: */
+/* cflags: */
+/* linker: generic.o main.o msg.o mtime.o stat.o -lm -lpthread -lrt */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#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");
+ }
+}
+++ /dev/null
-/* depend: */
-/* cflags: */
-/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <fcntl.h> /* For O_* constants */
-#include <sys/stat.h> /* For mode constants */
-#include <mqueue.h>
-
-#include <pthread.h>
-#include <unistd.h>
-
-#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;
-}
/* depend: */
/* cflags: */
-/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */
+/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
+#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);
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;
}
--- /dev/null
+/* depend: */
+/* cflags: */
+/* linker: generic.o main.o msg.o mtime.o stat.o -lm -lpthread -lrt */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#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);
+}
+++ /dev/null
-/* depend: */
-/* cflags: */
-/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <pthread.h>
-#include <semaphore.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#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;
-}
+++ /dev/null
-/* depend: */
-/* cflags: */
-/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <mqueue.h>
-#include <semaphore.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#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;
-}
/* depend: */
/* cflags: */
-/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */
+/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */
+#include <errno.h>
+#include <fcntl.h>
+#include <mqueue.h>
+#include <pthread.h>
+#include <semaphore.h>
#include <stdio.h>
#include <string.h>
-
-#include <semaphore.h>
-
-#include <pthread.h>
+#include <sys/stat.h>
#include <unistd.h>
+#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;
}
+++ /dev/null
-#define _GNU_SOURCE
-#include <assert.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <sched.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#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;
-}
+++ /dev/null
-/* test module */
-
-#ifndef __TEST_H__
-#define __TEST_H__
-
-#include <pthread.h>
-
-#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__ */
dcore=$1
lcpu=$2
nbcpu=$3
+ mode=$4
load=$(expr $lcpu \* 100 / $nbcpu)
for exe in *.exe; do
test=$(echo $exe | sed 's/\.exe//')
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
+++ /dev/null
-#include <assert.h>
-#include <sched.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#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;
-}
+++ /dev/null
-/* 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__ */
/* depend: */
/* cflags: */
-/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */
+/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */
#include <pthread.h>
+#include <semaphore.h>
#include <stdio.h>
+#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;
}
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);
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;
}
/* depend: */
/* cflags: */
-/* linker: mtime.o test.o stat.o -lm -lpthread -lrt */
+/* linker: main.o mtime.o stat.o -lm -lpthread -lrt */
#include <pthread.h>
+#include <semaphore.h>
#include <stdio.h>
+#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;
}
void* dummy_thread (__attribute__((unused)) void *arg)
{
sys_timestamp (&ts2);
- pthread_exit (NULL);
+ RETURN (current_mode, 0);
}
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);
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;
}
--- /dev/null
+/* depend: */
+/* cflags: */
+/* linker: generic.o main.o msg.o mtime.o stat.o -lm -lpthread -lrt */
+
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#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) { }
+++ /dev/null
-/* depend: */
-/* cflags: */
-/* linker: msg.o mtime.o test.o stat.o -lm -lpthread -lrt */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <pthread.h>
-#include <unistd.h>
-
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#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;
-}