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