From a6b3dd17b72035bf5a3bed5289765cbe87f271b4 Mon Sep 17 00:00:00 2001 From: Laurent MAZET Date: Wed, 8 Oct 2025 11:27:04 +0200 Subject: [PATCH] manage thread afficiny --- clock.c | 3 ++- cycle.c | 3 ++- mutex.c | 3 ++- semaphore.c | 3 ++- test.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/clock.c b/clock.c index b563f42..f21e5b7 100644 --- a/clock.c +++ b/clock.c @@ -21,6 +21,7 @@ void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; int try = 0; +int rc = 0; #define MAXDUR 1000 #define MINDUR 100 @@ -64,5 +65,5 @@ void *pong (__attribute__((unused)) void *arg) int finish () { - return 0; + return rc; } diff --git a/cycle.c b/cycle.c index 4f517d6..bd3c484 100644 --- a/cycle.c +++ b/cycle.c @@ -21,6 +21,7 @@ void (*usage_ext) (FILE *) = NULL; int (*parse_arg_ext) (char *) = NULL; int try = 0; +int rc = 0; #define MAXDUR 1000 #define MINDUR 100 @@ -64,5 +65,5 @@ void *pong (__attribute__((unused)) void *arg) int finish () { - return 0; + return rc; } diff --git a/mutex.c b/mutex.c index a9a5581..d9aa277 100644 --- a/mutex.c +++ b/mutex.c @@ -24,6 +24,7 @@ volatile int shared_flag = 0; ts_t ts1, ts2; int try = 0; int nbtoofast = 0; +int rc = 0; #define TIMER 1000 @@ -90,5 +91,5 @@ int finish () printf ("Too fast: %d\n", nbtoofast); - return nbtoofast; + return rc || nbtoofast; } diff --git a/semaphore.c b/semaphore.c index 21d2827..05885a3 100644 --- a/semaphore.c +++ b/semaphore.c @@ -28,6 +28,7 @@ ts_t ts1, ts2; sem_t sem; int try = 0; int nbtoofast = 0; +int rc = 0; #define TIMER 1000 @@ -98,5 +99,5 @@ int finish () printf ("Too fast: %d\n", nbtoofast); - return nbtoofast; + return rc || nbtoofast; } diff --git a/test.c b/test.c index c74d681..9964ab8 100644 --- a/test.c +++ b/test.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include #include #include @@ -24,23 +25,26 @@ int do_stat = 0; int excl_first = 0; int hist_bin = 10; 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] [-n int] [-o file] [-s]\n", progname); + fprintf (fd, "usage: %s [-a int] [-b int] [-d int] [-e int] [-h] [-k 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, " -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"); @@ -53,6 +57,29 @@ int usage (int ret) return ret; } +/* launch ping and pong */ +typedef struct { + 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 (pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpu_mask) != 0) { + fprintf (stderr, "error: pthread_setaffinity_np (%d)\n", cpu); + rc = 1; + pthread_exit (NULL); + } + } + return param->func (arg); +} + /* main function */ int main (int argc, char *argv[]) @@ -113,6 +140,14 @@ int main (int argc, char *argv[]) } 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 'n': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { @@ -142,6 +177,7 @@ int main (int argc, char *argv[]) } /* real-time process */ + struct sched_param param = {0}; if (sched_getparam (0, ¶m) != 0) { fprintf (stderr, "error: sched_getparam\n"); @@ -168,8 +204,10 @@ int main (int argc, char *argv[]) } printf ("Test: %s\n", (message) ? message : "unknown"); + printf ("Dedicated core(s): %d\n", nb_cores); pthread_mutex_t synchro = PTHREAD_MUTEX_INITIALIZER; + launch_param_t lparam = { 0 }; if (init (buffer, nb, &synchro)) { fprintf (stderr, "error on init\n"); @@ -179,7 +217,9 @@ int main (int argc, char *argv[]) pthread_mutex_lock (&synchro); pthread_t tid1; - if (pthread_create (&tid1, NULL, ping, NULL) != 0) { + lparam.target = 0; + lparam.func = ping; + if (pthread_create (&tid1, NULL, launch, &lparam) != 0) { fprintf (stderr, "error on pthread_create\n"); return 1; } @@ -187,7 +227,9 @@ int main (int argc, char *argv[]) pthread_mutex_lock (&synchro); pthread_t tid2; - if (pthread_create (&tid2, NULL, pong, NULL) != 0) { + lparam.target = 1; + lparam.func = pong; + if (pthread_create (&tid2, NULL, launch, &lparam) != 0) { fprintf (stderr, "error on pthread_create\n"); return 1; } -- 2.30.2