Commit bc9df6ac authored by Philippe Gerum's avatar Philippe Gerum
Browse files

tests: helpers: add CPU selection routine



Useful to pick the most appropriate CPU available for running a test,
accounting for the initial hint given by the caller.
Signed-off-by: default avatarPhilippe Gerum <rpm@xenomai.org>
parent 207ad9fe
......@@ -8,12 +8,16 @@
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <evl/thread.h>
#include "helpers.h"
#define ISOLATED_CPU_LIST "/sys/devices/system/cpu/isolated"
#define OOB_CPU_LIST "/sys/devices/virtual/evl/control/cpus"
char *get_unique_name_and_path(const char *type,
int serial, char **ppath)
{
......@@ -68,3 +72,107 @@ void timespec_add_ns(struct timespec *__restrict r,
r->tv_nsec -= 1000000000;
}
}
static void parse_cpu_list(const char *path, cpu_set_t *cpuset)
{
char *p, *range, *range_p = NULL, *id, *id_r;
int start, end, cpu;
char buf[BUFSIZ];
FILE *fp;
CPU_ZERO(cpuset);
fp = fopen(path, "r");
if (fp == NULL)
return;
if (!fgets(buf, sizeof(buf), fp))
goto out;
p = buf;
while ((range = strtok_r(p, ",", &range_p)) != NULL) {
if (*range == '\0' || *range == '\n')
goto next;
end = -1;
id = strtok_r(range, "-", &id_r);
if (id) {
start = atoi(id);
id = strtok_r(NULL, "-", &id_r);
if (id)
end = atoi(id);
else if (end < 0)
end = start;
for (cpu = start; cpu <= end; cpu++)
CPU_SET(cpu, cpuset);
}
next:
p = NULL;
}
out:
fclose(fp);
}
int pick_test_cpu(int hint_cpu, bool inband_test, bool *isolated)
{
cpu_set_t isolated_cpus, oob_cpus, best_cpus;
int cpu;
parse_cpu_list(ISOLATED_CPU_LIST, &isolated_cpus);
parse_cpu_list(OOB_CPU_LIST, &oob_cpus);
if (hint_cpu >= 0) {
/* The hint is not oob-capable, pick a better one. */
if (!inband_test && !CPU_ISSET(hint_cpu, &oob_cpus))
goto pick_oob;
goto finish;
}
if (inband_test)
goto pick_isolated;
/*
* Pick a default CPU among the ones which are both
* OOB-capable and isolated. If EVL is not enabled, oob_cpus
* is empty so there is no best choice.
*/
CPU_AND(&best_cpus, &isolated_cpus, &oob_cpus);
for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
if (CPU_ISSET(cpu, &best_cpus)) {
hint_cpu = cpu;
goto finish;
}
}
/*
* If no best choice, pick the first OOB-capable CPU we can
* find (if any).
*/
pick_oob:
for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
if (CPU_ISSET(cpu, &oob_cpus)) {
hint_cpu = cpu;
goto finish;
}
}
pick_isolated:
/*
* This must be a kernel with no EVL support or we
* specifically need an isolated CPU.
*/
for (cpu = 0; cpu < CPU_SETSIZE; cpu++) {
if (CPU_ISSET(cpu, &isolated_cpus)) {
hint_cpu = cpu;
goto finish;
}
}
/* Out of luck, run on the current CPU. */
if (hint_cpu < 0)
hint_cpu = sched_getcpu();
finish:
if (isolated)
*isolated = CPU_ISSET(hint_cpu, &isolated_cpus);
return hint_cpu;
}
......@@ -9,12 +9,15 @@
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>
#include <pthread.h>
#include <linux/ioctl.h>
#include <evl/proxy.h>
#define EXIT_NO_SUPPORT 42
#define ONE_BILLION 1000000000
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
......@@ -125,4 +128,7 @@ void timespec_add_ns(struct timespec *__restrict r,
const struct timespec *__restrict t,
long ns);
int pick_test_cpu(int hint_cpu,
bool inband_test, bool *isolated);
#endif /* !_EVL_TESTS_HELPERS_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment