bfin: remove inline keyword
[xenomai-head.git] / src / testsuite / regression / posix / xddp_test.c
blobe10a09a73df24e3c815fe6fc5db7d7f4c974d00a
1 /*
2 * XDDP-based RT/NRT threads regression test.
4 * Original author: Doug Brunner
6 * This test causes a crash with Xenomai 2.6.1 and earlier versions.
7 */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #include <errno.h>
14 #include <unistd.h>
15 #include <signal.h>
16 #include <sys/mman.h>
17 #include <pthread.h>
18 #include <semaphore.h>
20 #include <rtdm/rtipc.h>
21 #include "check.h"
23 static pthread_t rt, nrt;
24 static sem_t opened;
25 static int xddp_port = -1; /* First pass uses auto-selection */
27 static void *realtime_thread(void *arg)
29 unsigned long count = (unsigned long)arg;
30 struct sockaddr_ipc saddr;
31 struct timespec ts;
32 socklen_t addrlen;
33 size_t poolsz;
34 int ret, s;
37 * Get a datagram socket to bind to the RT endpoint. Each
38 * endpoint is represented by a port number within the XDDP
39 * protocol namespace.
41 s = check_unix(socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_XDDP));
44 * Set a local 16k pool for the RT endpoint. Memory needed to
45 * convey datagrams will be pulled from this pool, instead of
46 * Xenomai's system pool.
48 poolsz = 16384; /* bytes */
49 ret = check_unix(setsockopt(s, SOL_XDDP, XDDP_POOLSZ,
50 &poolsz, sizeof(poolsz)));
53 * Bind the socket to the port, to setup a proxy to channel
54 * traffic to/from the Linux domain.
56 * saddr.sipc_port specifies the port number to use.
58 memset(&saddr, 0, sizeof(saddr));
59 saddr.sipc_family = AF_RTIPC;
60 saddr.sipc_port = xddp_port;
61 ret = bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
62 if (count == 1) {
63 if (ret < 0 && errno == EADDRINUSE) {
64 fprintf(stderr, "Test OK\n");
65 exit(EXIT_SUCCESS);
67 if (ret < 0) {
68 fprintf(stderr, "FAILURE: bind: %m\n");
69 exit(EXIT_FAILURE);
71 fprintf(stderr, "FAILURE: bind returned %d\n", ret);
72 } else {
73 addrlen = sizeof(saddr);
74 check_unix(getsockname(s, (struct sockaddr *)&saddr, &addrlen));
75 xddp_port = saddr.sipc_port;
77 if (ret < 0) {
78 fprintf(stderr, "FAILURE bind: %m\n");
79 exit(EXIT_FAILURE);
82 check_unix(sem_post(&opened));
83 ts.tv_sec = 0;
84 ts.tv_nsec = 500000000; /* 500 ms */
85 check_unix(clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL));
86 check_unix(sem_wait(&opened));
87 check_unix(sem_destroy(&opened));
88 check_unix(close(s));
90 return NULL;
93 static void *regular_thread(void *arg)
95 char buf[128], *devname;
96 int fd;
98 check_unix(asprintf(&devname, "/dev/rtp%d", xddp_port));
100 fd = check_unix(open(devname, O_RDWR));
101 free(devname);
102 check_unix(sem_post(&opened));
104 for (;;) {
105 /* Get the next message from realtime_thread. */
106 read(fd, buf, sizeof(buf));
108 usleep(10000);
111 return NULL;
114 static void cleanup_upon_sig(int sig)
116 pthread_cancel(rt);
117 pthread_cancel(nrt);
118 signal(sig, SIG_DFL);
119 pthread_join(rt, NULL);
120 pthread_join(nrt, NULL);
121 raise(sig);
124 int main(int argc, char **argv)
126 struct sched_param rtparam = { .sched_priority = 42 };
127 pthread_attr_t rtattr, regattr;
128 sigset_t mask, oldmask;
130 check_unix(mlockall(MCL_CURRENT | MCL_FUTURE));
132 check_unix(sigemptyset(&mask));
133 check_unix(sigaddset(&mask, SIGINT));
134 check_unix(signal(SIGINT, cleanup_upon_sig) == SIG_ERR ? -1 : 0);
135 check_unix(sigaddset(&mask, SIGTERM));
136 check_unix(signal(SIGTERM, cleanup_upon_sig) == SIG_ERR ? -1 : 0);
137 check_unix(sigaddset(&mask, SIGHUP));
138 check_unix(signal(SIGHUP, cleanup_upon_sig) == SIG_ERR ? -1 : 0);
139 check_pthread(pthread_sigmask(SIG_BLOCK, &mask, &oldmask));
141 check_unix(sem_init(&opened, 0, 0));
142 check_pthread(pthread_attr_init(&rtattr));
143 check_pthread(pthread_attr_setdetachstate(&rtattr,
144 PTHREAD_CREATE_JOINABLE));
145 check_pthread(pthread_attr_setinheritsched(&rtattr,
146 PTHREAD_EXPLICIT_SCHED));
147 check_pthread(pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO));
148 check_pthread(pthread_attr_setschedparam(&rtattr, &rtparam));
150 check_pthread(pthread_create(&rt, &rtattr, &realtime_thread, NULL));
151 check_pthread(pthread_attr_destroy(&rtattr));
152 check_unix(sem_wait(&opened));
154 check_pthread(pthread_attr_init(&regattr));
155 check_pthread(pthread_attr_setdetachstate(&regattr,
156 PTHREAD_CREATE_JOINABLE));
157 check_pthread(pthread_attr_setinheritsched(&regattr,
158 PTHREAD_EXPLICIT_SCHED));
159 check_pthread(pthread_attr_setschedpolicy(&regattr, SCHED_OTHER));
161 check_pthread(pthread_create(&nrt, &regattr, &regular_thread, NULL));
162 check_pthread(pthread_attr_destroy(&regattr));
164 /* after this call returns the RT thread will have ended */
165 sleep(1);
167 /* start another RT thread to cause the crash */
168 check_pthread(pthread_attr_init(&rtattr));
169 check_pthread(pthread_attr_setdetachstate(&rtattr,
170 PTHREAD_CREATE_JOINABLE));
171 check_pthread(pthread_attr_setinheritsched(&rtattr,
172 PTHREAD_EXPLICIT_SCHED));
173 check_pthread(pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO));
174 check_pthread(pthread_attr_setschedparam(&rtattr, &rtparam));
176 check_pthread(pthread_create(&rt, &rtattr,
177 &realtime_thread, (void *)1UL));
178 check_pthread(pthread_attr_destroy(&rtattr));
180 check_unix(sigsuspend(&oldmask));
182 return 0;