Xenomai  3.0.8
smokey.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 _XENOMAI_SMOKEY_SMOKEY_H
19 #define _XENOMAI_SMOKEY_SMOKEY_H
20 
21 #include <stdarg.h>
22 #include <pthread.h>
23 #include <boilerplate/list.h>
24 #include <boilerplate/libc.h>
25 #include <copperplate/clockobj.h>
26 #include <xenomai/init.h>
27 
28 #ifdef HAVE_FORK
29 #define do_fork fork
30 #else
31 #define do_fork vfork
32 #endif
33 
34 #define SMOKEY_INT(__name) { \
35  .name = # __name, \
36  .parser = smokey_int, \
37  .matched = 0, \
38  }
39 
40 #define SMOKEY_BOOL(__name) { \
41  .name = # __name, \
42  .parser = smokey_bool, \
43  .matched = 0, \
44  }
45 
46 #define SMOKEY_STRING(__name) { \
47  .name = # __name, \
48  .parser = smokey_string, \
49  .matched = 0, \
50  }
51 
52 #define SMOKEY_ARGLIST(__args...) ((struct smokey_arg[]){ __args })
53 
54 #define SMOKEY_NOARGS (((struct smokey_arg[]){ { .name = NULL } }))
55 
56 struct smokey_arg {
57  const char *name;
58  int (*parser)(const char *s,
59  struct smokey_arg *arg);
60  union {
61  int n_val;
62  char *s_val;
63  } u;
64  int matched;
65 };
66 
67 struct smokey_test {
68  const char *name;
69  struct smokey_arg *args;
70  int nargs;
71  const char *description;
72  int (*run)(struct smokey_test *t,
73  int argc, char *const argv[]);
74  struct {
75  int id;
76  struct pvholder next;
77  } __reserved;
78 };
79 
80 #define for_each_smokey_test(__pos) \
81  pvlist_for_each_entry((__pos), &smokey_test_list, __reserved.next)
82 
83 #define __smokey_arg_count(__args) \
84  (sizeof(__args) / sizeof(__args[0]))
85 
86 #define smokey_test_plugin(__plugin, __args, __desc) \
87  static int run_ ## __plugin(struct smokey_test *t, \
88  int argc, char *const argv[]); \
89  static struct smokey_test __plugin = { \
90  .name = #__plugin, \
91  .args = (__args), \
92  .nargs = __smokey_arg_count(__args), \
93  .description = (__desc), \
94  .run = run_ ## __plugin, \
95  }; \
96  __early_ctor void smokey_plugin_ ## __plugin(void); \
97  void smokey_plugin_ ## __plugin(void) \
98  { \
99  smokey_register_plugin(&(__plugin)); \
100  }
101 
102 #define SMOKEY_ARG(__plugin, __arg) (smokey_lookup_arg(&(__plugin), # __arg))
103 #define SMOKEY_ARG_ISSET(__plugin, __arg) (SMOKEY_ARG(__plugin, __arg)->matched)
104 #define SMOKEY_ARG_INT(__plugin, __arg) (SMOKEY_ARG(__plugin, __arg)->u.n_val)
105 #define SMOKEY_ARG_BOOL(__plugin, __arg) (!!SMOKEY_ARG_INT(__plugin, __arg))
106 #define SMOKEY_ARG_STRING(__plugin, __arg) (SMOKEY_ARG(__plugin, __arg)->u.s_val)
107 
108 #define smokey_check_errno(__expr) \
109  ({ \
110  int __ret = (__expr); \
111  if (__ret < 0) { \
112  __ret = -errno; \
113  __smokey_warning(__FILE__, __LINE__, "%s: %s", \
114  #__expr, strerror(errno)); \
115  } \
116  __ret; \
117  })
118 
119 #define smokey_check_status(__expr) \
120  ({ \
121  int __ret = (__expr); \
122  if (__ret) { \
123  __smokey_warning(__FILE__, __LINE__, "%s: %s", \
124  #__expr, strerror(__ret)); \
125  __ret = -__ret; \
126  } \
127  __ret; \
128  })
129 
130 #define smokey_assert(__expr) \
131  ({ \
132  int __ret = (__expr); \
133  if (!__ret) \
134  __smokey_warning(__FILE__, __LINE__, \
135  "assertion failed: %s", #__expr); \
136  __ret; \
137  })
138 
139 #define smokey_warning(__fmt, __args...) \
140  __smokey_warning(__FILE__, __LINE__, __fmt, ##__args)
141 
142 #define __T(__ret, __action) \
143  ({ \
144  (__ret) = (__action); \
145  if (__ret) { \
146  if ((__ret) > 0) \
147  (__ret) = -(__ret); \
148  smokey_warning("FAILED: %s (=%s)", \
149  __stringify(__action), \
150  symerror(__ret)); \
151  } \
152  (__ret) == 0; \
153  })
154 
155 #define __F(__ret, __action) \
156  ({ \
157  (__ret) = (__action); \
158  if ((__ret) == 0) \
159  smokey_warning("FAILED: %s (=0)", \
160  __stringify(__action)); \
161  else if ((__ret) > 0) \
162  (__ret) = -(__ret); \
163  (__ret) != 0; \
164  })
165 
166 #define __Terrno(__ret, __action) \
167  ({ \
168  (__ret) = (__action); \
169  if (__ret) { \
170  (__ret) = -errno; \
171  smokey_warning("FAILED: %s (=%s)", \
172  __stringify(__action), \
173  symerror(__ret)); \
174  } \
175  (__ret) == 0; \
176  })
177 
178 #define __Tassert(__expr) \
179  ({ \
180  int __ret = !!(__expr); \
181  if (!__ret) \
182  smokey_warning("FAILED: %s (=false)", \
183  __stringify(__expr)); \
184  __ret; \
185  })
186 
187 #define __Fassert(__expr) \
188  ({ \
189  int __ret = (__expr); \
190  if (__ret) \
191  smokey_warning("FAILED: %s (=true)", \
192  __stringify(__expr)); \
193  !__ret; \
194  })
195 
196 struct smokey_barrier {
197  pthread_mutex_t lock;
198  pthread_cond_t barrier;
199  int signaled;
200 };
201 
202 #ifdef __cplusplus
203 extern "C" {
204 #endif
205 
206 void smokey_register_plugin(struct smokey_test *t);
207 
208 int smokey_int(const char *s, struct smokey_arg *arg);
209 
210 int smokey_bool(const char *s, struct smokey_arg *arg);
211 
212 int smokey_string(const char *s, struct smokey_arg *arg);
213 
214 struct smokey_arg *smokey_lookup_arg(struct smokey_test *t,
215  const char *arg);
216 
217 int smokey_parse_args(struct smokey_test *t,
218  int argc, char *const argv[]);
219 
220 void smokey_vatrace(const char *fmt, va_list ap);
221 
222 void smokey_trace(const char *fmt, ...);
223 
224 void smokey_note(const char *fmt, ...);
225 
226 void __smokey_warning(const char *file, int lineno,
227  const char *fmt, ...);
228 
229 int smokey_barrier_init(struct smokey_barrier *b);
230 
231 void smokey_barrier_destroy(struct smokey_barrier *b);
232 
233 int smokey_barrier_wait(struct smokey_barrier *b);
234 
235 int smokey_barrier_timedwait(struct smokey_barrier *b,
236  struct timespec *ts);
237 
238 void smokey_barrier_release(struct smokey_barrier *b);
239 
240 int smokey_fork_exec(const char *path, const char *arg);
241 
242 #ifdef __cplusplus
243 }
244 #endif
245 
246 extern struct pvlistobj smokey_test_list;
247 
248 extern int smokey_keep_going;
249 
250 extern int smokey_verbose_mode;
251 
252 extern int smokey_on_vm;
253 
254 #endif /* _XENOMAI_SMOKEY_SMOKEY_H */