1 /**
2  * @file fg_definitions.h
3  * @brief Common definitions used by the Flowgrind daemon, controller, and libs
4  */
5 
6 /*
7  * Copyright (C) 2013-2014 Alexander Zimmermann <alexander.zimmermann@netapp.com>
8  *
9  * This file is part of Flowgrind.
10  *
11  * Flowgrind is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * Flowgrind is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with Flowgrind.  If not, see <http://www.gnu.org/licenses/>.
23  *
24  */
25 
26 #ifndef _FG_DEFINITIONS_H_
27 #define _FG_DEFINITIONS_H_
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif /* HAVE_CONFIG_H */
32 
33 /** These macros gain us a few percent of speed. @{ */
34 #define likely(x)   __builtin_expect(!!(x), 1)
35 #define unlikely(x) __builtin_expect(!!(x), 0)			/** @} */
36 
37 /** Suppress warning for unused argument. */
38 #define UNUSED_ARGUMENT(x) (void)x
39 
40 /** To determine the number of arguments in __VA_ARGS__. */
41 #define NARGS(...) (sizeof((int[]){__VA_ARGS__})/sizeof(int))
42 
43 /** foreach macro for iterating through enum values. */
44 #define foreach(iter, ...)					    \
45 	for(int keep = 1, count = 0, size = NARGS(__VA_ARGS__);	    \
46 	    keep && count != size; keep = !keep, count++)	    \
47 		for(iter = ((int[]){__VA_ARGS__}) + count;	    \
48 		    keep; keep = !keep)
49 
50 /** To vectorize an arbitrary function that takes any type of pointer. */
51 #define FN_APPLY(type, fn, ...) do {				\
52 	void *stopper = (int[]){0};				\
53 	void **list = (type*[]){__VA_ARGS__, stopper};		\
54 	for (int i=0; list[i] != stopper; i++)			\
55 		fn(list[i]);					\
56 } while(0)
57 
58 /** To free() an arbitrary number of variables. */
59 #define free_all(...) FN_APPLY(void, free, __VA_ARGS__);
60 
61 /** Assign value if it less than current one. */
62 #define ASSIGN_MIN(s, c)		\
63 	({ typeof (s) _s = (s);		\
64 	   typeof (c) _c = (c);		\
65 	   if (_s > _c) s = c; })
66 
67 /** Assign value if it's greater than current one. */
68 #define ASSIGN_MAX(s, c)		\
69 	({ typeof (s) _s = (s);		\
70 	   typeof (c) _c = (c);		\
71 	   if (_s < _c) s = c; })
72 
73 #endif /* _FG_DEFINITIONS_H_*/
74