1 /*
2 
3 Copyright (C) 2008-2021 Michele Martone
4 
5 This file is part of librsb.
6 
7 librsb is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11 
12 librsb is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public
18 License along with librsb; see the file COPYING.
19 If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 /* @cond INNERDOC */
23 /**
24  * @file
25  * @brief System, or standard library related functions.
26  * @author Michele Martone
27  * */
28 #ifndef RSB_SYS_H_INCLUDED
29 #define RSB_SYS_H_INCLUDED
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif /* __cplusplus */
34 
35 #include <stdlib.h>
36 #include <time.h>	/* clock, difftime */
37 #include <sys/time.h>	/* timeval,gettimeofday */
38 #include <stdio.h>	/* printf */
39 #include <strings.h>   /* formerly bzero (now using memset) */
40 #include <string.h>	/* memset, memcpy */
41 #include <stdarg.h>	/* vprintf, va_start, va_end */
42 #if RSB_HAVE_LIMITS_H
43 #include <limits.h>	/* CHAR_BIT */
44 #endif /* RSB_HAVE_LIMITS_H  */
45 #include "rsb_perf.h"
46 
47 void * rsb__malloc(size_t size);
48 void * rsb__calloc(size_t n);
49 void * rsb__calloc_parallel(size_t n);
50 rsb_time_t rsb_do_time(void);
51 rsb_time_t rsb__timer_granularity(void );
52 void * rsb__free(void *rsb_data);
53 void * rsb__realloc(void *rsb_data, size_t size);
54 void * rsb__do_realloc(void *rsb_data, size_t size, size_t alignment);
55 void * rsb__aligned_malloc(size_t size, size_t alignment);
56 rsb_err_t rsb__sys_info(void);
57 long rsb__get_l1c_size(void);
58 long rsb__get_l2c_size(void);
59 long rsb__get_l3c_size(void);
60 long rsb__get_l4c_size(void);
61 long rsb__get_lastlevel_c_size(void);
62 long rsb__get_first_level_c_size(void);
63 rsb_int_t rsb__get_cache_levels_num(void);
64 long rsb__get_lnc_size(int n);
65 long rsb__know_cache_sizes(void);
66 rsb_err_t rsb__sys_init(void);
67 /* long rsb_want_executing_threads(void); */
68 
69 #ifndef RSB_CONDITIONAL_FREE_FAKE
70 #define RSB_CONDITIONAL_FREE_FAKE(p) {if((p))/*rsb__free((p))*/;(p)=NULL;}
71 #endif /* RSB_CONDITIONAL_FREE_FAKE */
72 /* A useful macro */
73 #ifndef RSB_CONDITIONAL_FREE
74 #define RSB_CONDITIONAL_FREE(p) {if((p)){rsb__free((p));(p)=NULL;}} /* frees and nullifies the associated pointer. */
75 /*#define RSB_CONDITIONAL_FREE(p) RSB_CONDITIONAL_FREE_FAKE(p) */
76 #endif /* RSB_CONDITIONAL_FREE */
77 
78 extern int rsb__error(const char * format, ...);
79 void rsb__g_rsb_memory_counter_init(void);
80 size_t rsb__get_g_rsb_allocations_count(void);
81 
82 /* ... and what about __PRETTY_FUNCTION__ ? */
83 #ifndef __func__
84 #ifdef __STDC_VERSION__
85 #if __STDC_VERSION__ < 199901L
86 # if __GNUC__ >= 2
87 #  define __func__ __FUNCTION__
88 # else /* __GNUC__  */
89 #  define __func__ "<unknown>"
90 # endif /* __GNUC__  */
91 #endif /* __STDC_VERSION__ */
92 #else /* __STDC_VERSION__ */
93 # define __func__ "<unknown>"
94 #endif /* __STDC_VERSION__ */
95 #endif /* __func__ */
96 
97 /* '1' is better than '{;}' in situations like : if(..)RSB_INFO(...);else RSB_INFO(...); */
98 #define RSB_NULL_EXPRESSION_FOR_ZEN_HAPPINESS 1
99 #define RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS RSB_NULL_EXPRESSION_FOR_ZEN_HAPPINESS
100 
101 /* FIXME : write a RSB_PRINTF */
102 /* note that the first argument should be a format string! */
103 /* note that variadic macros should not be supported by standard C++ */
104 /* note that putting brackets around this macro in the macro itself would break
105 	conditionals like:
106 	if(foo)
107 		RSB_ERROR("bar");
108 	else
109 		RSB_ERROR("baz");
110  */
111 #if RSB_INT_ERR_VERBOSITY==1
112 
113 /* #define RSB_FFL_PRINTF printf("In file %20s (in %s) at line %10d:\n",__FILE__,__func__,__LINE__) */
114 #define RSB_FFL_PRINTF printf("In %s located in %20s:%d :\n",__func__,__FILE__,__LINE__)
115 
116 #define RSB_DEPRECATED( ... ) \
117 	RSB_FFL_PRINTF,	\
118 	rsb__error( __VA_ARGS__ ), \
119 	printf(" is DEPRECATED !!\n") \
120 
121 #define RSB_ERROR( ... ) \
122 	RSB_FFL_PRINTF,	\
123 	rsb__error( __VA_ARGS__ )
124 
125 #define RSB_OCTAVE_ERROR( ... ) \
126 	RSB_ERROR("ERROR:"), RSB_ERROR( __VA_ARGS__ ),octave_failed_tests++;
127 
128 #define RSB_FATAL( ... ) {RSB_ERROR( __VA_ARGS__ );exit(-1);}
129 #else /* RSB_INT_ERR_VERBOSITY */
130 #define RSB_DEPRECATED( ... )  RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
131 #define RSB_ERROR( ... ) RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
132 #define RSB_OCTAVE_ERROR( ... ) RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
133 #define RSB_FATAL( ... )  RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
134 #endif /* RSB_INT_ERR_VERBOSITY */
135 /* FIXME: RSB_FATAL is obsolete */
136 /* FIXME: RSB_ERROR shall be diversified */
137 
138 
139 #define RSB_IOLEVEL RSB_WANT_IO_LEVEL
140 /*#define RSB_IOLEVEL 7*/ /* FIXME: EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL EXPERIMENTAL */
141 #define RSB_ALLOW_FPRINTF (RSB_IOLEVEL&4)
142 #define RSB_ALLOW_STDOUT  (RSB_IOLEVEL&1)
143 #define RSB_ALLOW_STDERR  (RSB_IOLEVEL&2)
144 
145 #if RSB_ALLOW_STDERR
146 /* WARNING : calling this without arguments causes segfaults! */
147 #define RSB_STDERR( ... ) fprintf(stderr, __VA_ARGS__ )
148 #else /* RSB_ALLOW_STDERR */
149 #define RSB_STDERR( ... ) RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
150 #endif /* RSB_ALLOW_STDERR */
151 #define RSB_IO_ERROR RSB_STDERR
152 #define RSB_IO_NOTICE RSB_STDERR
153 
154 #if RSB_ALLOW_STDOUT
155 /* explicit standard output printout */
156 #define RSB_STDOUT( ... ) fprintf(stdout, __VA_ARGS__ )
157 
158 /* */
159 /*#define RSB_DEBUGINFO( ... ) printf("%s @ %10d (%s):\n",__FILE__,__LINE__,__func__),RSB_STDOUT(__VA_ARGS__)*/
160 
161 /** RSB_WARN is used in not-yet-implemented-feature-but-skip-error-triggering situations.  */
162 #define RSB_WARN( ... ) \
163 	RSB_STDOUT("%s\n#","#*****************************************************************************"),\
164 	RSB_STDOUT( __VA_ARGS__ ),\
165 	RSB_STDOUT("%s\n","#*****************************************************************************")
166 #else
167 #define RSB_STDOUT( ... ) RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
168 #define RSB_WARN( ... ) RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
169 #endif /* RSB_ALLOW_STDOUT */
170 
171 
172 #if (RSB_WANT_IO_LEVEL==0)
173 #define RSB_QUIET 1
174 #endif /* RSB_WANT_IO_LEVEL */
175 
176 /* RSB_INFO is the stream of informative messages which are user requested and expected (that is, not errors). */
177 #ifdef RSB_QUIET
178 #define RSB_INFO( ... ) RSB_NULL_COMMA_STATEMENT_FOR_ZEN_HAPPINESS
179 #else /* RSB_QUIET */
180 #define RSB_INFO( ... ) ((rsb_global_session_handle.out_stream)?fprintf(rsb_global_session_handle.out_stream, __VA_ARGS__ ):RSB_NULL_EXPRESSION_FOR_ZEN_HAPPINESS)
181 #endif /* RSB_QUIET */
182 /* RSB_FPRINTF is just a tool */
183 #define RSB_FPRINTF( ... ) fprintf( __VA_ARGS__ )
184 
185 #if   defined(__GNUC__)
186 	/* GCC */
187         #define RSB_UNLIKELY(expr) __builtin_expect(!!(expr),0)
188         #define RSB_LIKELY(expr)   __builtin_expect(!!(expr),1)
189         #define RSB_ALIGNED __attribute__((aligned (sizeof(double)*sizeof(unsigned char))))
190 /*        #define RSB_ALIGNED __attribute__((aligned (64)))	*/
191 #else /* __GNUC__ */
192         #define RSB_UNLIKELY(expr)  (expr)
193         #define RSB_LIKELY(expr)   (expr)
194         #define RSB_ALIGNED
195 #endif /* __GNUC__ */
196 #define RSB_PERFORMANCE_BINARY_DUMP_FILE_SIGNATURE_MAX_CHARS 128
197 #define RSB_PERFORMANCE_BINARY_DUMP_FILE_SIGNATURE \
198 "this is a non portable performance dump file, dude........\x40\x40\x40\x40"
199 
200 #define RSB_TIMER_GRANULARITY_TEST_TIMES (1024*128)
201 #define RSB_TIMER_SANITY_TEST_TIMES (1024)
202 #define RSB_MIN_ALLOWED_CACHE_BLOCK_SIZE (1024)	/* in bytes */
203 #define RSB_MAX_ALLOWED_CACHE_BLOCK_SIZE ((1024)*(1024)*(1024))	/* in bytes */
204 
205 #define RSB_BZERO(b,len) (memset((b), '\0', (len)), (void) 0) /* recommendation from IEEE Std 1003.1 since bzero has been made legacy */
206 
207 #define RSB_BZERO_P(P) RSB_BZERO(P,sizeof(*(P)))
208 
209 #define RSB_MEMMOVE memmove	/**< we have the chance of using a custom memmove function in this way */
210 
211 #define RSB_MEMCMP memcmp	/**< we have the chance of using a custom memcmp function in this way */
212 
213 int rsb__getopt_long( int argc, char * const argv[], const char *optstring, const rsb_option *longopts, int *longindex);
214 #define rsb_getopt_long rsb__getopt_long
215 #define rsb_numerical_memcpy(TYPECODE,DST,DOFF,SRC,SOFF,N) {size_t es = RSB_NUMERICAL_TYPE_SIZE(TYPECODE); 	\
216 	rsb__memcpy( 					\
217 			((rsb_byte_t*)(DST)+es*(DOFF)) ,	\
218 			((const rsb_byte_t*)(SRC)+es*(SOFF)) ,	\
219 			es*(N));	\
220 } 		/* see rsb__xcopy(DST,SRC,DOFF,SOFF,N,size_t el_size) */
221 void *rsb__memcpy(void *RSB_RESTRICT dest, const void *RSB_RESTRICT src, size_t n);
222 
223 rsb_time_t rsb__timer_sanity(void);
224 size_t rsb__sys_free_system_memory(void);
225 size_t rsb__sys_total_system_memory(void);
226 long rsb__get_lastlevel_c_size_per_thread(void);
227 long rsb__get_cache_block_byte_size(void);
228 /* long rsb_set_executing_threads(long tn); */
229 rsb_err_t rsb__print_memory_allocation_info(void);
230 rsb_err_t rsb__lock_as_memory_resident(rsb_bool_t dolock);
231 int rsb__fileno(FILE *stream);
232 rsb_err_t rsb__getrusage(void);
233 const rsb_char_t * rsb__getenv(const rsb_char_t * name);
234 const rsb_char_t * rsb__getenv_nnr(const rsb_char_t * name);
235 long rsb__get_lnc_size_hwloc(int n);
236 
237 #define RSB_THREADS_GET_MAX_LIB	-5
238 #define RSB_THREADS_GET_MAX_SYS	-4
239 #define RSB_THREADS_GET_MAX	-3
240 #define RSB_THREADS_GET		-2
241 #define RSB_THREADS_AUTO	-1
242 rsb_int_t rsb__set_num_threads(rsb_int_t tn);
243 
244 #ifdef __cplusplus
245 }
246 #endif  /* __cplusplus */
247 
248 #endif /* RSB_SYS_H_INCLUDED */
249 
250 /* @endcond */
251