OpenMPI 0.1.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

vt_iowrap.h
1 /**
2 * VampirTrace
3 * http://www.tu-dresden.de/zih/vampirtrace
4 *
5 * Copyright (c) 2005-2012, ZIH, TU Dresden, Federal Republic of Germany
6 *
7 * Copyright (c) 1998-2005, Forschungszentrum Juelich, Juelich Supercomputing
8 * Centre, Federal Republic of Germany
9 *
10 * See the file COPYING in the package base directory for details
11 **/
12
13 #ifndef _VT_IOWRAP_H_
14 #define _VT_IOWRAP_H_
15
16 #include "config.h"
17
18 #ifdef __cplusplus
19 # define EXTERN extern "C"
20 #else
21 # define EXTERN extern
22 #endif
23
24 #if (defined(VT_IOWRAP))
25
26 #include "vt_error.h"
27 #include "vt_thrd.h"
28 #include "vt_inttypes.h"
29
30 #include <string.h>
31
32
33 #define VT_ENABLE_IO_TRACING() \
34 VT_CHECK_THREAD; \
35 VTTHRD_IO_TRACING_ENABLED(VTTHRD_MY_VTTHRD) = 1; \
36 vt_debug_msg( DBG_INIT, "ENABLED I/O tracing (susp=%hhu) at " __FILE__ ", %i", VTTHRD_IO_TRACING_SUSPEND_CNT(VTTHRD_MY_VTTHRD), __LINE__ )
37
38 #define VT_DISABLE_IO_TRACING() \
39 VT_CHECK_THREAD; \
40 VTTHRD_IO_TRACING_ENABLED(VTTHRD_MY_VTTHRD) = 0; \
41 vt_debug_msg( DBG_INIT, "DISABLED I/O tracing (susp=%hhu) at " __FILE__ ", %i", VTTHRD_IO_TRACING_SUSPEND_CNT(VTTHRD_MY_VTTHRD), __LINE__ )
42
43 #define VT_SUSPEND_IO_TRACING(tid) \
44 { \
45 VTThrd *thrd; \
46 if( tid == VT_CURRENT_THREAD ) { \
47 VT_CHECK_THREAD; \
48 thrd = VTTHRD_MY_VTTHRD; \
49 } else { \
50 thrd = VTThrdv[tid]; \
51 } \
52 if( VTTHRD_IO_TRACING_ENABLED(thrd) ) { \
53 VTTHRD_IO_TRACING_STATE(thrd) = VTTHRD_IO_TRACING_ENABLED(thrd); \
54 VTTHRD_IO_TRACING_SUSPEND_CNT(thrd)++; \
55 VTTHRD_IO_TRACING_ENABLED(thrd) = 0; \
56 vt_debug_msg( DBG_INIT, "SUSPENDED I/O tracing (%hhu) at " __FILE__ ", %i", VTTHRD_IO_TRACING_SUSPEND_CNT(thrd), __LINE__ ); \
57 } \
58 else { \
59 VTTHRD_IO_TRACING_SUSPEND_CNT(thrd)++; \
60 vt_debug_msg( DBG_INIT, "SUSPENDED I/O tracing (%hhu) at " __FILE__ ", %i", VTTHRD_IO_TRACING_SUSPEND_CNT(thrd), __LINE__ ); \
61 } \
62 }
63
64 #define VT_RESUME_IO_TRACING(tid) \
65 { \
66 VTThrd *thrd; \
67 if( tid == VT_CURRENT_THREAD ) { \
68 VT_CHECK_THREAD; \
69 thrd = VTTHRD_MY_VTTHRD; \
70 } else { \
71 thrd = VTThrdv[tid]; \
72 } \
73 vt_debug_msg( DBG_INIT, "TRY RESUME I/O tracing (%hhu) at " __FILE__ ", %i", VTTHRD_IO_TRACING_SUSPEND_CNT(thrd), __LINE__ ); \
74 if( VTTHRD_IO_TRACING_SUSPEND_CNT(thrd) > 0 ) { \
75 if( (--VTTHRD_IO_TRACING_SUSPEND_CNT(thrd)) == 0 ) { \
76 vt_debug_msg( DBG_INIT, "RESUMED I/O tracing (%hhu) at " __FILE__ ", %i", VTTHRD_IO_TRACING_SUSPEND_CNT(thrd), __LINE__ ); \
77 VTTHRD_IO_TRACING_ENABLED(thrd) = VTTHRD_IO_TRACING_STATE(thrd); \
78 } \
79 } \
80 }
81
82 enum func_id {
83 open_IDX,
84 open64_IDX,
85 creat_IDX,
86 creat64_IDX,
87 close_IDX,
88 dup_IDX,
89 dup2_IDX,
90 lseek_IDX,
91 lseek64_IDX,
92 read_IDX,
93 write_IDX,
94 readv_IDX,
95 writev_IDX,
96 pread_IDX,
97 pwrite_IDX,
98 pread64_IDX,
99 pwrite64_IDX,
100 fdopen_IDX,
101 fopen_IDX,
102 fopen64_IDX,
103 fclose_IDX,
104 fseek_IDX,
105 fseeko_IDX,
106 fseeko64_IDX,
107 rewind_IDX,
108 fsetpos_IDX,
109 fsetpos64_IDX,
110 fread_IDX,
111 fwrite_IDX,
112 fgetc_IDX,
113 getc_IDX,
114 fgets_IDX,
115 gets_IDX,
116 fputc_IDX,
117 putc_IDX,
118 fputs_IDX,
119 puts_IDX,
120 fscanf_IDX,
121 fprintf_IDX,
122 unlink_IDX,
123 flockfile_IDX,
124 ftrylockfile_IDX,
125 funlockfile_IDX,
126 lockf_IDX,
127 fcntl_IDX,
128 sync_IDX,
129 fflush_IDX,
130 fsync_IDX,
131 fdatasync_IDX,
132 NUMFUNCTIONS
133 };
134
135 struct iofunctions {
136 int traceme;
137 int vt_func_id;
138 /* The following is necessary to avoid "warning: ISO C forbids conversion of
139 * object pointer to function pointer type". If the function calls break on some
140 * platform, the cause would most possibly lie here.
141 * Then sizeof(void *) != sizeof(<function pointer>)
142 */
143 union {
144 void *p;
145 void (*f)(void);
146 } lib_func;
147 };
148
149
150 /* io wrapper initialization/finalization */
151 EXTERN void vt_iowrap_externals_init(void);
152 EXTERN void vt_iowrap_init(void);
153 EXTERN void vt_iowrap_reg(void);
154 EXTERN void vt_iowrap_finalize(void);
155
156 EXTERN int(*libc_fprintf)(FILE *, const char *, ...);
157
158 #define open_FUNCDEF (int (*)(const char *, int, mode_t))
159 #define open_FUNCTYPE VT_IOOP_OPEN
160 #define open64_FUNCDEF (int (*)(const char *, int, mode_t))
161 #define open64_FUNCTYPE VT_IOOP_OPEN
162 #define creat_FUNCDEF (int (*)(const char *, mode_t))
163 #define creat_FUNCTYPE VT_IOOP_OPEN
164 #define creat64_FUNCDEF (int (*)(const char *, mode_t))
165 #define creat64_FUNCTYPE VT_IOOP_OPEN
166 #define dup_FUNCDEF (int (*)(int))
167 #define dup_FUNCTYPE VT_IOOP_DUP
168 #define dup2_FUNCDEF (int (*)(int, int))
169 #define dup2_FUNCTYPE VT_IOOP_DUP
170 #define close_FUNCDEF (int (*)(int))
171 #define close_FUNCTYPE VT_IOOP_CLOSE
172 #define lseek_FUNCDEF (off_t (*)(int, off_t, int))
173 #define lseek_FUNCTYPE VT_IOOP_SEEK
174 #define lseek64_FUNCDEF (off64_t (*)(int, off64_t, int))
175 #define lseek64_FUNCTYPE VT_IOOP_SEEK
176 #define read_FUNCDEF (ssize_t (*)(int, void *, size_t))
177 #define read_FUNCTYPE VT_IOOP_READ
178 #define write_FUNCDEF (ssize_t (*)(int, const void *, size_t))
179 #define write_FUNCTYPE VT_IOOP_WRITE
180 #define readv_FUNCDEF (int (*)(int, const struct iovec *, size_t))
181 #define readv_FUNCTYPE VT_IOOP_READ
182 #define writev_FUNCDEF (int (*)(int, const struct iovec *, size_t))
183 #define writev_FUNCTYPE VT_IOOP_WRITE
184 #define pread_FUNCDEF (ssize_t (*)(int, void *, size_t, off_t))
185 #define pread_FUNCTYPE VT_IOOP_READ
186 #define pwrite_FUNCDEF (ssize_t (*)(int, const void *, size_t, off_t))
187 #define pwrite_FUNCTYPE VT_IOOP_WRITE
188 #define pread64_FUNCDEF (ssize_t (*)(int, void *, size_t, off64_t))
189 #define pread64_FUNCTYPE VT_IOOP_READ
190 #define pwrite64_FUNCDEF (ssize_t (*)(int, const void *, size_t, off64_t))
191 #define pwrite64_FUNCTYPE VT_IOOP_WRITE
192 #define fdopen_FUNCDEF (FILE *(*)(int, const char *))
193 #define fdopen_FUNCTYPE VT_IOOP_OPEN
194 #define fopen_FUNCDEF (FILE *(*)(const char *, const char *))
195 #define fopen_FUNCTYPE VT_IOOP_OPEN
196 #define fopen64_FUNCDEF (FILE *(*)(const char *, const char *))
197 #define fopen64_FUNCTYPE VT_IOOP_OPEN
198 #define fclose_FUNCDEF (int (*)(FILE *))
199 #define fclose_FUNCTYPE VT_IOOP_CLOSE
200 #define fseek_FUNCDEF (int (*)(FILE *, long, int))
201 #define fseek_FUNCTYPE VT_IOOP_SEEK
202 #define fseeko_FUNCDEF (int (*)(FILE *, off_t, int))
203 #define fseeko_FUNCTYPE VT_IOOP_SEEK
204 #define fseeko64_FUNCDEF (int (*)(FILE *, off64_t, int))
205 #define fseeko64_FUNCTYPE VT_IOOP_SEEK
206 #define rewind_FUNCDEF (void (*)(FILE *))
207 #define rewind_FUNCTYPE VT_IOOP_SEEK
208 #define fsetpos_FUNCDEF (int (*)(FILE *, const fpos_t *))
209 #define fsetpos_FUNCTYPE VT_IOOP_SEEK
210 #define fsetpos64_FUNCDEF (int (*)(FILE *, const fpos64_t *))
211 #define fsetpos64_FUNCTYPE VT_IOOP_SEEK
212 #define fread_FUNCDEF (size_t (*)(void *, size_t, size_t, FILE *))
213 #define fread_FUNCTYPE VT_IOOP_READ
214 #define fwrite_FUNCDEF (size_t (*)(const void *, size_t, size_t, FILE *))
215 #define fwrite_FUNCTYPE VT_IOOP_WRITE
216 #define fgetc_FUNCDEF (int (*)(FILE *))
217 #define fgetc_FUNCTYPE VT_IOOP_READ
218 #define getc_FUNCDEF (int (*)(FILE *))
219 #define getc_FUNCTYPE VT_IOOP_READ
220 #define fgets_FUNCDEF (char *(*)(char *, int, FILE *))
221 #define fgets_FUNCTYPE VT_IOOP_READ
222 #define gets_FUNCDEF (char *(*)(char *))
223 #define gets_FUNCTYPE VT_IOOP_READ
224 #define fputc_FUNCDEF (int (*)(int, FILE *))
225 #define fputc_FUNCTYPE VT_IOOP_WRITE
226 #define putc_FUNCDEF (int (*)(int, FILE *))
227 #define putc_FUNCTYPE VT_IOOP_WRITE
228 #define fputs_FUNCDEF (int (*)(const char *, FILE *))
229 #define fputs_FUNCTYPE VT_IOOP_WRITE
230 #define puts_FUNCDEF (int (*)(const char *))
231 #define puts_FUNCTYPE VT_IOOP_WRITE
232 /* #define ungetc_FUNCDEF (int (*)(int, FILE *)) */
233 #define fscanf_FUNCDEF (int (*)(FILE *, const char *, ...))
234 #define fscanf_FUNCTYPE VT_IOOP_READ
235 #define fprintf_FUNCDEF (int (*)(FILE *, const char *, ...))
236 #define fprintf_FUNCTYPE VT_IOOP_WRITE
237 /* #define vfscanf_FUNCDEF (int (*)(FILE *, const char *, va_list)) */
238 /* #define vfprintf_FUNCDEF (int (*)(FILE *, const char *, va_list)) */
239 #define unlink_FUNCDEF (int (*)(const char *))
240 #define unlink_FUNCTYPE VT_IOOP_UNLINK
241 #define flockfile_FUNCDEF (void (*)(FILE *))
242 #define flockfile_FUNCTYPE VT_IOOP_LOCK
243 #define ftrylockfile_FUNCDEF (int (*)(FILE *))
244 #define ftrylockfile_FUNCTYPE VT_IOOP_LOCK
245 #define funlockfile_FUNCDEF (void (*)(FILE *))
246 #define funlockfile_FUNCTYPE VT_IOOP_UNLOCK
247 #define lockf_FUNCDEF (int (*)(int, int, off_t))
248 /* No need for lockf_FUNCTYPE, it is set inside the function */
249 #define fcntl_FUNCDEF (int (*)(int, int, void *))
250 /* No need for fcntl_FUNCTYPE, it is set inside the function */
251 #define sync_FUNCDEF (void (*)(void))
252 #define sync_FUNCTYPE VT_IOOP_SYNC
253 #define fflush_FUNCDEF (int (*)(FILE *))
254 #define fflush_FUNCTYPE VT_IOOP_SYNC
255 #define fsync_FUNCDEF (int (*)(int))
256 #define fsync_FUNCTYPE VT_IOOP_SYNC
257 #define fdatasync_FUNCDEF (int (*)(int))
258 #define fdatasync_FUNCTYPE VT_IOOP_SYNC
259
260 /* #define IOWRAP_REGION_DESCR_LEN 256 */
261 #define DBG_INIT 1
262 #define DBG_IO 2
263 #define DBG_VT_CALL 3
264 #define DBG_TRACECHK 4
265 #define DBG_FULL 255
266
267
268 #define FUNC_IDX(f) _FUNC_IDX(f)
269 #define _FUNC_IDX(f) f ## _IDX
270 #define VT_IOWRAP_FUNCDEF(f) f ## _FUNCDEF
271 #define VT_IOWRAP_FUNCTYPE(f) _VT_IOWRAP_FUNCTYPE(f)
272 #define _VT_IOWRAP_FUNCTYPE(f) f ## _FUNCTYPE
273 /* need double macro for stringify to evaluate macro arguments before stringifying */
274 #define stringify(x) _stringify(x)
275 #define _stringify(x) #x
276
277 /** Setup libc pointers
278 * ... to be used in global initialization before everything else
279 * iolib_handle MUST be initialized already!
280 */
281 #define VT_IOWRAP_INIT_FUNC(FUNC_NAME) \
282 { \
283 if (!iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.p) { \
284 vt_debug_msg(DBG_INIT, "init_func: dlsym(" stringify(FUNC_NAME) ") --> "); \
285 (void)dlerror(); \
286 iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.p = \
287 dlsym( iolib_handle, stringify(FUNC_NAME) ); \
288 vt_debug_msg(DBG_INIT, "%p", iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.p); \
289 if (!iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.p) \
290 symload_fail( stringify(FUNC_NAME), dlerror() ); \
291 } \
292 else { \
293 vt_debug_msg(DBG_INIT, "init_func: " stringify(FUNC_NAME) " was already looked up: %p", \
294 iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.p); \
295 } \
296 }
297
298 /** Setup VT region and tracing specific settings
299 * ... to be used in global initialization after RFG initialization
300 */
301 #define VT_IOWRAP_REG_FUNC(FUNC_NAME) \
302 { \
303 vt_debug_msg(DBG_INIT, "reg_func: vt_def_region(" stringify(FUNC_NAME) ")"); \
304 iofunctions[FUNC_IDX(FUNC_NAME)].vt_func_id = \
305 vt_def_region( VT_CURRENT_THREAD, stringify(FUNC_NAME), \
306 vt_fid, \
307 VT_NO_LNO, \
308 VT_NO_LNO, \
309 NULL, \
310 VT_LIBC_IO ); \
311 iofunctions[FUNC_IDX(FUNC_NAME)].traceme = 1; \
312 }
313
314 /** Call the function FUNC_NAME from the I/O library (usually libc)
315 */
316 #if 0
317 #define VT_IOWRAP_CALL_LIBFUNC(FUNC_NAME, RET, ...) \
318 { \
319 vt_libwrap_set_libc_errno(errno); \
320 RET = ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
321 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
322 (__VA_ARGS__); \
323 errno = vt_libwrap_get_libc_errno(); \
324 }
325 #endif
326 #define VT_IOWRAP_CALL_LIBFUNC0(FUNC_NAME, RET) \
327 { \
328 vt_libwrap_set_libc_errno(errno); \
329 RET = ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
330 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
331 (); \
332 errno = vt_libwrap_get_libc_errno(); \
333 }
334 #define VT_IOWRAP_CALL_LIBFUNC1(FUNC_NAME, RET, ARG1) \
335 { \
336 vt_libwrap_set_libc_errno(errno); \
337 RET = ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
338 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
339 (ARG1); \
340 errno = vt_libwrap_get_libc_errno(); \
341 }
342 #define VT_IOWRAP_CALL_LIBFUNC2(FUNC_NAME, RET, ARG1, ARG2) \
343 { \
344 vt_libwrap_set_libc_errno(errno); \
345 RET = ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
346 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
347 (ARG1, ARG2); \
348 errno = vt_libwrap_get_libc_errno(); \
349 }
350 #define VT_IOWRAP_CALL_LIBFUNC3(FUNC_NAME, RET, ARG1, ARG2, ARG3) \
351 { \
352 vt_libwrap_set_libc_errno(errno); \
353 RET = ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
354 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
355 (ARG1, ARG2, ARG3); \
356 errno = vt_libwrap_get_libc_errno(); \
357 }
358 #define VT_IOWRAP_CALL_LIBFUNC4(FUNC_NAME, RET, ARG1, ARG2, ARG3, ARG4) \
359 { \
360 vt_libwrap_set_libc_errno(errno); \
361 RET = ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
362 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
363 (ARG1, ARG2, ARG3, ARG4); \
364 errno = vt_libwrap_get_libc_errno(); \
365 }
366
367 #if 0
368 #define VT_IOWRAP_CALL_LIBFUNC_VOID(FUNC_NAME, ...) \
369 { \
370 vt_libwrap_set_libc_errno(errno); \
371 ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
372 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
373 (__VA_ARGS__); \
374 errno = vt_libwrap_get_libc_errno(); \
375 }
376 #endif
377 #define VT_IOWRAP_CALL_LIBFUNC_VOID0(FUNC_NAME) \
378 { \
379 vt_libwrap_set_libc_errno(errno); \
380 ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
381 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
382 (); \
383 errno = vt_libwrap_get_libc_errno(); \
384 }
385 #define VT_IOWRAP_CALL_LIBFUNC_VOID1(FUNC_NAME, ARG1) \
386 { \
387 vt_libwrap_set_libc_errno(errno); \
388 ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
389 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
390 (ARG1); \
391 errno = vt_libwrap_get_libc_errno(); \
392 }
393 #define VT_IOWRAP_CALL_LIBFUNC_VOID2(FUNC_NAME, ARG1, ARG2) \
394 { \
395 vt_libwrap_set_libc_errno(errno); \
396 ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
397 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
398 (ARG1, ARG2); \
399 errno = vt_libwrap_get_libc_errno(); \
400 }
401 #define VT_IOWRAP_CALL_LIBFUNC_VOID3(FUNC_NAME, ARG1, ARG2, ARG3) \
402 { \
403 vt_libwrap_set_libc_errno(errno); \
404 ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
405 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
406 (ARG1, ARG2, ARG3); \
407 errno = vt_libwrap_get_libc_errno(); \
408 }
409 #define VT_IOWRAP_CALL_LIBFUNC4_VOID(FUNC_NAME, ARG1, ARG2, ARG3, ARG4) \
410 { \
411 vt_libwrap_set_libc_errno(errno); \
412 ( VT_IOWRAP_FUNCDEF(FUNC_NAME) \
413 (iofunctions[FUNC_IDX(FUNC_NAME)].lib_func.f) ) \
414 (ARG1, ARG2, ARG3, ARG4); \
415 errno = vt_libwrap_get_libc_errno(); \
416 }
417
418 /** Resolve function address from the I/O library (usually libc)
419 */
420 #define VT_IOWRAP_INIT_IOFUNC() \
421 uint64_t matchingid = 0; \
422 ssize_t num_bytes=0; \
423 uint8_t was_recorded; \
424 uint8_t enable_memhooks=0; \
425 { \
426 if( VT_MEMHOOKS_ENABLED() ) \
427 { VT_MEMHOOKS_OFF(); enable_memhooks = 1; } \
428 if (!iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p) { \
429 get_iolib_handle(); \
430 (void)dlerror(); \
431 iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p = \
432 dlsym( iolib_handle, stringify(VT_IOWRAP_THISFUNCNAME) ); \
433 if (!iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p) \
434 symload_fail( stringify(VT_IOWRAP_THISFUNCNAME), dlerror() ); \
435 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_INIT_IOFUNC(): " stringify(VT_IOWRAP_THISFUNCNAME) " --> %p", iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p); \
436 } \
437 }
438
439 /** Resolve function address from the I/O library (usually libc)
440 */
441 #define VT_IOWRAP_INIT_IOFUNC_OPEN() \
442 uint64_t matchingid = 0; \
443 uint8_t was_recorded; \
444 uint8_t enable_memhooks=0; \
445 { \
446 if( VT_MEMHOOKS_ENABLED() ) \
447 { VT_MEMHOOKS_OFF(); enable_memhooks = 1; } \
448 if (!iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p) { \
449 get_iolib_handle(); \
450 (void)dlerror(); \
451 iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p = \
452 dlsym( iolib_handle, stringify(VT_IOWRAP_THISFUNCNAME) ); \
453 if (!iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p) \
454 symload_fail( stringify(VT_IOWRAP_THISFUNCNAME), dlerror() ); \
455 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_INIT_IOFUNC_OPEN(): " stringify(VT_IOWRAP_THISFUNCNAME) " --> %p", iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].lib_func.p); \
456 } \
457 }
458
459 /** Check if tracing is enabled and return immediately if not
460 */
461 #if 0
462 #define VT_IOWRAP_CHECK_TRACING(RET, ...) \
463 { \
464 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
465 if( !DO_TRACE() ) { \
466 VT_IOWRAP_CALL_LIBFUNC(VT_IOWRAP_THISFUNCNAME, RET, __VA_ARGS__); \
467 return RET; \
468 } \
469 }
470 #endif
471 #define VT_IOWRAP_CHECK_TRACING1(RET, ARG1) \
472 { \
473 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
474 if( !DO_TRACE() ) { \
475 VT_IOWRAP_CALL_LIBFUNC1(VT_IOWRAP_THISFUNCNAME, RET, ARG1); \
476 return RET; \
477 } \
478 }
479 #define VT_IOWRAP_CHECK_TRACING2(RET, ARG1, ARG2) \
480 { \
481 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
482 if( !DO_TRACE() ) { \
483 VT_IOWRAP_CALL_LIBFUNC2(VT_IOWRAP_THISFUNCNAME, RET, ARG1, ARG2); \
484 return RET; \
485 } \
486 }
487 #define VT_IOWRAP_CHECK_TRACING3(RET, ARG1, ARG2, ARG3) \
488 { \
489 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
490 if( !DO_TRACE() ) { \
491 VT_IOWRAP_CALL_LIBFUNC3(VT_IOWRAP_THISFUNCNAME, RET, ARG1, ARG2, ARG3); \
492 return RET; \
493 } \
494 }
495 #define VT_IOWRAP_CHECK_TRACING4(RET, ARG1, ARG2, ARG3, ARG4) \
496 { \
497 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
498 if( !DO_TRACE() ) { \
499 VT_IOWRAP_CALL_LIBFUNC4(VT_IOWRAP_THISFUNCNAME, RET, ARG1, ARG2, ARG3, ARG4); \
500 return RET; \
501 } \
502 }
503
504 #if 0
505 #define VT_IOWRAP_CHECK_TRACING_VOID(...) \
506 { \
507 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING_VOID(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
508 if( !DO_TRACE() ) { \
509 VT_IOWRAP_CALL_LIBFUNC_VOID(VT_IOWRAP_THISFUNCNAME, __VA_ARGS__); \
510 return; \
511 } \
512 }
513 #endif
514 #define VT_IOWRAP_CHECK_TRACING_VOID0() \
515 { \
516 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING_VOID(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
517 if( !DO_TRACE() ) { \
518 VT_IOWRAP_CALL_LIBFUNC_VOID0(VT_IOWRAP_THISFUNCNAME); \
519 return; \
520 } \
521 }
522 #define VT_IOWRAP_CHECK_TRACING_VOID1(ARG1) \
523 { \
524 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING_VOID(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
525 if( !DO_TRACE() ) { \
526 VT_IOWRAP_CALL_LIBFUNC_VOID1(VT_IOWRAP_THISFUNCNAME, ARG1); \
527 return; \
528 } \
529 }
530 #define VT_IOWRAP_CHECK_TRACING_VOID2(ARG1, ARG2) \
531 { \
532 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING_VOID(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
533 if( !DO_TRACE() ) { \
534 VT_IOWRAP_CALL_LIBFUNC_VOID2(VT_IOWRAP_THISFUNCNAME, ARG1, ARG2); \
535 return; \
536 } \
537 }
538 #define VT_IOWRAP_CHECK_TRACING_VOID3(ARG1, ARG2, ARG3) \
539 { \
540 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING_VOID(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
541 if( !DO_TRACE() ) { \
542 VT_IOWRAP_CALL_LIBFUNC_VOID3(VT_IOWRAP_THISFUNCNAME, ARG1, ARG2, ARG3); \
543 return; \
544 } \
545 }
546 #define VT_IOWRAP_CHECK_TRACING_VOID4(ARG1, ARG2, ARG3, ARG4) \
547 { \
548 vt_debug_msg( DBG_TRACECHK, "Macro VT_IOWRAP_CHECK_TRACING_VOID(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
549 if( !DO_TRACE() ) { \
550 VT_IOWRAP_CALL_LIBFUNC_VOID4(VT_IOWRAP_THISFUNCNAME, ARG1, ARG2, ARG3, ARG4); \
551 return; \
552 } \
553 }
554
555 /** Write enter record and I/O begin record, if necessary
556 */
557 #define VT_IOWRAP_ENTER_IOFUNC() \
558 { \
559 enter_time = vt_pform_wtime(); \
560 vt_debug_msg(DBG_VT_CALL, "vt_enter(" stringify(VT_IOWRAP_THISFUNCNAME) "), stamp %llu", (unsigned long long)enter_time); \
561 was_recorded = vt_enter( VT_CURRENT_THREAD, &enter_time, iofunctions[FUNC_IDX(VT_IOWRAP_THISFUNCNAME)].vt_func_id ); \
562 if( was_recorded ) { \
563 matchingid = VTTHRD_IO_NEXT_MATCHINGID(VTTHRD_MY_VTTHRD); \
564 vt_iobegin( VT_CURRENT_THREAD, &enter_time, matchingid ); \
565 } \
566 }
567
568 /** Write I/O end record
569 * The argument is a failure condition and decides whether VT_IOFLAG_IOFAILED is
570 * added in vt_ioend
571 */
572 #define VT_IOWRAP_LEAVE_IOFUNC(ERROR_CONDITION,FD) \
573 { \
574 int preserve_errno = errno; \
575 uint64_t time = vt_pform_wtime(); \
576 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_LEAVE_IOFUNC(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
577 if( was_recorded ) { \
578 uint32_t ioop = VT_IOWRAP_FUNCTYPE(VT_IOWRAP_THISFUNCNAME); \
579 uint32_t fid; \
580 uint64_t handle; \
581 if( FD == -1 ) { \
582 fid = invalid_fd_fid; \
583 handle = 0; \
584 } \
585 else { \
586 vampir_file_t* file; \
587 file = get_vampir_file( FD ); \
588 fid = file->vampir_file_id; \
589 handle = file->handle; \
590 } \
591 if( ERROR_CONDITION ) { \
592 ioop |= VT_IOFLAG_IOFAILED; \
593 } \
594 vt_debug_msg(DBG_VT_CALL, "vt_ioend(" stringify(VT_IOWRAP_THISFUNCNAME) "), stamp %llu", (unsigned long long)time); \
595 vt_ioend( VT_CURRENT_THREAD, &time, fid, matchingid, handle, ioop, (uint64_t)num_bytes ); \
596 } \
597 vt_exit( VT_CURRENT_THREAD, &time ); \
598 if( enable_memhooks ) VT_MEMHOOKS_ON(); \
599 errno = preserve_errno; \
600 }
601
602 /** Use custom values for fid and handle */
603 #define VT_IOWRAP_LEAVE_IOFUNC_CUSTOM(ERROR_CONDITION, FID, HANDLE) \
604 { \
605 int preserve_errno = errno; \
606 uint64_t time = vt_pform_wtime(); \
607 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_LEAVE_IOFUNC(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
608 if( was_recorded ) { \
609 uint32_t ioop = VT_IOWRAP_FUNCTYPE(VT_IOWRAP_THISFUNCNAME); \
610 if( ERROR_CONDITION ) { \
611 ioop |= VT_IOFLAG_IOFAILED; \
612 } \
613 vt_debug_msg(DBG_VT_CALL, "vt_ioend(" stringify(VT_IOWRAP_THISFUNCNAME) "), stamp %llu", (unsigned long long)time); \
614 vt_ioend( VT_CURRENT_THREAD, &time, FID, matchingid, HANDLE, ioop, (uint64_t)num_bytes ); \
615 } \
616 vt_exit( VT_CURRENT_THREAD, &time ); \
617 if( enable_memhooks ) VT_MEMHOOKS_ON(); \
618 errno = preserve_errno; \
619 }
620
621 /**
622 * If open fails, no fd is returned -> use handle=0 in vt_ioend().
623 * Always remember fd->vampir_file mapping if open succeeds.
624 */
625 #define VT_IOWRAP_LEAVE_IOFUNC_OPEN(ERROR_CONDITION,FD) \
626 { \
627 int preserve_errno = errno; \
628 uint64_t time = vt_pform_wtime(); \
629 uint32_t ioop = VT_IOWRAP_FUNCTYPE(VT_IOWRAP_THISFUNCNAME); \
630 uint32_t fid; \
631 vampir_file_t* file; \
632 uint64_t handle; \
633 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_LEAVE_IOFUNC_OPEN(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
634 if( ERROR_CONDITION ) { \
635 if( was_recorded ) { \
636 if( path && strlen(path) > 0 ) { \
637 fid = vt_iofile_id(path); \
638 } \
639 else { \
640 fid = invalid_fd_fid; \
641 } \
642 handle = 0; \
643 ioop |= VT_IOFLAG_IOFAILED; \
644 } \
645 } \
646 else { \
647 vt_iofile_open( path, FD ); \
648 if( was_recorded ) { \
649 file = get_vampir_file( FD ); \
650 fid = file->vampir_file_id; \
651 handle = file->handle; \
652 } \
653 } \
654 if( was_recorded ) { \
655 vt_debug_msg(DBG_VT_CALL, "vt_ioend(" stringify(VT_IOWRAP_THISFUNCNAME) "), stamp %llu", (unsigned long long)time); \
656 vt_ioend( VT_CURRENT_THREAD, &time, fid, matchingid, handle, ioop, 0 ); \
657 } \
658 vt_exit( VT_CURRENT_THREAD, &time ); \
659 if( enable_memhooks ) VT_MEMHOOKS_ON(); \
660 errno = preserve_errno; \
661 }
662
663 /**
664 * Handle is always from the fd that was dup'd
665 */
666 #define VT_IOWRAP_LEAVE_IOFUNC_DUP(ERROR_CONDITION,OLDFD,NEWFD) \
667 { \
668 int preserve_errno = errno; \
669 uint64_t time = vt_pform_wtime(); \
670 uint32_t ioop = VT_IOWRAP_FUNCTYPE(VT_IOWRAP_THISFUNCNAME); \
671 vampir_file_t* file; \
672 uint32_t fid; \
673 uint64_t handle; \
674 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_LEAVE_IOFUNC_DUP(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
675 file = get_vampir_file( OLDFD ); \
676 fid = file->vampir_file_id; \
677 handle = file->handle; \
678 if( ERROR_CONDITION ) { \
679 ioop |= VT_IOFLAG_IOFAILED; \
680 } \
681 else { \
682 vt_iofile_dupfd( OLDFD, NEWFD ); \
683 } \
684 if( was_recorded ) { \
685 vt_debug_msg(DBG_VT_CALL, "vt_ioend(" stringify(VT_IOWRAP_THISFUNCNAME) "), stamp %llu", (unsigned long long)time); \
686 vt_ioend( VT_CURRENT_THREAD, &time, fid, matchingid, handle, ioop, (uint64_t)num_bytes ); \
687 } \
688 vt_exit( VT_CURRENT_THREAD, &time ); \
689 if( enable_memhooks ) VT_MEMHOOKS_ON(); \
690 errno = preserve_errno; \
691 }
692
693 /* Used for I/O functions that work on paths instead of using fd's, e.g. unlink.
694 */
695 #define VT_IOWRAP_LEAVE_IOFUNC_PATH(ERROR_CONDITION,PATH) \
696 { \
697 int preserve_errno = errno; \
698 uint64_t time = vt_pform_wtime(); \
699 vt_debug_msg( DBG_INIT, "Macro VT_IOWRAP_LEAVE_IOFUNC_PATH(), Function " stringify(VT_IOWRAP_THISFUNCNAME) ); \
700 if( was_recorded ) { \
701 uint32_t ioop = VT_IOWRAP_FUNCTYPE(VT_IOWRAP_THISFUNCNAME); \
702 uint32_t fid; \
703 if( ERROR_CONDITION ) { \
704 if( PATH && strlen(PATH) > 0 ) { \
705 fid = vt_iofile_id(PATH); \
706 } \
707 else { \
708 fid = invalid_fd_fid; \
709 } \
710 ioop |= VT_IOFLAG_IOFAILED; \
711 } \
712 else { \
713 fid = vt_iofile_id(PATH); \
714 } \
715 vt_debug_msg(DBG_VT_CALL, "vt_ioend(" stringify(VT_IOWRAP_THISFUNCNAME) "), stamp %llu", (unsigned long long)time); \
716 vt_ioend( VT_CURRENT_THREAD, &time, fid, matchingid, 0, ioop, 0 ); \
717 } \
718 vt_exit( VT_CURRENT_THREAD, &time ); \
719 if( enable_memhooks ) VT_MEMHOOKS_ON(); \
720 errno = preserve_errno; \
721 }
722
723 #else /* VT_IOWRAP */
724
725 #define VT_ENABLE_IO_TRACING()
726 #define VT_DISABLE_IO_TRACING()
727 #define VT_SUSPEND_IO_TRACING(tid)
728 #define VT_RESUME_IO_TRACING(tid)
729
730 #define libc_fprintf fprintf
731 #define vt_iowrap_externals_init()
732
733 #endif
734
735 #endif /* _VT_IOWRAP_H_ */
736