Skip to content

Commit c7be441

Browse files
authored
Merge pull request #3908 from hdiethelm/rtapi_cleanup
Rtapi cleanup
2 parents b7423fb + e30e2ef commit c7be441

File tree

11 files changed

+1569
-1424
lines changed

11 files changed

+1569
-1424
lines changed

src/rtapi/Submakefile

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ $(patsubst ./rtapi/%,../include/%,$(RTAPIINCS)): ../include/%.h: ./rtapi/%.h
3232
ifeq ($(BUILD_SYS),uspace)
3333

3434
RTAPI_APP_SRCS := \
35+
rtapi/uspace_rtapi_main.cc \
3536
rtapi/uspace_rtapi_app.cc \
3637
rtapi/uspace_rtapi_parport.cc \
3738
rtapi/uspace_rtapi_string.c \
@@ -43,10 +44,19 @@ $(call TOOBJSDEPS, $(RTAPI_APP_SRCS)): EXTRAFLAGS += -DSIM \
4344
-UULAPI -DRTAPI -pthread
4445
../bin/rtapi_app: $(call TOOBJS, $(RTAPI_APP_SRCS))
4546
$(ECHO) Linking $(notdir $@)
46-
$(Q)$(CXX) -rdynamic -o $@ $^ $(LIBDL) -pthread -lrt $(LIBUDEV_LIBS) -ldl $(LDFLAGS)
47+
$(Q)$(CXX) -rdynamic -o $@ $^ $(LIBDL) -pthread -lrt -lfmt $(LIBUDEV_LIBS) -ldl $(LDFLAGS)
4748
TARGETS += ../bin/rtapi_app
4849
endif
4950

51+
USPACE_POSIX_SRCS := rtapi/uspace_posix.cc
52+
USERSRCS += $(USPACE_POSIX_SRCS)
53+
$(call TOOBJSDEPS, $(USPACE_POSIX_SRCS)): EXTRAFLAGS += -pthread -fPIC
54+
../lib/libuspace-posix.so.0: $(call TOOBJS, $(USPACE_POSIX_SRCS))
55+
$(ECHO) Linking $(notdir $@)
56+
$(Q)$(CXX) -shared $(LDFLAGS) -o $@ $^ -Wl,-soname,$(notdir $@)
57+
TARGETS += ../lib/libuspace-posix.so.0
58+
TARGETS += ../lib/libuspace-posix.so
59+
5060
ifeq ($(CONFIG_USPACE_RTAI),y)
5161
USPACE_RTAI_SRCS := rtapi/uspace_rtai.cc
5262
USERSRCS += $(USPACE_RTAI_SRCS)

src/rtapi/rtapi_pci.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
#include <rtapi.h>
3535
#include <rtapi_pci.h>
3636
#include <rtapi_firmware.h>
37-
#include "rtapi_uspace.hh"
37+
#include "uspace_rtapi_app.hh"
3838

3939
#include <dirent.h>
4040
#include <errno.h>

src/rtapi/uspace_common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <sys/time.h>
2222
#include <time.h>
2323
#include <stdio.h>
24+
#include <stdlib.h>
2425
#include <sys/utsname.h>
2526
#include <string.h>
2627
#include <unistd.h>
@@ -39,7 +40,7 @@ static msg_level_t msg_level = RTAPI_MSG_ERR; /* message printing level */
3940
#include "config.h"
4041

4142
#ifdef RTAPI
42-
#include "rtapi_uspace.hh"
43+
#include "uspace_rtapi_app.hh"
4344
#endif
4445

4546
typedef struct {

src/rtapi/uspace_posix.cc

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
/* Copyright (C) 2006-2014 Jeff Epler <jepler@unpythonic.net>
2+
*
3+
* This program is free software; you can redistribute it and/or modify
4+
* it under the terms of the GNU General Public License as published by
5+
* the Free Software Foundation; either version 2 of the License, or
6+
* (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU General Public License
14+
* along with this program; if not, write to the Free Software
15+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16+
*/
17+
18+
#include "config.h"
19+
#include "rtapi.h"
20+
#include "uspace_rtapi_app.hh"
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
#include <string.h>
24+
#include <stdexcept>
25+
#ifdef HAVE_SYS_IO_H
26+
#include <sys/io.h>
27+
#endif
28+
29+
namespace {
30+
struct PosixTask : rtapi_task {
31+
PosixTask() : rtapi_task{}, thr{} {
32+
}
33+
34+
pthread_t thr; /* thread's context */
35+
};
36+
37+
struct PosixApp : RtapiApp {
38+
PosixApp(int policy = SCHED_FIFO) : RtapiApp(policy), do_thread_lock(policy != SCHED_FIFO) {
39+
pthread_once(&key_once, init_key);
40+
if (do_thread_lock) {
41+
pthread_once(&lock_once, init_lock);
42+
}
43+
}
44+
45+
struct rtapi_task *do_task_new() {
46+
return new PosixTask;
47+
}
48+
49+
int task_delete(int id) {
50+
auto task = ::rtapi_get_task<PosixTask>(id);
51+
if (!task)
52+
return -EINVAL;
53+
54+
pthread_cancel(task->thr);
55+
pthread_join(task->thr, 0);
56+
task->magic = 0;
57+
task_array[id] = 0;
58+
delete task;
59+
return 0;
60+
}
61+
62+
int task_start(int task_id, unsigned long period_nsec) {
63+
auto task = ::rtapi_get_task<PosixTask>(task_id);
64+
if (!task)
65+
return -EINVAL;
66+
67+
task->period = period_nsec;
68+
struct sched_param param;
69+
memset(&param, 0, sizeof(param));
70+
param.sched_priority = task->prio;
71+
72+
// limit PLL correction values to +/-1% of cycle time
73+
task->pll_correction_limit = period_nsec / 100;
74+
task->pll_correction = 0;
75+
76+
int nprocs = sysconf(_SC_NPROCESSORS_ONLN);
77+
78+
pthread_attr_t attr;
79+
int ret;
80+
if ((ret = pthread_attr_init(&attr)) != 0)
81+
return -ret;
82+
if ((ret = pthread_attr_setstacksize(&attr, task->stacksize)) != 0)
83+
return -ret;
84+
if ((ret = pthread_attr_setschedpolicy(&attr, policy)) != 0)
85+
return -ret;
86+
if ((ret = pthread_attr_setschedparam(&attr, &param)) != 0)
87+
return -ret;
88+
if ((ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) != 0)
89+
return -ret;
90+
if (nprocs > 1) {
91+
const static int rt_cpu_number = find_rt_cpu_number();
92+
rtapi_print_msg(RTAPI_MSG_INFO, "rt_cpu_number = %i\n", rt_cpu_number);
93+
if (rt_cpu_number != -1) {
94+
#ifdef __FreeBSD__
95+
cpuset_t cpuset;
96+
#else
97+
cpu_set_t cpuset;
98+
#endif
99+
CPU_ZERO(&cpuset);
100+
CPU_SET(rt_cpu_number, &cpuset);
101+
if ((ret = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset)) != 0)
102+
return -ret;
103+
}
104+
}
105+
if (do_thread_lock)
106+
pthread_mutex_lock(&thread_lock);
107+
if ((ret = pthread_create(&task->thr, &attr, &wrapper, reinterpret_cast<void *>(task))) != 0)
108+
return -ret;
109+
110+
return 0;
111+
}
112+
113+
static void *wrapper(void *arg) {
114+
auto task = reinterpret_cast<PosixTask *>(arg);
115+
116+
pthread_setspecific(key, arg);
117+
set_namef("rtapi_app:T#%d", task->id);
118+
119+
struct timespec now;
120+
clock_gettime(CLOCK_MONOTONIC, &now);
121+
rtapi_timespec_advance(task->nextstart, now, task->period + task->pll_correction);
122+
123+
/* call the task function with the task argument */
124+
(task->taskcode)(task->arg);
125+
126+
rtapi_print("ERROR: reached end of wrapper for task %d\n", task->id);
127+
return NULL;
128+
}
129+
130+
int task_pause(int task_id) {
131+
(void)task_id;
132+
return -ENOSYS;
133+
}
134+
135+
int task_resume(int task_id) {
136+
(void)task_id;
137+
return -ENOSYS;
138+
}
139+
140+
long long task_pll_get_reference(void) {
141+
struct rtapi_task *task = reinterpret_cast<rtapi_task *>(pthread_getspecific(key));
142+
if (!task)
143+
return 0;
144+
return task->nextstart.tv_sec * 1000000000LL + task->nextstart.tv_nsec;
145+
}
146+
147+
int task_pll_set_correction(long value) {
148+
struct rtapi_task *task = reinterpret_cast<rtapi_task *>(pthread_getspecific(key));
149+
if (!task)
150+
return -EINVAL;
151+
if (value > task->pll_correction_limit)
152+
value = task->pll_correction_limit;
153+
if (value < -(task->pll_correction_limit))
154+
value = -(task->pll_correction_limit);
155+
task->pll_correction = value;
156+
return 0;
157+
}
158+
159+
void wait() {
160+
if (do_thread_lock)
161+
pthread_mutex_unlock(&thread_lock);
162+
pthread_testcancel();
163+
struct rtapi_task *task = reinterpret_cast<rtapi_task *>(pthread_getspecific(key));
164+
rtapi_timespec_advance(task->nextstart, task->nextstart, task->period + task->pll_correction);
165+
struct timespec now;
166+
clock_gettime(CLOCK_MONOTONIC, &now);
167+
if (rtapi_timespec_less(task->nextstart, now)) {
168+
if (policy == SCHED_FIFO)
169+
unexpected_realtime_delay(task);
170+
} else {
171+
int res = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &task->nextstart, nullptr);
172+
if (res < 0)
173+
perror("clock_nanosleep");
174+
}
175+
if (do_thread_lock)
176+
pthread_mutex_lock(&thread_lock);
177+
}
178+
179+
unsigned char do_inb(unsigned int port) {
180+
#ifdef HAVE_SYS_IO_H
181+
return inb(port);
182+
#else
183+
(void)port;
184+
return 0;
185+
#endif
186+
}
187+
188+
void do_outb(unsigned char val, unsigned int port) {
189+
#ifdef HAVE_SYS_IO_H
190+
return outb(val, port);
191+
#else
192+
(void)val;
193+
(void)port;
194+
#endif
195+
}
196+
197+
int run_threads(int fd, int (*callback)(int fd)) {
198+
while (callback(fd)) {
199+
/* nothing */
200+
}
201+
return 0;
202+
}
203+
204+
int task_self() {
205+
struct rtapi_task *task = reinterpret_cast<rtapi_task *>(pthread_getspecific(key));
206+
if (!task)
207+
return -EINVAL;
208+
return task->id;
209+
}
210+
211+
bool do_thread_lock;
212+
213+
static pthread_once_t key_once;
214+
static pthread_key_t key;
215+
static void init_key(void) {
216+
pthread_key_create(&key, NULL);
217+
}
218+
219+
static pthread_once_t lock_once;
220+
static pthread_mutex_t thread_lock;
221+
static void init_lock(void) {
222+
pthread_mutex_init(&thread_lock, NULL);
223+
}
224+
225+
long long do_get_time() {
226+
struct timespec ts;
227+
clock_gettime(CLOCK_MONOTONIC, &ts);
228+
return ts.tv_sec * 1000000000LL + ts.tv_nsec;
229+
}
230+
231+
void do_delay(long ns) {
232+
struct timespec ts = {0, ns};
233+
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, nullptr);
234+
}
235+
};
236+
237+
pthread_once_t PosixApp::key_once = PTHREAD_ONCE_INIT;
238+
pthread_once_t PosixApp::lock_once = PTHREAD_ONCE_INIT;
239+
pthread_key_t PosixApp::key;
240+
pthread_mutex_t PosixApp::thread_lock;
241+
242+
} // namespace
243+
244+
extern "C" RtapiApp *make(int policy);
245+
246+
RtapiApp *make(int policy) {
247+
if (policy == SCHED_OTHER) {
248+
rtapi_print_msg(RTAPI_MSG_ERR, "Note: Using POSIX non-realtime\n");
249+
} else {
250+
rtapi_print_msg(RTAPI_MSG_ERR, "Note: Using POSIX realtime\n");
251+
}
252+
return new PosixApp(policy);
253+
}

0 commit comments

Comments
 (0)