Xenomai  3.0-rc7
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 #include <sched.h>
111 static inline
112 int pthread_attr_setaffinity_np(pthread_attr_t *attr,
113  size_t cpusetsize, const cpu_set_t *cpuset)
114 {
115  if (CPU_ISSET(0, cpuset) && CPU_COUNT(cpuset) == 1)
116  return 0;
117  return ENOSYS;
118 }
119 #endif /* !HAVE_PTHREAD_ATTR_SETAFFINITY_NP */
120 
121 #if !defined(HAVE_CLOCK_NANOSLEEP) && defined(CONFIG_XENO_MERCURY)
122 /*
123  * Best effort for a Mercury setup based on an outdated libc lacking
124  * "advanced" real-time support. Too bad if the system clock is set
125  * during sleep time. This is a non-issue for Cobalt, as the libcobalt
126  * implementation will always be picked instead.
127  */
128 __weak inline int clock_nanosleep(clockid_t clock_id, int flags,
129  const struct timespec *request,
130  struct timespec *remain)
131 {
132  struct timespec now, tmp;
133 
134  tmp = *request;
135  if (flags) {
136  clock_gettime(CLOCK_REALTIME, &now);
137  tmp.tv_sec -= now.tv_sec;
138  tmp.tv_nsec -= now.tv_nsec;
139  if (tmp.tv_nsec < 0) {
140  tmp.tv_sec--;
141  tmp.tv_nsec += 1000000000;
142  }
143  }
144 
145  return nanosleep(&tmp, remain);
146 }
147 #else /* HAVE_CLOCK_NANOSLEEP || COBALT */
148 /*
149  * Either libcobalt or the libc implements this, we only want the
150  * possibly missing declaration from the libc headers.
151  */
152 int clock_nanosleep(clockid_t clock_id, int flags,
153  const struct timespec *request,
154  struct timespec *remain);
155 #endif /* HAVE_CLOCK_NANOSLEEP || COBALT */
156 
157 #ifndef HAVE_SCHED_GETCPU
158 /*
159  * Might be declared in uClibc headers but not actually implemented,
160  * so we make the placeholder a weak symbol.
161  */
162 __weak inline int sched_getcpu(void)
163 {
164  return 0; /* outdated uClibc: assume uniprocessor. */
165 }
166 #endif /* !HAVE_SCHED_GETCPU */
167 
168 #ifndef HAVE_SHM_OPEN
169 __weak inline int shm_open(const char *name, int oflag, mode_t mode)
170 {
171  errno = ENOSYS;
172  return -1;
173 }
174 #endif /* !HAVE_SHM_OPEN */
175 
176 #ifndef HAVE_SHM_UNLINK
177 __weak inline int shm_unlink(const char *name)
178 {
179  errno = ENOSYS;
180  return -1;
181 }
182 #endif /* !HAVE_SHM_UNLINK */
183 
184 #ifndef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP
185 #define pthread_mutexattr_setrobust_np(__attr, __robust) \
186  ({ ENOSYS; })
187 #endif /* !HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP */
188 
189 #if !defined(HAVE_PTHREAD_SETNAME_NP) && defined(CONFIG_XENO_MERCURY)
190 static inline
191 int pthread_setname_np(pthread_t thread, const char *name)
192 {
193  return ENOSYS;
194 }
195 #else /* HAVE_PTHREAD_SETNAME_NP || COBALT */
196 /* Same as clock_nanosleep() */
197 int pthread_setname_np(pthread_t thread, const char *name);
198 #endif /* HAVE_PTHREAD_SETNAME_NP || COBALT */
199 
200 #endif /* __IN_XENO__ */
201 
202 #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:439
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