trace.h
Go to the documentation of this file.
1 /** @file trace.h
2  * Contains all the userspace and kernel space macros for running
3  * TRACE. It also contains some of the data structures, and the
4  * userspace initialization routine.
5  */
6 
7 #ifndef __TRACE_H
8 #define __TRACE_H
9 
10 /* This file (trace.h) was created by Ron Rechenmacher <ron@fnal.gov> on
11  Dec 20, 1999. "TERMS AND CONDITIONS" governing this file are in the README
12  or COPYING file. If you do not have such a file, one can be obtained by
13  contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
14 */
15 #define __TRACE_H_REV "\
16 $RCSfile: trace.h,v $\
17 $Revision: 1.1.1.1 $\
18 $Date: 2009/10/09 20:03:00 $"
19 
20 #ifdef __KERNEL__
21 # include <linux/types.h> /* pid_t */
22 #else
23 # include <sys/types.h> /* pid_t, open */
24 # include <sys/stat.h> /* open */
25 # include <stdio.h> /* perror */
26 # include <fcntl.h> /* open */
27 # include <unistd.h> /* mmap */
28 # include <sys/mman.h> /* mmap */
29 # include <sys/ioctl.h> /* ioctl */
30 # include <string.h> /* strlen */
31 # ifdef __USE_POSIX
32 # include <time.h> /* localtime_r */
33 # else
34 # define __USE_POSIX
35 # include <time.h> /* localtime_r */
36 # undef __USE_POSIX
37 # endif
38 # include <sys/time.h> /* NESTED by time.h struct timeval */
39 # include <stdarg.h> /* varargs */
40 # include <stdio.h> /* printf */
41 # include <rms/util/trace_intr.h> /* *** THE APPROPRIATE trace_function! *** */
42 # include <stdlib.h> /* malloc */
43 # include <alloca.h> /* alloca */
44 #endif
45 
46 /**
47  * The TRACE macro
48  *
49  * The macro first checks to see if TRACE is installed on the system. This is
50  * accomplished by the TRACE_INIT_CHECK macro. If TRACE is in fact installed
51  * we move on and verify that logging with TRACE is enabled, and that logging
52  * as the appropriate level is enabled. If all that is true, we call the
53  * TRACE_FUNCTION. The TRACE macro will return the time at which it was called.
54  * If no TRACE took place, the time will be 0.
55  *
56  * @bug The TRACE_USER_FUNCTION macro should be taken out. The TRACE_FUNCTION
57  * macro should handle printing to all the TRACE functions.
58  *
59  * @param lvl The TRACE level
60  * @param msg The TRACE format message
61  * @param params Parameters for the TRACE format message
62  *
63  * @return The time that the macro was called if TRACE is setup on the system,
64  * 0 otherwise.
65  */
66 
67 #define TRACE( lvl, msg, params... ) \
68 ({ int lidx;\
69  struct timeval lclTime={0,0};/*an indication that no trace occurred*/\
70  /* first function activated sets the reference time */\
71  TRACE_INIT_CHECK;\
72  lidx = TRACE_TID * traceControl_sp->numberOfFunctions;\
73  if ((traceControl_sp->mode&(1<<0)) && (traceLevel_ip[lidx+0]&(1<<lvl)))\
74  { /* need to provide a way to return time (only when in user space\
75  though?maybe?) */\
76  TRACE_FUNCTION( &lclTime, TRACE_TID, lvl, msg , ## params );\
77  }\
78  TRACE_USER_FUNCTION( &lclTime, TRACE_TID, lvl, msg , ## params );\
79  lclTime;\
80 })
81 
82 /**
83  * The maximum number of TRACE message logging functions that can be
84  * used. The TRACE mode is a bitmask for enabling the different TRACE
85  * functions. Because the TRACE mode is an integer, we are limited
86  * to however many bit are in an integer.
87  */
88 #define TRACE_MAXIMUM_NUMBER_OF_FUNCTIONS (sizeof(int)*8)
89 
90 /**
91  * The default name for a TRACE source
92  */
93 # ifndef TRACE_NAME
94 # define TRACE_NAME ""
95 # endif
96 
97 /**
98  * Determine the difference in microseconds between two
99  * timeval structures.
100  *
101  * @param sooner The earlier timeval struct
102  * @param later The later timeval struct
103  *
104  * @return The difference in microseconds between the two
105  * timeval structures.
106  */
107 #define traceControl_TimeDiff( sooner, later ) \
108  ({ int secs, usecs;\
109  secs = later.tv_sec - sooner.tv_sec;\
110  usecs = later.tv_usec - sooner.tv_usec;\
111  ((secs*1000000) + usecs);\
112  })
113 
114 
115 #if __GNUC_MINOR__ == 96 || __GNUC__ == 3
116 # define TRACE_COMPILER_DOES_DYNAMIC_ARRAYS 0
117 #else
118 # define TRACE_COMPILER_DOES_DYNAMIC_ARRAYS 1
119 #endif
120 
121 /**
122  * The maximum number of integer parameters that can be passed
123  * to the TRACE macro.
124  */
125 #define TRACE_NUM_PARAMETER_INTS 6
126 
127 /**
128  * This structure groups information about the headings and spacing
129  * of elements as they are printed out of the TRACE circular buffer.
130  */
132 {
133  char *heading; /**< The heading, or field name */
134  int width; /**< The width of the field, in characters */
135  char type; /**< The field type, d for integer, L for long, and 0 for string */
136  int offset; /**< The place in the field that the least significant digit will be printed */
137 };
138 
139 /**
140  * Contains all the settings and pointers to all the relevant TRACE
141  * data structures.
142  */
144 {
145  char blockMarker[28]; /**< Filled with "beginning of trace control structure".
146  * Used to mark the beginning of the TRACE control data
147  * structure. */
148 
149  int numberOfTID; /**< The maximum number of TRACE IDs allowable */
150  int nameSize_bytes; /**< The maximum length of a TRACE ID's name, in bytes */
151  int numberOfFunctions; /**< The number of TRACE logging functions running */
152  int circularQueueSize_bytes; /**< The size of the TRACE circular queue in bytes,
153  * which is configurable at startup. */
154  int messageSize_bytes; /**< The maximum length of the TRACE format message */
155  int numberOfParameter_integers; /**< The maximum number of integer parameters
156  * that can be used with the TRACE message */
157 
158  struct s_tracePrint *print_sp; /**< A pointer to a data structure containing all
159  * the headings for printing the TRACE buffer */
160  int printAscending; /**< I don't know, this isn't used anywhere. */
161  int printHeading; /**< Determines whether or not the heading is printed when looking
162  * at the TRACE circular buffer. */
163  int mode; /**< The TRACE mode, a bit mask used to determine which TRACE functions
164  * are enabled. */
165  int initializationOK; /**< This is set to 0 until the trace_init() routine has completed. */
166 
167  int *initialLevel; /**< Pointer to an array of integers that contains the initial levels
168  * for all the TRACE functions. */
169 
170  char *name_a; /**< Pointer to an array of chars that has all the TRACE ID's names */
171 
172  int circularQueueEntrySize_bytes; /**< The size in bytes of an entry in the TRACE circular
173  * queue. This will changed depending on the size of the
174  * format string and the number of parameters. */
175  int circularQueueEntries; /**< The total number of entries that the circular queue can hold */
176  char *circularQueueFirst; /**< Pointer to the first byte of first entry */
177  char *circularQueueLast; /**< Pointer to the first byte of last entry */
178  char *circularQueueHead; /**< Pointer to the first byte of the entry that is the head of the queue. */
179  char *circularQueueTail; /**< Pointer to the first byte of the entry that is the tail of the queue. */
180  int circularQueueFull; /**< Shows whether or not the queue is full. */
181  int circularQueueEntriesUsed; /**< Keeps track of the number of entries that are in use in the queue. */
182 };
183 
184 /**
185  * Enumerations for the various things you can have TRACE do through the ioctl()
186  * interface.
187  */
198 };
199 
200 /**
201  * Used to pass information between user space and kernel space
202  * through the ioctl() mechanism.
203  */
205 { struct
206  { int num;
207  void *ptr;
208  int mask; /* mask will also contain cpuid for PMC Get/Read */
209  } generic;
210  struct
211  { unsigned long long pmc_data_val;
213  } pmc;
214 };
215 
216 #ifdef __KERNEL__
217 
218 # include <linux/time.h> /* do_gettimeofday */
219 # include <linux/version.h> /* LINUX_VERSION_CODE, KERNEL_VERSION */
220 # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
221 # include <asm/system.h>
222 # include <linux/trace_sys.h> /* traceCircularQueuePut, struct s_traceEntry */
223 # endif
224 extern struct s_traceControl *traceControl_sp;
225 extern int *traceLevel_ip;
226 extern int tracePMC[];
227 
228 struct s_traceEntry *
229 traceCircularQueuePut( int, ... );
230 
231 /**
232  * Inside the kernel, we don't need to run TRACE_INIT_CHECK because
233  * this is done at startup, and its not really possible to create
234  * messages before startup.
235  */
236 # define TRACE_INIT_CHECK
237 
238 /**
239  * The kernel TRACE ID is 0.
240  */
241 # define TRACE_TID 0
242 
243 /**
244  * Since we are in fact in kernel space, we don't have to trap or
245  * int to get to the TRACE function. We can simply call the
246  * appropriate functions right away.
247  *
248  * @param tv_adr Pointer to a timeval struct that will contain the
249  * time at which the TRACE was made.
250  * @param tid The TRACE ID, usually 0 in kernel space
251  * @param msg The TRACE format string
252  * @param params The integer parameters to the format string
253  */
254 # define TRACE_FUNCTION( tv_adr, tid, lvl, msg, params...) \
255  do\
256  { unsigned long __flags__;\
257  struct s_traceEntry *traceEntry_sp;\
258  local_save_flags( __flags__ );\
259  local_irq_disable();\
260  traceEntry_sp = traceCircularQueuePut( tid, lvl, msg , ## params );\
261  *tv_adr = traceEntry_sp->time;\
262  local_irq_restore( __flags__ );\
263  } while (0)
264 
265 
266 # ifndef TRACE_USER_FUNCTION
267 extern void (*(*trace_kernel_functions)[])( struct timeval*, int, int, char*, ... ); /* ptr to array of function ptrs */
268 
269 /**
270  * The TRACE_USER_FUNCTION macro is responsible for iterating through all the TRACE
271  * functions and calling them with the appropriate parameters.
272  *
273  * @bug Why do we check to see if TRACE is on and the message has an appropriate
274  * level in the TRACE macro _AND_ this macro?
275  *
276  * @param tv_adr Pointer to a timeval struct that will contain the
277  * time at which the TRACE was made.
278  * @param tid The TRACE ID, usually 0 in kernel space
279  * @param msg The TRACE format string
280  * @param params The integer parameters to the format string
281  */
282 # define TRACE_USER_FUNCTION( tv_adr, tid, lvl, msg, params... ) \
283  /* NOTE THE FUNCTION ARRAY IDX 0 LINES UP WITH MODE/LEVEL IDX 1 */\
284  do \
285  { int _ii_, lidx;\
286  lidx = TRACE_TID * traceControl_sp->numberOfFunctions;\
287  for (_ii_=1; _ii_<traceControl_sp->numberOfFunctions; _ii_++)\
288  { if ((traceControl_sp->mode&(1<<_ii_)) && (traceLevel_ip[lidx+_ii_]&(1<<lvl)))\
289  {\
290  if ((*trace_kernel_functions)[_ii_-1])\
291  { char _tmp_buf_[traceControl_sp->messageSize_bytes+4];\
292  int _jj_;\
293  if ((tv_adr)->tv_sec == 0) do_gettimeofday( tv_adr );\
294  for (_jj_=0; (_jj_<traceControl_sp->messageSize_bytes) && *((msg)+_jj_); _jj_++)\
295  { _tmp_buf_[_jj_] = *((msg)+_jj_);\
296  }\
297  _tmp_buf_[_jj_] = '\n'; _jj_++;\
298  _tmp_buf_[_jj_] = '\0';\
299  (*trace_kernel_functions)[_ii_-1]( tv_adr, tid, lvl, _tmp_buf_ , ## params );\
300  }\
301  }\
302  }\
303  } while (0)
304 # endif
305 
306 /**
307  * the traceControl_Mode() macro changes the TRACE mode. The
308  * mode is a bit mask that determines which TRACE functions are
309  * enabled.
310  *
311  * @param new_mode The new mode TRACE will be in.
312  *
313  * @return The mode TRACE was in.
314  */
315 #define traceControl_Mode( new_mode ) \
316  ({ int old_mode;\
317  old_mode = traceControl_sp->mode;\
318  traceControl_sp->mode = new_mode;\
319  old_mode;\
320  })
321 
322 /**
323  * Macro to get the current TRACE mode. The mode is a bit mask
324  * that determines which TRACE functions are enabled.
325  *
326  * @return The current TRACE mode
327  */
328 #define traceControl_ModeGet() \
329  ({ traceControl_sp->mode;\
330  })
331 
332 
333 #else /* USER SPACE -------------------------------------------------------*/
334 
335 /**
336  * Global pointer to the TRACE control structure.
337  */
338 static struct s_traceControl *traceControl_sp=0;
339 
340 /**
341  * Pointer to an array that contains the information
342  * about the levels for all the TRACE functions.
343  *
344  * @bug Why is this not in the traceControl data structure?
345  */
346 static int *traceLevel_ip;
347 
348 /**
349  * Global value to keep track of the TRACE ID of the current
350  * process.
351  */
352 static int traceTID=0;
353 
354 /**
355  * Check to see if the kernel has TRACE support, and if so
356  * map the traceControl data strcture into our address space
357  * so we can do stuff with it.
358  */
359 # define TRACE_INIT_CHECK do\
360  { if (!traceControl_sp)traceControl_Init("");\
361  } while (0)
362 
363 /**
364  * The numerical TRACE ID. This is procured from the TRACE_NAME.
365  */
366 # define TRACE_TID traceTID
367 
368 /**
369  * The TRACE_FUNCTION sets the appropriate registers and then
370  * jumps into kernel space. There is a seperate TRACE_FUNCTION
371  * for each architecture that TRACE supports.
372  *
373  * @param tv_adr Pointer to a timeval struct that will contain the
374  * time at which the TRACE was made.
375  * @param tid The TRACE ID, usually 0 in kernel space
376  * @param msg The TRACE format string
377  * @param params The integer parameters to the format string
378  */
379 # define TRACE_FUNCTION( tv_adr, tid, lvl, msg, params... ) \
380  trace_function( tv_adr, tid\
381  ,lvl, msg , ## params )
382 
383 #ifndef TRACE_FUNCTIONS
384 /**
385  * An array of function pointers to the various userspace TRACE
386  * functions. They can be used as follows:
387  *
388  * extern void trace_print( struct timeval, int, int, char*, ...);
389  * #define TRACE_FUNCTIONS {trace_print}
390  * #define TRACE_NAME "simple"
391  */
392 #define TRACE_FUNCTIONS {0,0,trace_printf}
393 
394 /**
395  * A user space TRACE print function. This one prints TRACE messages
396  * using printf.
397  *
398  * @param tv_adr Pointer to a timeval struct that will contain the
399  * time at which the TRACE was made.
400  * @param tid The TRACE ID, usually 0 in kernel space
401  * @param msg The TRACE format string
402  * @param params The integer parameters to the format string
403  */
404 
405 static void trace_printf( struct timeval *tv_sp, int tid, int lvl, char *msg, ... )
406 { va_list ap;
407  char timbuf[100];
408  int timlen;
409  char *newbuf;
410  struct tm tm_s;
411 
412  localtime_r( (time_t *)&tv_sp->tv_sec, &tm_s );
413  timlen = strftime( timbuf, sizeof(timbuf), "%a %H:%M:%S", &tm_s );
414 
415  sprintf( &timbuf[timlen], ".%06d: ", (int)tv_sp->tv_usec );
416  newbuf = (char *)alloca( timlen+strlen(&timbuf[timlen])+strlen(msg)+2/*room for "\n\0"*/ );
417 
418  /* now accomplish the prepending of the time and the appending of the newline */
419  sprintf( newbuf, "%s%s\n", timbuf, msg );
420 
421  va_start( ap, msg );
422  vprintf( newbuf, ap );
423  va_end( ap );
424 
425  return;
426 }
427 
428 # endif
429 # ifndef TRACE_USER_FUNCTION
430 typedef void (*func_ptr_t)(struct timeval*,int,int,char*,...);
432 
433 /**
434  * The TRACE_USER_FUNCTION macro loops through all the user space
435  * TRACE functions and executes them.
436  *
437  * @param tv_adr Pointer to a timeval struct that will contain the
438  * time at which the TRACE was made.
439  * @param tid The TRACE ID, usually 0 in kernel space
440  * @param msg The TRACE format string
441  * @param params The integer parameters to the format string
442  */
443 
444 # define TRACE_USER_FUNCTION( tv_adr, tid, lvl, msg, params... ) \
445  /* NOTE THE FUNCTION ARRAY IDX 0 LINES UP WITH MODE/LEVEL IDX 1 */\
446  do \
447  { int _ii_, lidx;\
448  lidx = TRACE_TID * traceControl_sp->numberOfFunctions;\
449  for (_ii_=1; _ii_<traceControl_sp->numberOfFunctions; _ii_++)\
450  { if ((traceControl_sp->mode&(1<<_ii_)) && (traceLevel_ip[lidx+_ii_]&(1<<lvl)))\
451  { if (trace_user_functions[_ii_-1])\
452  { if ((tv_adr)->tv_sec == 0) gettimeofday( tv_adr, 0 );\
453  trace_user_functions[_ii_-1](tv_adr,tid,lvl, msg , ## params );\
454  }\
455  }\
456  }\
457  } while (0)
458 # endif
459 
460 /**
461  * traceControl_fd is point at /proc/trace/control and is used when
462  * making ioctl() calls for TRACE.
463  */
464 static int traceControl_fd=0;
465 
466 /**
467  * This is the level mask that is used if TRACE is disabled.
468  *
469  * @bug Should this be 4, or should it be the number of TRACE
470  * functions?
471  */
472 static int disabled_level[4]={0};
473 
474 /**
475  * This is a copy of the control structure that has been disabled
476  * and is used when there is no TRACE support in the kernel.
477  */
478 static struct s_traceControl disabled_control={{0}};
479 
480 /**
481  * Called if there is TRACE support in the kernel, this function
482  * will initialize the traceControl_sp data structures.
483  *
484  * @param name The TRACE name that will be used for all logging.
485  */
486 static int traceControl_Init( char *name )
487 {
488  int fd_map;
489  int levelArraySize;
490  int levelOffset;
491  int sts;
492  union u_traceIoctl ioctl_data;
493 
494  /* This should assure we do init processing once. Use ReInit to
495  change name.
496  Note: first call may return -1 while successive calls will
497  return 0. */
498  if (traceControl_sp) return (0);
499 
500  /* incase anything bad happens... */
501  traceTID = 0;
502  traceControl_sp = &disabled_control;
503  traceLevel_ip = disabled_level;
504  traceControl_sp->numberOfFunctions = ( sizeof(disabled_level)
505  /sizeof(disabled_level[0]));
506 
507  traceControl_fd = open( "/proc/trace/control", O_RDONLY );
508  if (traceControl_fd == -1)
509  { perror( "open /proc/trace/control" );
510  fprintf( stderr, "continueing with disabled tracing\n" );
511  return (-1);
512  }
513 
514  /* get a traceTID via ioctl */
515  if (name[0] == '\0')
516  { /* try TRACE_NAME (which may actually be the same thing [""] */
517  name = TRACE_NAME;
518  }
519  ioctl_data.generic.ptr = name;
520  sts = ioctl( traceControl_fd, traceIoctl_e_init, &ioctl_data );
521  traceTID = ioctl_data.generic.num;
522 
523 
524  fd_map = open( "/proc/trace/map", O_RDONLY );
525  if (fd_map == -1)
526  { perror( "open /proc/trace/map" );
527  fprintf( stderr, "continueing with disabled tracing\n" );
528  traceTID = 0;
529  traceControl_fd = -1;
530  traceControl_sp = &disabled_control;
531  traceLevel_ip = disabled_level;
532  traceControl_sp->numberOfFunctions = ( sizeof(disabled_level)
533  /sizeof(disabled_level[0]));
534  return (-1);
535  }
536 
537  traceControl_sp = (struct s_traceControl *)mmap( 0 /* hint address */
538  , sizeof(struct s_traceControl)
539  , PROT_READ
540  , MAP_SHARED
541  , fd_map
542  , 0 /* offset */ );
543  if (traceControl_sp == (void *)-1/*MAP_FAILED*/)
544  { perror( "mmap /proc/trace/map" );
545  fprintf( stderr, "continueing with disabled tracing\n" );
546  traceTID = 0;
547  traceControl_fd = -1;
548  traceControl_sp = &disabled_control;
549  traceLevel_ip = disabled_level;
550  traceControl_sp->numberOfFunctions = ( sizeof(disabled_level)
551  /sizeof(disabled_level[0]));
552  return (-1);
553  }
554 
555  levelArraySize = ( traceControl_sp->numberOfTID
556  *traceControl_sp->numberOfFunctions);
557 
558  /* NEED TO REORGANIZE STRUCTURE TO REMOVE HARD CODED NUMBER
559  ref. trace_proc.c:trace_proc_map_mmap() */
560  levelOffset = 4096;
561 
562  traceLevel_ip = (int *)mmap( 0 /* hint address */
563  , levelArraySize * sizeof(int)
564  , PROT_READ
565  , MAP_SHARED
566  , fd_map
567  , levelOffset );
568 
569  if (traceLevel_ip == (void *)-1/*MAP_FAILED*/)
570  { perror( "mmap level" );
571  fprintf( stderr, "continueing with disabled tracing\n" );
572  traceTID = 0;
573  traceControl_fd = -1;
574  traceControl_sp = &disabled_control;
575  traceLevel_ip = disabled_level;
576  traceControl_sp->numberOfFunctions = ( sizeof(disabled_level)
577  /sizeof(disabled_level[0]));
578  return (-1);
579  }
580 
581  /* skip past initial
582  NOTE: it does not work to add this to the offset as mmap page
583  aligns the returned pointer */
584  traceLevel_ip += traceControl_sp->numberOfFunctions;
585 
586  close( fd_map );
587 
588  return (0);
589 } /* traceControl_Init */
590 
591 /**
592  * Get a new TRACE ID and name for a process. This can be useful
593  * for forked processes that want a different name.
594  *
595  * @param name The new TRACE name
596  */
597 #define traceControl_ReInit( name ) \
598  ({ int __sts__=0;\
599  if (!traceControl_sp)\
600  { traceControl_Init("");\
601  }\
602  else if (traceControl_fd > 0)\
603  { /* get a traceTID via ioctl */\
604  union u_traceIoctl ioctl_data;\
605  ioctl_data.generic.ptr = name;\
606  __sts__ = ioctl( traceControl_fd, traceIoctl_e_init, &ioctl_data );\
607  traceTID = ioctl_data.generic.num;\
608  }\
609  __sts__;\
610  })
611 
612 /**
613  * Set the TRACE mode. Currently, there are two modes. Mode "0"
614  * is TRACE turned off, while mode "1" is TRACE turned on.
615  *
616  * @param new_mode The mode that TRACE will switch to.
617  */
618 #define traceControl_Mode( new_mode ) \
619  ({ int old_mode;\
620  if (!traceControl_sp) traceControl_Init("");\
621  old_mode = traceControl_sp->mode;\
622  if (traceControl_fd > 0)\
623  { ioctl( traceControl_fd, traceIoctl_e_modeSet, new_mode );\
624  }\
625  old_mode;\
626  })
627 
628 /**
629  * Get the current TRACE mode.
630  *
631  * @return The current TRACE mode.
632  */
633 #define traceControl_ModeGet() \
634  ({ if (!traceControl_sp) traceControl_Init("");\
635  traceControl_sp->mode;\
636  })
637 
638 /**
639  * Apply a mask (bitwise OR) to the TRACE mode.
640  *
641  * @param mask The mask that will be ORed with the TRACE mode.
642  */
643 #define traceControl_ModeSet( mask ) \
644  ({ int old_mode, new_mode;\
645  if (!traceControl_sp) traceControl_Init("");\
646  old_mode = traceControl_sp->mode;\
647  new_mode = old_mode | mask;\
648  if (traceControl_fd > 0)\
649  { ioctl( traceControl_fd, traceIoctl_e_modeSet, new_mode );\
650  }\
651  else\
652  { traceControl_sp->mode = new_mode;\
653  }\
654  old_mode;\
655  })
656 
657 /**
658  * Apply a mask (bitwise AND) to the TRACE mode.
659  *
660  * @param mask The mask that will be ANDed to the TRACE mode.
661  */
662 #define traceControl_ModeClr( mask ) \
663  ({ int old_mode, new_mode;\
664  if (!traceControl_sp) traceControl_Init("");\
665  old_mode = traceControl_sp->mode;\
666  new_mode = old_mode & ~mask;\
667  if (traceControl_fd > 0)\
668  { ioctl( traceControl_fd, traceIoctl_e_modeSet, new_mode );\
669  }\
670  else\
671  { traceControl_sp->mode = new_mode;\
672  }\
673  old_mode;\
674  })
675 
676 /**
677  * Reset TRACE, which clears the TRACE circular buffer.
678  */
679 #define traceControl_Reset() \
680  ({ if (!traceControl_sp) traceControl_Init("");\
681  if (traceControl_fd > 0)\
682  { ioctl( traceControl_fd, traceIoctl_e_reset, 0 );\
683  }\
684  })
685 
686 /**
687  * Get the data from the Performance Monitoring Counter on a specific
688  * CPU.
689  *
690  * @param which Which CPU to get the data from
691  * @return The value from the PMC on the specific CPU.
692  */
693 #define traceControl_PMCGet( which ) \
694  ({ union u_traceIoctl ioctl_data;\
695  if (!traceControl_sp) traceControl_Init("");\
696  if (traceControl_fd > 0)\
697  { ioctl_data.pmc.whichIn_cpuidOut = which;\
698  ioctl( traceControl_fd, traceIoctl_e_PMCGet, &ioctl_data );\
699  }\
700  ioctl_data.pmc.pmc_data_val;\
701  })
702 
703 /**
704  * Practically the same as traceControl_PMCGet, except that
705  * this will place the cpuID in the area pointed to by
706  * cpuidOut_ptr.
707  *
708  * @bug I really don't know what this will do.
709  *
710  * @param which The processor to retreive PMC data from
711  * @param cpuidOut_ptr A pointer to an int where the processes ID will be stored.
712  */
713 #define traceControl_PMCRead( which, cpuidOut_ptr ) \
714  ({ union u_traceIoctl ioctl_data;\
715  if (!traceControl_sp) traceControl_Init("");\
716  if (traceControl_fd > 0)\
717  { ioctl_data.pmc.whichIn_cpuidOut = which;\
718  ioctl( traceControl_fd, traceIoctl_e_PMCGet, &ioctl_data );\
719  }\
720  *(cpuidOut_ptr) = ioctl_data.pmc.whichIn_cpuidOut;\
721  ioctl_data.pmc.pmc_data_val;\
722  })
723 
724 /**
725  * Set the TRACE level for the current TRACE ID for a particular
726  * TRACE function.
727  *
728  * @bug Does this really want the function number?
729  * @bug __mask__ isn't a very good name.
730  *
731  * @param func The index of the function who's level we want to set
732  * @param __mask__ The new level mask.
733  */
734 #define traceControl_LevelSet( func, __mask__ ) \
735  ({ union u_traceIoctl ioctl_data;\
736  if (!traceControl_sp) traceControl_Init("");\
737  if (traceControl_fd > 0)\
738  { ioctl_data.generic.num = traceTID;\
739  ioctl_data.generic.ptr = (void*)func;\
740  ioctl_data.generic.mask = __mask__;\
741  ioctl( traceControl_fd, traceIoctl_e_levelSet, &ioctl_data );\
742  }\
743  else if (func < (sizeof(disabled_level)/sizeof(int)))\
744  { traceLevel_ip[func] = __mask__;\
745  }\
746  })
747 
748 /**
749  * Get the current TRACE level for a specific TRACE function.
750  *
751  * @param func The index of the function who's level we want to get.
752  * @return The TRACE level for the TRACE function with index func.
753  */
754 #define traceControl_LevelGet( func ) \
755  ({ int lidx;\
756  if (!traceControl_sp) traceControl_Init("");\
757  lidx = TRACE_TID * traceControl_sp->numberOfFunctions;\
758  traceLevel_ip[lidx+func];\
759  })
760 
761 
762 #endif /* of #else for ifdef __KERNEL__ */
763 /*----------------------------------------------------------------------------*/
764 
765 #endif /* __TRACE_H */
const XML_Char * name
Definition: expat.h:151
struct s_tracePrint * print_sp
Definition: trace.h:158
static int * traceLevel_ip
Definition: trace.h:346
e_traceIoctl
Definition: trace.h:188
int messageSize_bytes
Definition: trace.h:154
static int disabled_level[4]
Definition: trace.h:472
int numberOfFunctions
Definition: trace.h:151
char * circularQueueHead
Definition: trace.h:178
int width
Definition: trace.h:134
static void trace_printf(struct timeval *tv_sp, int tid, int lvl, char *msg,...)
Definition: trace.h:405
static int traceControl_Init(char *name)
Definition: trace.h:486
int num
Definition: trace.h:206
int circularQueueEntries
Definition: trace.h:175
char * heading
Definition: trace.h:133
#define TRACE_NAME
Definition: trace.h:94
int numberOfTID
Definition: trace.h:149
int nameSize_bytes
Definition: trace.h:150
void * ptr
Definition: trace.h:207
void(* func_ptr_t)(struct timeval *, int, int, char *,...)
Definition: trace.h:430
char type
Definition: trace.h:135
int circularQueueEntriesUsed
Definition: trace.h:181
int circularQueueSize_bytes
Definition: trace.h:152
int whichIn_cpuidOut
Definition: trace.h:212
int offset
Definition: trace.h:136
procfile open("FD_BRL_v0.txt")
static struct s_traceControl disabled_control
Definition: trace.h:478
int numberOfParameter_integers
Definition: trace.h:155
struct u_traceIoctl::@35 generic
static int traceControl_fd
Definition: trace.h:464
int circularQueueFull
Definition: trace.h:180
int mask
Definition: trace.h:208
static struct s_traceControl * traceControl_sp
Definition: trace.h:338
char * name_a
Definition: trace.h:170
int printHeading
Definition: trace.h:161
static int traceTID
Definition: trace.h:352
int printAscending
Definition: trace.h:160
unsigned long long pmc_data_val
Definition: trace.h:211
char * circularQueueTail
Definition: trace.h:179
char * circularQueueFirst
Definition: trace.h:176
#define TRACE_FUNCTIONS
Definition: trace.h:392
int circularQueueEntrySize_bytes
Definition: trace.h:172
typedef void(XMLCALL *XML_ElementDeclHandler)(void *userData
int initializationOK
Definition: trace.h:165
int * initialLevel
Definition: trace.h:167
char * circularQueueLast
Definition: trace.h:177
static func_ptr_t trace_user_functions[]
Definition: trace.h:431
procfile close()