Skip to content

Commit 46c14f9

Browse files
committed
EVL: Fix cpu assignement for posix/lxrt/xenomai/evl
1 parent 202aec2 commit 46c14f9

5 files changed

Lines changed: 86 additions & 47 deletions

File tree

src/rtapi/rtapi_uspace.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ T *rtapi_get_task(int task_id) {
106106
return static_cast<T*>(RtapiApp::get_task(task_id));
107107
}
108108

109+
int find_rt_cpu_number();
110+
109111
#define MAX_TASKS 64
110112
#define TASK_MAGIC 21979 /* random numbers used as signatures */
111113
#define TASK_MAGIC_INIT ((rtapi_task*)(-1))

src/rtapi/uspace_rtai.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,11 @@ struct RtaiApp : RtapiApp {
8585
rt_set_periodic_mode();
8686
start_rt_timer(nano2count(task->period));
8787
if(task->uses_fp) rt_task_use_fpu(task->rt_task, 1);
88-
// assumes processor numbers are contiguous
89-
int nprocs = sysconf( _SC_NPROCESSORS_ONLN );
90-
rt_set_runnable_on_cpus(task->rt_task, 1u << (nprocs - 1));
88+
const static int rt_cpu_number = find_rt_cpu_number();
89+
if(rt_cpu_number != -1) {
90+
rtapi_print_msg(RTAPI_MSG_INFO, "rt_cpu_number = %i\n", rt_cpu_number);
91+
rt_set_runnable_on_cpus(task->rt_task, 1u << rt_cpu_number);
92+
}
9193
rt_make_hard_real_time();
9294
rt_task_make_periodic_relative_ns(task->rt_task, task->period, task->period);
9395
(task->taskcode) (task->arg);

src/rtapi/uspace_rtapi_app.cc

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,48 +1013,72 @@ int Posix::task_delete(int id)
10131013
return 0;
10141014
}
10151015

1016-
static int find_rt_cpu_number() {
1016+
//parse_cpu_list from https://gitlab.com/Xenomai/xenomai4/libevl/-/blob/master/tests/helpers.c?ref_type=heads
1017+
//License: MIT
1018+
static void parse_cpu_list(const char *path, cpu_set_t *cpuset)
1019+
{
1020+
char *p, *range, *range_p = NULL, *id, *id_r;
1021+
int start, end, cpu;
1022+
char buf[BUFSIZ];
1023+
FILE *fp;
1024+
1025+
CPU_ZERO(cpuset);
1026+
1027+
fp = fopen(path, "r");
1028+
if (fp == NULL)
1029+
return;
1030+
1031+
if (!fgets(buf, sizeof(buf), fp))
1032+
goto out;
1033+
1034+
p = buf;
1035+
while ((range = strtok_r(p, ",", &range_p)) != NULL) {
1036+
if (*range == '\0' || *range == '\n')
1037+
goto next;
1038+
end = -1;
1039+
id = strtok_r(range, "-", &id_r);
1040+
if (id) {
1041+
start = atoi(id);
1042+
id = strtok_r(NULL, "-", &id_r);
1043+
if (id)
1044+
end = atoi(id);
1045+
else if (end < 0)
1046+
end = start;
1047+
for (cpu = start; cpu <= end; cpu++)
1048+
CPU_SET(cpu, cpuset);
1049+
}
1050+
next:
1051+
p = NULL;
1052+
}
1053+
out:
1054+
fclose(fp);
1055+
}
1056+
1057+
int find_rt_cpu_number() {
10171058
if(getenv("RTAPI_CPU_NUMBER")) return atoi(getenv("RTAPI_CPU_NUMBER"));
10181059

10191060
#ifdef __linux__
1020-
cpu_set_t cpuset_orig;
1021-
int r = sched_getaffinity(getpid(), sizeof(cpuset_orig), &cpuset_orig);
1022-
if(r < 0)
1023-
// if getaffinity fails, (it shouldn't be able to), just use CPU#0
1024-
return 0;
1025-
1061+
const char* isolated_file="/sys/devices/system/cpu/isolated";
10261062
cpu_set_t cpuset;
1027-
CPU_ZERO(&cpuset);
1028-
long top_probe = sysconf(_SC_NPROCESSORS_CONF);
1029-
// in old glibc versions, it was an error to pass to sched_setaffinity bits
1030-
// that are higher than an imagined/probed kernel-side CPU mask size.
1031-
// this caused the message
1032-
// sched_setaffinity: Invalid argument
1033-
// to be printed at startup, and the probed CPU would not take into
1034-
// account CPUs masked from this process by default (whether by
1035-
// isolcpus or taskset). By only setting bits up to the "number of
1036-
// processes configured", the call is successful on glibc versions such as
1037-
// 2.19 and older.
1038-
for(long i=0; i<top_probe && i<CPU_SETSIZE; i++) CPU_SET(i, &cpuset);
1039-
1040-
r = sched_setaffinity(getpid(), sizeof(cpuset), &cpuset);
1041-
if(r < 0)
1042-
// if setaffinity fails, (it shouldn't be able to), go on with
1043-
// whatever the default CPUs were.
1044-
perror("sched_setaffinity");
1045-
1046-
r = sched_getaffinity(getpid(), sizeof(cpuset), &cpuset);
1047-
if(r < 0) {
1048-
// if getaffinity fails, (it shouldn't be able to), copy the
1049-
// original affinity list in and use it
1050-
perror("sched_getaffinity");
1051-
CPU_AND(&cpuset, &cpuset_orig, &cpuset);
1063+
1064+
parse_cpu_list(isolated_file, &cpuset);
1065+
1066+
//Print list
1067+
rtapi_print_msg(RTAPI_MSG_INFO, "cpuset isolated ");
1068+
for(int i=0; i<CPU_SETSIZE; i++) {
1069+
if(CPU_ISSET(i, &cpuset)){
1070+
rtapi_print_msg(RTAPI_MSG_INFO, "%i ", i);
1071+
}
10521072
}
1073+
rtapi_print_msg(RTAPI_MSG_INFO, "\n");
10531074

10541075
int top = -1;
10551076
for(int i=0; i<CPU_SETSIZE; i++) {
10561077
if(CPU_ISSET(i, &cpuset)) top = i;
10571078
}
1079+
if(top == -1){
1080+
rtapi_print_msg(RTAPI_MSG_ERR, "No isolated CPU's found, expect some latency!");
1081+
}
10581082
return top;
10591083
#else
10601084
return (-1);
@@ -1094,6 +1118,7 @@ int Posix::task_start(int task_id, unsigned long int period_nsec)
10941118
return -ret;
10951119
if(nprocs > 1) {
10961120
const static int rt_cpu_number = find_rt_cpu_number();
1121+
rtapi_print_msg(RTAPI_MSG_INFO, "rt_cpu_number = %i\n", rt_cpu_number);
10971122
if(rt_cpu_number != -1) {
10981123
#ifdef __FreeBSD__
10991124
cpuset_t cpuset;

src/rtapi/uspace_xenomai.cc

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,7 @@ struct XenomaiApp : RtapiApp {
5252
task->pll_correction_limit = period_nsec / 100;
5353
task->pll_correction = 0;
5454

55-
cpu_set_t cpuset;
56-
CPU_ZERO(&cpuset);
5755
int nprocs = sysconf( _SC_NPROCESSORS_ONLN );
58-
CPU_SET(nprocs-1, &cpuset); // assumes processor numbers are contiguous
5956

6057
int ret;
6158
pthread_attr_t attr;
@@ -69,9 +66,17 @@ struct XenomaiApp : RtapiApp {
6966
return -ret;
7067
if((ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) != 0)
7168
return -ret;
72-
if(nprocs > 1)
73-
if((ret = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset)) != 0)
74-
return -ret;
69+
if(nprocs > 1){
70+
const static int rt_cpu_number = find_rt_cpu_number();
71+
rtapi_print_msg(RTAPI_MSG_INFO, "rt_cpu_number = %i\n", rt_cpu_number);
72+
if(rt_cpu_number != -1) {
73+
cpu_set_t cpuset;
74+
CPU_ZERO(&cpuset);
75+
CPU_SET(rt_cpu_number, &cpuset);
76+
if((ret = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset)) != 0)
77+
return -ret;
78+
}
79+
}
7580
if((ret = pthread_create(&task->thr, &attr, &wrapper, reinterpret_cast<void*>(task))) != 0)
7681
return -ret;
7782

src/rtapi/uspace_xenomai_evl.cc

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ struct XenomaiApp : RtapiApp {
6060
task->pll_correction_limit = period_nsec / 100;
6161
task->pll_correction = 0;
6262

63-
cpu_set_t cpuset;
64-
CPU_ZERO(&cpuset);
6563
int nprocs = sysconf( _SC_NPROCESSORS_ONLN );
66-
CPU_SET(nprocs-1, &cpuset); // assumes processor numbers are contiguous
6764

6865
int ret;
6966
pthread_attr_t attr;
@@ -77,9 +74,17 @@ struct XenomaiApp : RtapiApp {
7774
return -ret;
7875
if((ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) != 0)
7976
return -ret;
80-
if(nprocs > 1)
81-
if((ret = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset)) != 0)
82-
return -ret;
77+
if(nprocs > 1){
78+
const static int rt_cpu_number = find_rt_cpu_number();
79+
rtapi_print_msg(RTAPI_MSG_INFO, "rt_cpu_number = %i\n", rt_cpu_number);
80+
if(rt_cpu_number != -1) {
81+
cpu_set_t cpuset;
82+
CPU_ZERO(&cpuset);
83+
CPU_SET(rt_cpu_number, &cpuset);
84+
if((ret = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset)) != 0)
85+
return -ret;
86+
}
87+
}
8388
if((ret = pthread_create(&task->thr, &attr, &wrapper, reinterpret_cast<void*>(task))) != 0)
8489
return -ret;
8590

0 commit comments

Comments
 (0)