Xenomai  3.0.5
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_ATTR_SETAFFINITY_NP
112 #include <sched.h>
113 static inline
114 int pthread_attr_setaffinity_np(pthread_attr_t *attr,
115  size_t cpusetsize, const cpu_set_t *cpuset)
116 {
117  if (CPU_ISSET(0, cpuset) && CPU_COUNT(cpuset) == 1)
118  return 0;
119  return ENOSYS;
120 }
121 #endif /* !HAVE_PTHREAD_ATTR_SETAFFINITY_NP */
122 
123 #ifndef HAVE_PTHREAD_SETAFFINITY_NP
124 static inline
125 int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,
126  const cpu_set_t *cpuset)
127 {
128  if (CPU_ISSET(0, cpuset) && CPU_COUNT(cpuset) == 1)
129  return 0;
130  return ENOSYS;
131 }
132 #endif /* !HAVE_PTHREAD_SETAFFINITY_NP */
133 
134 #if !defined(HAVE_CLOCK_NANOSLEEP) && defined(CONFIG_XENO_MERCURY)
135 /*
136  * Best effort for a Mercury setup based on an outdated libc lacking
137  * "advanced" real-time support. Too bad if the system clock is set
138  * during sleep time. This is a non-issue for Cobalt, as the libcobalt
139  * implementation will always be picked instead.
140  */
141 __weak int clock_nanosleep(clockid_t clock_id, int flags,
142  const struct timespec *request,
143  struct timespec *remain)
144 {
145  struct timespec now, tmp;
146 
147  tmp = *request;
148  if (flags) {
149  clock_gettime(CLOCK_REALTIME, &now);
150  tmp.tv_sec -= now.tv_sec;
151  tmp.tv_nsec -= now.tv_nsec;
152  if (tmp.tv_nsec < 0) {
153  tmp.tv_sec--;
154  tmp.tv_nsec += 1000000000;
155  }
156  }
157 
158  return nanosleep(&tmp, remain);
159 }
160 #endif /* !HAVE_CLOCK_NANOSLEEP && MERCURY */
161 
162 #ifndef HAVE_SCHED_GETCPU
163 /*
164  * Might be declared in uClibc headers but not actually implemented,
165  * so we make the placeholder a weak symbol.
166  */
167 __weak int sched_getcpu(void)
168 {
169  return 0; /* outdated uClibc: assume uniprocessor. */
170 }
171 #endif /* !HAVE_SCHED_GETCPU */
172 
173 #ifndef HAVE_SHM_OPEN
174 __weak int shm_open(const char *name, int oflag, mode_t mode)
175 {
176  errno = ENOSYS;
177  return -1;
178 }
179 #endif /* !HAVE_SHM_OPEN */
180 
181 #ifndef HAVE_SHM_UNLINK
182 __weak int shm_unlink(const char *name)
183 {
184  errno = ENOSYS;
185  return -1;
186 }
187 #endif /* !HAVE_SHM_UNLINK */
188 
189 #ifndef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP
190 #define pthread_mutexattr_setrobust_np(__attr, __robust) \
191  ({ ENOSYS; })
192 #endif /* !HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP */
193 
194 #if !defined(HAVE_PTHREAD_SETNAME_NP) && defined(CONFIG_XENO_MERCURY)
195 static inline
196 int pthread_setname_np(pthread_t thread, const char *name)
197 {
198  return ENOSYS;
199 }
200 #endif /* !HAVE_PTHREAD_SETNAME_NP && MERCURY */
201 
202 #endif /* __IN_XENO__ */
203 
204 #if defined(__COBALT_WRAP__) || defined(__IN_XENO__)
205 /*
206  * clock_nanosleep() and pthread_setname_np() must be declared when the libc
207  * does not declare them, both for compiling xenomai, and for compiling
208  * applications wrapping these symbols to the libcobalt versions.
209  */
210 #ifndef HAVE_CLOCK_NANOSLEEP
211 int clock_nanosleep(clockid_t clock_id, int flags,
212  const struct timespec *request,
213  struct timespec *remain);
214 #endif /* !HAVE_CLOCK_NANOSLEEP */
215 
216 #ifndef HAVE_PTHREAD_SETNAME_NP
217 int pthread_setname_np(pthread_t thread, const char *name);
218 #endif /* !HAVE_PTHREAD_SETNAME_NP */
219 #endif /* __COBALT_WRAP__ || __IN_XENO__ */
220 
221 #ifndef PTHREAD_STACK_DEFAULT
222 #define PTHREAD_STACK_DEFAULT \
223  ({ \
224  int __ret = PTHREAD_STACK_MIN; \
225  if (__ret < 65536) \
226  __ret = 65536; \
227  __ret; \
228  })
229 #endif /* !PTHREAD_STACK_DEFAULT */
230 
231 #endif /* _BOILERPLATE_LIBC_H */
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_setname_np(pthread_t thread, const char *name)
Set a thread name.
Definition: thread.c:448
int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int *proto)
Get the protocol attribute from a mutex attributes object.
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:335
int clock_gettime(clockid_t clock_id, struct timespec *tp)
Read the specified clock.
Definition: clock.c:181
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp)
Sleep some amount of time.
Definition: clock.c:291