Xenomai  3.1
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
35 enum {
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
43 static inline int fork(void)
44 {
45  errno = ENOSYS;
46  return -1;
47 }
48 #endif
49 
50 #ifndef HAVE_PTHREAD_ATFORK
51 #ifndef HAVE_FORK
52 static inline
53 int 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
64 static inline
65 int 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
72 static inline
73 int 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
81 static inline
82 int 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
92 static inline
93 int 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
101 static inline
102 int 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
112 static inline
113 int 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
121 static inline
122 int 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
131 static inline
132 int 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
141 static inline
142 int 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>
151 static inline
152 int 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
162 static inline
163 int 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 
174 static inline
175 int 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_NP
247 #define pthread_mutexattr_setrobust_np(__attr, __robust) \
248  ({ ENOSYS; })
249 #endif /* !HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP */
250 
251 #if !defined(HAVE_PTHREAD_SETNAME_NP) && defined(CONFIG_XENO_MERCURY)
252 static inline
253 int pthread_setname_np(pthread_t thread, const char *name)
254 {
255  return ENOSYS;
256 }
257 #endif /* !HAVE_PTHREAD_SETNAME_NP && MERCURY */
258 
259 #endif /* __IN_XENO__ */
260 
261 #if defined(__COBALT_WRAP__) || defined(__IN_XENO__)
262 /*
263  * clock_nanosleep() and pthread_setname_np() must be declared when the libc
264  * does not declare them, both for compiling xenomai, and for compiling
265  * applications wrapping these symbols to the libcobalt versions.
266  */
267 #ifndef HAVE_CLOCK_NANOSLEEP
268 int clock_nanosleep(clockid_t clock_id, int flags,
269  const struct timespec *request,
270  struct timespec *remain);
271 #endif /* !HAVE_CLOCK_NANOSLEEP */
272 
273 #ifndef HAVE_PTHREAD_SETNAME_NP
274 int pthread_setname_np(pthread_t thread, const char *name);
275 #endif /* !HAVE_PTHREAD_SETNAME_NP */
276 #endif /* __COBALT_WRAP__ || __IN_XENO__ */
277 
278 #ifndef PTHREAD_STACK_DEFAULT
279 #define PTHREAD_STACK_DEFAULT \
280  ({ \
281  int __ret = PTHREAD_STACK_MIN; \
282  if (__ret < 65536) \
283  __ret = 65536; \
284  __ret; \
285  })
286 #endif /* !PTHREAD_STACK_DEFAULT */
287 
288 #endif /* _BOILERPLATE_LIBC_H */
int pthread_getschedparam(pthread_t thread, int *__restrict__ policy, struct sched_param *__restrict__ param)
Get the scheduling policy and parameters of the specified thread.
Definition: thread.c:738
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_mutexattr_setprotocol(pthread_mutexattr_t *attr, int proto)
Set the protocol attribute of a mutex attributes object.
int pthread_mutex_getprioceiling(pthread_mutex_t *__restrict mutex, int *__restrict old_ceiling)
Get a mutex&#39;s priority ceiling.
Definition: mutex.c:772
int pthread_setname_np(pthread_t thread, const char *name)
Set a thread name.
Definition: thread.c:408
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *proto)
Get the protocol attribute from 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:548
int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clk_id)
Set the clock selection attribute of a condition variable attributes object.
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
Sleep some amount of time.
Definition: clock.c:356
int clock_gettime(clockid_t clock_id, struct timespec *tp)
Read the specified clock.
Definition: clock.c:183
int pthread_mutex_setprioceiling(pthread_mutex_t *__restrict mutex, int prioceiling, int *__restrict old_ceiling)
Set a mutex&#39;s priority ceiling.
Definition: mutex.c:720
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp)
Sleep some amount of time.
Definition: clock.c:311