Xenomai 3.3.2
Loading...
Searching...
No Matches
libc.h
1/*
2 * Copyright (C) 2014 Philippe Gerum <rpm@xenomai.org>.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 */
18#ifndef _BOILERPLATE_LIBC_H
19#define _BOILERPLATE_LIBC_H
20
21#include <limits.h>
22
23#ifdef __IN_XENO__
24/*
25 * Quirks for dealing with outdated libc* issues. This header will be
26 * parsed by the Xenomai implementation only, applications based on it
27 * have to provide their own set of wrappers as they should decide by
28 * themselves what to do when a feature is missing.
29 */
30#include <xeno_config.h>
31#include <errno.h>
32#include <boilerplate/compiler.h>
33
34#if !HAVE_DECL_PTHREAD_PRIO_NONE
35enum {
36 PTHREAD_PRIO_NONE,
37 PTHREAD_PRIO_INHERIT,
38 PTHREAD_PRIO_PROTECT
39};
40#endif /* !HAVE_DECL_PTHREAD_PRIO_NONE */
41
42#ifndef HAVE_FORK
43static inline int fork(void)
44{
45 errno = ENOSYS;
46 return -1;
47}
48#endif
49
50#ifndef HAVE_PTHREAD_ATFORK
51#ifndef HAVE_FORK
52static inline
53int pthread_atfork(void (*prepare)(void), void (*parent)(void),
54 void (*child)(void))
55{
56 return 0;
57}
58#else
59#error "fork() without pthread_atfork()"
60#endif
61#endif /* !HAVE_PTHREAD_ATFORK */
62
63#ifndef HAVE_PTHREAD_GETATTR_NP
64static inline
65int pthread_getattr_np(pthread_t th, pthread_attr_t *attr)
66{
67 return ENOSYS;
68}
69#endif /* !HAVE_PTHREAD_GETATTR_NP */
70
71#ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK
72static inline
73int pthread_condattr_setclock(pthread_condattr_t *__restrict__ attr,
74 clockid_t clock_id)
75{
76 return clock_id == CLOCK_REALTIME ? 0 : ENOSYS;
77}
78#endif /* !HAVE_PTHREAD_CONDATTR_SETCLOCK */
79
80#ifndef HAVE_PTHREAD_CONDATTR_GETCLOCK
81static inline
82int pthread_condattr_getclock(const pthread_condattr_t *__restrict__ attr,
83 clockid_t *__restrict__ clock_id)
84{
85 *clock_id = CLOCK_REALTIME;
86
87 return 0;
88}
89#endif /* !HAVE_PTHREAD_CONDATTR_GETCLOCK */
90
91#ifndef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
92static inline
93int pthread_mutexattr_setprotocol(pthread_mutexattr_t *__restrict__ attr,
94 int protocol)
95{
96 return protocol == PTHREAD_PRIO_NONE ? 0 : ENOSYS;
97}
98#endif /* !HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL */
99
100#ifndef HAVE_PTHREAD_MUTEXATTR_GETPROTOCOL
101static inline
102int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *
103 __restrict__ attr, int *__restrict__ protocol)
104{
105 *protocol = PTHREAD_PRIO_NONE;
106
107 return 0;
108}
109#endif /* !HAVE_PTHREAD_MUTEXATTR_GETPROTOCOL */
110
111#ifndef HAVE_PTHREAD_MUTEXATTR_SETPRIOCEILING
112static inline
113int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr,
114 int prioceiling)
115{
116 return ENOSYS;
117}
118#endif /* !HAVE_PTHREAD_MUTEXATTR_SETPRIOCEILING */
119
120#ifndef HAVE_PTHREAD_MUTEXATTR_GETPRIOCEILING
121static inline
122int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *
123 __restrict attr,
124 int *__restrict prioceiling)
125{
126 return ENOSYS;
127}
128#endif /* !HAVE_PTHREAD_MUTEXATTR_GETPRIOCEILING */
129
130#ifndef HAVE_PTHREAD_MUTEX_SETPRIOCEILING
131static inline
132int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict attr,
133 int prioceiling,
134 int *__restrict old_ceiling)
135{
136 return ENOSYS;
137}
138#endif /* !HAVE_PTHREAD_MUTEXATTR_SETPRIOCEILING */
139
140#ifndef HAVE_PTHREAD_MUTEX_GETPRIOCEILING
141static inline
142int pthread_mutex_getprioceiling(pthread_mutex_t *__restrict attr,
143 int *__restrict prioceiling)
144{
145 return ENOSYS;
146}
147#endif /* !HAVE_PTHREAD_MUTEXATTR_GETPRIOCEILING */
148
149#ifndef HAVE_PTHREAD_ATTR_SETAFFINITY_NP
150#include <sched.h>
151static inline
152int pthread_attr_setaffinity_np(pthread_attr_t *attr,
153 size_t cpusetsize, const cpu_set_t *cpuset)
154{
155 if (CPU_ISSET(0, cpuset) && CPU_COUNT(cpuset) == 1)
156 return 0;
157 return ENOSYS;
158}
159#endif /* !HAVE_PTHREAD_ATTR_SETAFFINITY_NP */
160
161#ifndef HAVE_PTHREAD_SETAFFINITY_NP
162static inline
163int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
164 const cpu_set_t *cpuset)
165{
166 if (CPU_ISSET(0, cpuset) && CPU_COUNT(cpuset) == 1)
167 return 0;
168 return ENOSYS;
169}
170#endif /* !HAVE_PTHREAD_SETAFFINITY_NP */
171
172#ifndef HAVE_PTHREAD_SETSCHEDPRIO
173
174static inline
175int pthread_setschedprio(pthread_t thread, int prio)
176{
177 struct sched_param param;
178 int policy, ret;
179
180 ret = pthread_getschedparam(thread, &policy, &param);
181 if (ret)
182 return ret;
183
184 param.sched_priority = prio;
185
186 return pthread_setschedparam(thread, policy, &param);
187}
188
189#endif /* !HAVE_PTHREAD_SETSCHEDPRIO */
190
191#if !defined(HAVE_CLOCK_NANOSLEEP) && defined(CONFIG_XENO_MERCURY)
192/*
193 * Best effort for a Mercury setup based on an outdated libc lacking
194 * "advanced" real-time support. Too bad if the system clock is set
195 * during sleep time. This is a non-issue for Cobalt, as the libcobalt
196 * implementation will always be picked instead.
197 */
198__weak int clock_nanosleep(clockid_t clock_id, int flags,
199 const struct timespec *request,
200 struct timespec *remain)
201{
202 struct timespec now, tmp;
203
204 tmp = *request;
205 if (flags) {
206 clock_gettime(CLOCK_REALTIME, &now);
207 tmp.tv_sec -= now.tv_sec;
208 tmp.tv_nsec -= now.tv_nsec;
209 if (tmp.tv_nsec < 0) {
210 tmp.tv_sec--;
211 tmp.tv_nsec += 1000000000;
212 }
213 }
214
215 return nanosleep(&tmp, remain);
216}
217#endif /* !HAVE_CLOCK_NANOSLEEP && MERCURY */
218
219#ifndef HAVE_SCHED_GETCPU
220/*
221 * Might be declared in uClibc headers but not actually implemented,
222 * so we make the placeholder a weak symbol.
223 */
224__weak int sched_getcpu(void)
225{
226 return 0; /* outdated uClibc: assume uniprocessor. */
227}
228#endif /* !HAVE_SCHED_GETCPU */
229
230#ifndef HAVE_SHM_OPEN
231__weak int shm_open(const char *name, int oflag, mode_t mode)
232{
233 errno = ENOSYS;
234 return -1;
235}
236#endif /* !HAVE_SHM_OPEN */
237
238#ifndef HAVE_SHM_UNLINK
239__weak int shm_unlink(const char *name)
240{
241 errno = ENOSYS;
242 return -1;
243}
244#endif /* !HAVE_SHM_UNLINK */
245
246#ifndef HAVE_PTHREAD_MUTEXATTR_SETROBUST
247#ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP
248#define pthread_mutexattr_setrobust pthread_mutexattr_setrobust_np
249#else
250static inline
251int pthread_mutexattr_setrobust(pthread_mutexattr_t *attr,
252 int robustness)
253{
254 return ENOSYS;
255}
256#endif /* !HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP */
257#endif /* !HAVE_PTHREAD_MUTEXATTR_SETROBUST */
258
259#if !defined(HAVE_PTHREAD_SETNAME_NP) && defined(CONFIG_XENO_MERCURY)
260static inline
261int pthread_setname_np(pthread_t thread, const char *name)
262{
263 return ENOSYS;
264}
265#endif /* !HAVE_PTHREAD_SETNAME_NP && MERCURY */
266
267#endif /* __IN_XENO__ */
268
269#if defined(__COBALT_WRAP__) || defined(__IN_XENO__)
270/*
271 * clock_nanosleep() and pthread_setname_np() must be declared when the libc
272 * does not declare them, both for compiling xenomai, and for compiling
273 * applications wrapping these symbols to the libcobalt versions.
274 */
275#ifndef HAVE_CLOCK_NANOSLEEP
276int clock_nanosleep(clockid_t clock_id, int flags,
277 const struct timespec *request,
278 struct timespec *remain);
279#endif /* !HAVE_CLOCK_NANOSLEEP */
280
281#ifndef HAVE_PTHREAD_SETNAME_NP
282int pthread_setname_np(pthread_t thread, const char *name);
283#endif /* !HAVE_PTHREAD_SETNAME_NP */
284#endif /* __COBALT_WRAP__ || __IN_XENO__ */
285
286#ifndef PTHREAD_STACK_DEFAULT
287#define PTHREAD_STACK_DEFAULT \
288 ({ \
289 int __ret = PTHREAD_STACK_MIN; \
290 if (__ret < 65536) \
291 __ret = 65536; \
292 __ret; \
293 })
294#endif /* !PTHREAD_STACK_DEFAULT */
295
296#endif /* _BOILERPLATE_LIBC_H */
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clk_id)
Set the clock selection attribute of a condition variable attributes object.
int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clk_id)
Get the clock selection attribute from a condition variable attributes object.
int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict mutex, int prioceiling, int *__restrict old_ceiling))
Set a mutex's priority ceiling.
Definition mutex.c:741
int pthread_mutex_getprioceiling(pthread_mutex_t *__restrict mutex, int *__restrict old_ceiling))
Get a mutex's priority ceiling.
Definition mutex.c:792
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *proto)
Get the protocol attribute from a mutex attributes object.
int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int proto)
Set the protocol attribute of a mutex attributes object.
int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param))
Set the scheduling policy and parameters of the specified thread.
Definition thread.c:540
int pthread_setname_np(pthread_t thread, const char *name))
Set a thread name.
Definition thread.c:403