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