1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
|
/*
* EventDB.h
*
* Copyright (C) 1999 Karim Yaghmour.
*
* This is distributed under GPL.
*
* Header for event database engine for trace toolkit.
*
* History :
* K.Y., 26/06/99, Initial typing.
*/
#ifndef __TRACE_TOOLKIT_EVENT_DB__
#define __TRACE_TOOLKIT_EVENT_DB__
#include <stdio.h>
#include <LinuxEvents.h>
#include <RTAIEvents.h>
#include <EventOptions.h>
/* Definitions */
#define EVENT_STRING_MAX_SIZE 256
#define HEADER_BANER "####################################################################\n"
#define HEADER_CPUID "CPU-ID"
#define HEADER_EVENT "Event\t\t"
#define HEADER_TIME "\tTime\t\t"
#define HEADER_PID "\tPID"
#define HEADER_LENGTH "\tLength"
#define HEADER_STRING "\tDescription"
/* Length of time representing strings */
#define TIME_STR_LEN 80
/* Maximum number of interrupts possible */
#define MAX_NB_INTERRUPTS 64
/* Trace processing errors */
#define ERR_UNKNOWN_TRACE_TYPE -1 /* Trace type not recognized */
#define ERR_EMPTY_TRACE -2 /* Trace doesn't contain any events */
/******************************************************************
* Macro :
* PrintData()
* Description :
* Prints out the given data in the given format to the given file.
* Parameters :
* pmFile, File to which we write.
* pmFormat, Format of the data.
* pmArg, The data to be printed
* History :
* K.Y., 17/10/99, Initial typing
******************************************************************/
#define DBPrintData(pmFile, pmFormat, pmArg...) \
do \
{\
char lWriteString[100];\
\
sprintf(lWriteString, pmFormat, ##pmArg);\
write(pmFile, lWriteString, strlen(lWriteString));\
} while(0)
/* Time operation macros */
/* (T3 = T2 - T1) */
#define DBTimeSub(T3, T2, T1) \
do \
{\
T3.tv_sec = T2.tv_sec - T1.tv_sec; \
T3.tv_usec = T2.tv_usec - T1.tv_usec; \
if(T3.tv_usec < 0)\
{\
T3.tv_sec--;\
T3.tv_usec += 1000000;\
}\
} while(0)
/* (T3 = T2 + T1) */
#define DBTimeAdd(T3, T2, T1) \
do \
{\
T3.tv_sec = T2.tv_sec + T1.tv_sec; \
T3.tv_usec = T2.tv_usec + T1.tv_usec; \
if(T3.tv_usec >= 1000000)\
{\
T3.tv_sec += T3.tv_usec / 1000000;\
T3.tv_usec = T3.tv_usec % 1000000;\
}\
} while(0)
/* Get the time in the double format */
#define DBGetTimeInDouble(X) (double) (((double)X.tv_sec)*1000000 + (double)X.tv_usec)
/* Events are equal */
#define DBEventsEqual(X, Y) ((X.BufID == Y.BufID) && (X.EventPos == Y.EventPos))
#define DBIEventGetBufStart(pmDB, pmEvent) \
(pmEvent->BufID * pmDB->BufferSize + pmDB->TraceStart)
#define DBIEventGetPosition(pmDB, pmEvent) \
(DBIEventGetBufStart(pmDB, pmEvent) + pmEvent->EventPos)
/* Event structure */
typedef struct _event
{
uint32_t BufID; /* Buffer ID of the buffer to which this event belongs */
uint32_t EventPos; /* Event position in the buffer */
} event;
typedef struct _eventDescription
{
/* Characteristics as read from raw trace */
int ID; /* The ID number of the event as given in linux/include/linux/profile.h */
struct timeval Time; /* Time at which event occured */
int CPUID; /* CPU on which this event occured */
void* Struct; /* Structured describing the event */
char String[EVENT_STRING_MAX_SIZE]; /* String describing the event */
int Size; /* Size of entry describing event (as was recorded in kernel trace module) */
} eventDescription;
/* Custom event description */
typedef struct _customEventDesc
{
/* The event itself */
uint32_t ID;
trace_new_event Event; /* The "event creation" event containing the custom event description */
/* List links */
struct _customEventDesc* Next;
struct _customEventDesc* Prev;
/* Hash links */
struct _customEventDesc* NextHash;
} customEventDesc;
/* Size of custom event hash table */
#define CUSTOM_EVENT_HASH_TABLE_SIZE 256
/* Event database */
typedef struct _db
{
int ByteRev; /* Byte-reverse trace data */
void* TraceStart; /* Address at which the raw trace starts */
off_t TraceSize; /* Size of the trace */
uint32_t BufferSize; /* Size of buffers */
trace_event_mask EventMask; /* The event mask */
trace_event_mask DetailsMask; /* Are the event details logged */
uint8_t LogCPUID; /* Is the CPUID logged */
uint32_t ArchType; /* Architecture on which trace was generated */
uint32_t ArchVariant; /* Variant of the given architecture */
uint32_t SystemType; /* System on which trace was generated */
uint8_t MajorVersion; /* Major version number of trace format */
uint8_t MinorVersion; /* Minor version number of trace format */
unsigned long int Nb; /* Number of events */
event FirstEvent; /* First event in database */
event LastEvent; /* Last event in event list */
struct timeval StartTime; /* Time at which trace started */
struct timeval EndTime; /* Time at which trace ended */
int SchedEventsExist; /* There is at least one scheduling change in the trace */
event FirstEventWithProc; /* First event that belongs to a process */
struct timeval DrawStartTime; /* Time at which we should start drawing */
/* Custom event information */
unsigned long int NbCustom; /* Number of custom events */
customEventDesc CustomEvents; /* Circular list of custom events */
customEventDesc CustomHashTable[CUSTOM_EVENT_HASH_TABLE_SIZE]; /* Hash table of custom event descriptions */
/* Information needed to understand trace */
int MaxEventID; /* Maximum event ID */
char** EventOT; /* Event Omit/Trace table */
/* Functions */
int (*EventStructSize) (); /* Event structure size function */
char* (*EventString) (); /* Event string function */
char* (*SyscallString) (); /* Syscall string function */
char* (*TrapString) (); /* Trap string function */
} db;
/* Syscall tracking structure */
typedef struct _syscallInfo
{
int ID; /* The ID number of the system call */
int Nb; /* Number of times system call was called */
int Depth; /* Depth of system call */
struct timeval Time; /* Total amount of time passed in system call */
struct _syscallInfo* Next; /* Next system call */
} syscallInfo;
/* Structure type */
#define LINUX_PROCESS_OBJECT 0 /* type = "struct _process" */
/* Process description */
typedef struct _process
{
/* DO NOT MOVE THIS FROM THE BEGINING OF THE STRUCT */
/* Structure type */
int Type; /* Type of structure */
/* Graphic properties of process */
int ListPos; /* Position of process in process list */
/* Properties */
int PID; /* PID of process */
int PPID; /* PID of parent */
char* Command; /* Command given to start process */
int NbSyscalls; /* Number of system calls that occured */
int NbTraps; /* Number of traps that occured */
int QFileRead; /* Quantity of data read by process to files */
int QFileWrite; /* Quantity of data written by process to files */
struct timeval TimeOfBirth; /* Time at which process was created */
struct timeval TimeProcCode; /* Time during which we were executing process code */
struct timeval TimeRuning; /* Time during which this process had the control over the CPU */
struct timeval TimeIO; /* Time spent waiting for I/O */
/* Temporary data used during graph construction */
struct timeval ReportedSwitchTime; /* Time of occurence of last task switch with this task in */
/* Variables used during analysis */
int Depth; /* Current syscall depth */
syscallInfo* Pending; /* Syscalls not completely analyzed yet */
int CtrlDepth; /* Depth in control events */
event LastIOEvent; /* Last I/O event */
event LastSchedIn; /* Last time the task was scheduled in */
/* Related structures */
syscallInfo* Syscalls; /* Process specific syscall analysis */
struct _systemInfo* System; /* System to which this process belongs */
/* List hooks */
struct _process* Next; /* Next process in list */
struct _process* Children; /* Pointer to first child */
struct _process* NextChild; /* Next child in child list */
struct _process* NextHash; /* Next process in hash table entry */
/* Generic hook */
void* Hook; /* Data hook into process structure */
} process;
typedef uint8_t proc_hash;
#define PROC_HASH_SIZE 256
/* System database */
typedef struct _systemInfo
{
/* Statistics */
/* Core events */
unsigned long int SyscallEntry; /* Number of system call entries */
unsigned long int SyscallExit; /* Number of system call exits */
unsigned long int TrapEntry; /* Number of trap entries */
unsigned long int TrapExit; /* Number of trap exits */
unsigned long int IRQEntry; /* Number of interrupt entries */
unsigned long int IRQExit; /* Number of interrupt exits */
unsigned long int SchedChange; /* Number of scheduler changes */
unsigned long int KernelTimer; /* Number of times the kernel timer has been called */
unsigned long int BH; /* Number of bottom-halves that occured */
/* Extend events set */
unsigned long int TimerExpire; /* Number of timer expiries */
unsigned long int PageAlloc; /* Number of page allocations */
unsigned long int PageFree; /* Number of page frees */
unsigned long int PacketOut; /* Number of outgoing packets */
unsigned long int PacketIn; /* Number of incoming packets */
/* Lists of system components */
char* Interrupts[MAX_NB_INTERRUPTS]; /* Interrupt descriptions */
process* Processes; /* All the processes seen during trace */
process* ProcTree; /* The process tree */
process ProcHash[PROC_HASH_SIZE]; /* Hash table containing pointer to the processes */
syscallInfo* Syscalls; /* System-wide syscall analysis */
/* Trace type system specific data */
void* SystemSpec;
} systemInfo;
/* The trace manipulating functions */
uint8_t DBEventID
(db* /* The database to which the event belongs */,
event* /* The event for which the ID is sought */);
void DBEventTime
(db* /* The database to which the event belongs */,
event* /* The event for which the time is sought */,
struct timeval* /* Pointer to the timeval structure to be filled */);
uint8_t DBEventCPUID
(db* /* The database to which the event belongs */,
event* /* The event for which the CPUID is sought */);
void* DBEventStruct
(db* /* The database to which the event belongs */,
event* /* The event for which the describing structure is sought */);
int DBEventString
(db* /* The database to which the event belongs */,
event* /* The event for which the size is sought */,
char* /* Pointer to the buffer to be filled with the description of the event */,
int /* The size of the buffer */);
uint16_t DBEventSize
(db* /* The database to which the event belongs */,
event* /* The event for which the size is sought */);
int DBEventControlEntry
(db* /* The database to which the event belongs */,
event* /* The event that is being tested for being a control event */,
int /* The PID of the process to which this event belongs */);
int DBEventControlExit
(db* /* The database to which the event belongs */,
event* /* The event that is being tested for being a control event */,
int /* The PID of the process to which this event belongs */);
int DBEventControl
(db* /* The database to which the event belongs */,
event* /* The event that is being tested for being a control event */,
systemInfo* /* The system to which this event belongs */);
customEventDesc*
DBEventGetCustomDescription
(db* /* The database to which the event belongs */,
event* /* The event who's custom formatting data is looked for */);
char* DBEventGetFormat
(db* /* The database to which the event belongs */,
event* /* The event who's custom formatting data is looked for */,
int* /* Pointer to int where to store the format type */);
char* DBEventGetFormatByCustomID
(db* /* The database to which the events belongs */,
int /* The custom event ID who's custom formatting data is looked for */,
int* /* Pointer to int where to store the format type */);
char* DBEventGetFormatByCustomType
(db* /* The database to which the events belongs */,
char* /* The custom event type string who's custom formatting data is looked for */,
int* /* Pointer to int where to store the format type */);
int DBEventSetFormat
(db* /* The database to which the events belongs */,
event* /* The event who's custom formatting data is to be set */,
int /* The format type being set */,
char* /* Custom event formatting string to be set */);
int DBEventSetFormatByCustomID
(db* /* The database to which the events belongs */,
int /* The custom event ID who's custom formatting data is to be set */,
int /* The format type being set */,
char* /* Custom event formatting string to be set */);
int DBEventSetFormatByCustomType
(db* /* The database to which the events belongs */,
char* /* The custom event type string who's custom formatting data is to be set */,
int /* The format type being set */,
char* /* Custom event formatting string to be set */);
process* DBEventProcess
(db* /* The database to which the event belongs */,
event* /* The event for which the parent process is sought */,
systemInfo* /* The system to which this event belongs */,
int /* Should the time of occurence of the corresponding sched-change be remembered */);
void DBEventDescription
(db* /* The database to which the event belongs */,
event* /* The event for which the description is sought */,
int /* Boolean to indicate whether the description string is necessary */,
eventDescription* /* Pointer to an eventDescription structure to be filled */);
int DBEventNext
(db* /* The database to which the event belongs */,
event* /* The event for which the next event is sought */);
int DBEventPrev
(db* /* The database to which the event belongs */,
event* /* The event for which the previous event is sought */);
int DBReadTrace
(int /* File from which data is to be read */,
db* /* Database to be filled */);
void DBProcessProcInfo
(FILE* /* File containing proc info */,
systemInfo* /* System description to be filled */);
void DBBuildProcTree
(systemInfo* /* System for which proc tree is to be built */);
void DBBuildProcHash
(systemInfo* /* System for which proc hash is to be built */);
process* DBGetProcByPID
(int /* PID of process to find */,
systemInfo* /* System in which process is to be found */);
process* DBFindProcInTree
(int /* PID of process to find */,
process* /* Process tree in which to search */);
int DBProcessTrace
(systemInfo* /* System to be processed */,
db* /* Database of events */,
options* /* The processing options */);
void DBFormatTimeInReadableString
(char* /* Pointer to buffer where formatted string is to be outputed */,
long /* Number of seconds */,
long /* Number of micro-seconds */);
void DBPrintHeader
(int /* File to which data is to be printed */,
db* /* Database of events */,
options* /* Options */);
void DBPrintTrace
(int /* File to which data is to be printed */,
systemInfo* /* System who's information is to be printed */,
db* /* Database of events */,
options* /* Options */);
process* DBCreateProcess
(systemInfo* /* The system to which the process belongs */,
int /* The PID of the created process */,
int /* The PID of the parent process */);
db* DBCreateDB
(void);
systemInfo* DBCreateSystem
(void);
void DBDestroyTrace
(systemInfo* /* The system to be destroyed */,
db* /* The event database to be destroyed */);
#endif /* __TRACE_TOOLKIT_EVENT_DB__ */
|