Xenomai  3.0-rc3
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 #ifdef __IN_XENO__
22 /*
23  * Quirks for dealing with outdated libc* issues. This header will be
24  * parsed by the Xenomai implementation only, applications based on it
25  * have to provide their own set of wrappers as they should decide by
26  * themselves what to do when a feature is missing.
27  */
28 #include <xeno_config.h>
29 #include <errno.h>
30 #include <boilerplate/compiler.h>
31 
32 #if defined(__UCLIBC__) && !defined(UCLIBC_HAS_THREADS_NATIVE)
33 enum {
34  PTHREAD_PRIO_NONE,
35  PTHREAD_PRIO_INHERIT,
36  PTHREAD_PRIO_PROTECT
37 };
38 #endif /* __UCLIBC__ && !UCLIBC_HAS_THREADS_NATIVE */
39 
40 #ifndef HAVE_FORK
41 static inline int fork(void)
42 {
43  errno = ENOSYS;
44  return -1;
45 }
46 #endif
47 
48 #ifndef HAVE_PTHREAD_ATFORK
49 #ifndef HAVE_FORK
50 static inline
51 int pthread_atfork(void (*prepare)(void), void (*parent)(void),
52  void (*child)(void))
53 {
54  return 0;
55 }
56 #else
57 #error "fork() without pthread_atfork()"
58 #endif
59 #endif /* !HAVE_PTHREAD_ATFORK */
60 
61 #ifndef HAVE_PTHREAD_GETATTR_NP
62 static inline
63 int pthread_getattr_np(pthread_t th, pthread_attr_t *attr)
64 {
65  return ENOSYS;
66 }
67 #endif /* !HAVE_PTHREAD_GETATTR_NP */
68 
69 #ifndef HAVE_PTHREAD_CONDATTR_SETCLOCK
70 static inline
71 int pthread_condattr_setclock(pthread_condattr_t *__restrict__ attr,
72  clockid_t clock_id)
73 {
74  return clock_id == CLOCK_REALTIME ? 0 : ENOSYS;
75 }
76 #endif /* !HAVE_PTHREAD_CONDATTR_SETCLOCK */
77 
78 #ifndef HAVE_PTHREAD_CONDATTR_GETCLOCK
79 static inline
80 int pthread_condattr_getclock(const pthread_condattr_t *__restrict__ attr,
81  clockid_t *__restrict__ clock_id)
82 {
83  *clock_id = CLOCK_REALTIME;
84 
85  return 0;
86 }
87 #endif /* !HAVE_PTHREAD_CONDATTR_GETCLOCK */
88 
89 #ifndef HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL
90 static inline
91 int pthread_mutexattr_setprotocol(pthread_mutexattr_t *__restrict__ attr,
92  int protocol)
93 {
94  return protocol == PTHREAD_PRIO_NONE ? 0 : ENOSYS;
95 }
96 #endif /* !HAVE_PTHREAD_MUTEXATTR_SETPROTOCOL */
97 
98 #ifndef HAVE_PTHREAD_MUTEXATTR_GETPROTOCOL
99 static inline
100 int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *
101  __restrict__ attr, int *__restrict__ protocol)
102 {
103  *protocol = PTHREAD_PRIO_NONE;
104 
105  return 0;
106 }
107 #endif /* !HAVE_PTHREAD_MUTEXATTR_GETPROTOCOL */
108 
109 #ifndef HAVE_PTHREAD_ATTR_SETAFFINITY_NP
110 static inline
111 int pthread_attr_setaffinity_np(pthread_attr_t *attr,
112  size_t cpusetsize, const cpu_set_t *cpuset)
113 {
114  return ENOSYS;
115 }
116 #endif /* !HAVE_PTHREAD_ATTR_SETAFFINITY_NP */
117 
118 #if !defined(HAVE_CLOCK_NANOSLEEP) && defined(CONFIG_XENO_MERCURY)
119 /*
120  * Best effort for a Mercury setup based on an outdated libc lacking
121  * "advanced" real-time support. Too bad if the system clock is set
122  * during sleep time. This is a non-issue for Cobalt, as the libcobalt
123  * implementation will always be picked instead.
124  */
125 __weak inline int clock_nanosleep(clockid_t clock_id, int flags,
126  const struct timespec *request,
127  struct timespec *remain)
128 {
129  struct timespec now, tmp;
130 
131  tmp = *request;
132  if (flags) {
133  clock_gettime(CLOCK_REALTIME, &now);
134  tmp.tv_sec -= now.tv_sec;
135  tmp.tv_nsec -= now.tv_nsec;
136  if (tmp.tv_nsec < 0) {
137  tmp.tv_sec--;
138  tmp.tv_nsec += 1000000000;
139  }
140  }
141 
142  return nanosleep(&tmp, remain);
143 }
144 #else /* HAVE_CLOCK_NANOSLEEP || COBALT */
145 /*
146  * Either libcobalt or the libc implements this, we only want the
147  * possibly missing declaration from the libc headers.
148  */
149 int clock_nanosleep(clockid_t clock_id, int flags,
150  const struct timespec *request,
151  struct timespec *remain);
152 #endif /* HAVE_CLOCK_NANOSLEEP || COBALT */
153 
154 #ifndef HAVE_SCHED_GETCPU
155 /*
156  * Might be declared in uClibc headers but not actually implemented,
157  * so we make the placeholder a weak symbol.
158  */
159 __weak inline int sched_getcpu(void)
160 {
161  return 0; /* outdated uClibc: assume uniprocessor. */
162 }
163 #endif /* !HAVE_SCHED_GETCPU */
164 
165 #ifndef HAVE_SHM_OPEN
166 __weak inline int shm_open(const char *name, int oflag, mode_t mode)
167 {
168  errno = ENOSYS;
169  return -1;
170 }
171 #endif /* !HAVE_SHM_OPEN */
172 
173 #ifndef HAVE_SHM_UNLINK
174 __weak inline int shm_unlink(const char *name)
175 {
176  errno = ENOSYS;
177  return -1;
178 }
179 #endif /* !HAVE_SHM_UNLINK */
180 
181 #ifndef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP
182 #define pthread_mutexattr_setrobust_np(__attr, __robust) \
183  ({ ENOSYS; })
184 #endif /* !HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP */
185 
186 #if !defined(HAVE_PTHREAD_SETNAME_NP) && defined(CONFIG_XENO_MERCURY)
187 static inline
188 int pthread_setname_np(pthread_t thread, const char *name)
189 {
190  return ENOSYS;
191 }
192 #else /* HAVE_PTHREAD_SETNAME_NP || COBALT */
193 /* Same as clock_nanosleep() */
194 int pthread_setname_np(pthread_t thread, const char *name);
195 #endif /* HAVE_PTHREAD_SETNAME_NP || COBALT */
196 
197 #endif /* __IN_XENO__ */
198 
199 #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:410
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:330
int clock_gettime(clockid_t clock_id, struct timespec *tp)
Read the specified clock.
Definition: clock.c:179
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp)
Sleep some amount of time.
Definition: clock.c:287