git-svn-id: http://ltt.polymtl.ca/svn@151 04897980-b3bd-0310-b5e0-8ef037075253
[lttv.git] / ltt / branches / poly / ltt / tracefile.c
CommitLineData
6cd62ccf 1#include <stdio.h>
2#include <fcntl.h>
3#include <sys/stat.h>
4#include <sys/types.h>
963b5f2d 5#include <dirent.h>
6cd62ccf 6#include <linux/errno.h>
7
fcdf0ec2 8#include <ltt/LTTTypes.h>
6cd62ccf 9#include "parser.h"
963b5f2d 10#include <ltt/trace.h>
6cd62ccf 11
963b5f2d 12#define DIR_NAME_SIZE 256
6cd62ccf 13
14/* set the offset of the fields belonging to the event,
15 need the information of the archecture */
40331ba8 16void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace *t);
6cd62ccf 17
18/* get the size of the field type according to the archtecture's
19 size and endian type(info of the archecture) */
40331ba8 20int getFieldtypeSize(LttTracefile * tf, LttEventType * evT, int offsetRoot,
21 int offsetParent, LttField *fld, void *evD, LttTrace* t);
6cd62ccf 22
23/* read a fixed size or a block information from the file (fd) */
24int readFile(int fd, void * buf, size_t size, char * mesg);
963b5f2d 25int readBlock(LttTracefile * tf, int whichBlock);
6cd62ccf 26
27/* calculate cycles per nsec for current block */
963b5f2d 28void getCyclePerNsec(LttTracefile * t);
6cd62ccf 29
30/* reinitialize the info of the block which is already in the buffer */
963b5f2d 31void updateTracefile(LttTracefile * tf);
6cd62ccf 32
33/* go to the next event */
963b5f2d 34int skipEvent(LttTracefile * t);
6cd62ccf 35
963b5f2d 36/* compare two time (LttTime), 0:t1=t2, -1:t1<t2, 1:t1>t2 */
37int timecmp(LttTime * t1, LttTime * t2);
6cd62ccf 38
39/* get an integer number */
40int getIntNumber(int size1, void *evD);
41
42
6cd62ccf 43
44/*****************************************************************************
45 *Function name
963b5f2d 46 * ltt_tracefile_open : open a trace file, construct a LttTracefile
6cd62ccf 47 *Input params
963b5f2d 48 * t : the trace containing the tracefile
49 * fileName : path name of the trace file
6cd62ccf 50 *Return value
963b5f2d 51 * : a pointer to a tracefile
6cd62ccf 52 ****************************************************************************/
53
963b5f2d 54LttTracefile* ltt_tracefile_open(LttTrace * t, char * fileName)
6cd62ccf 55{
963b5f2d 56 LttTracefile * tf;
57 struct stat lTDFStat; /* Trace data file status */
58 BlockStart a_block_start;
6cd62ccf 59
963b5f2d 60 tf = g_new(LttTracefile, 1);
6cd62ccf 61
62 //open the file
963b5f2d 63 tf->name = g_strdup(fileName);
64 tf->trace = t;
6cd62ccf 65 tf->fd = open(fileName, O_RDONLY, 0);
66 if(tf->fd < 0){
67 g_error("Unable to open input data file %s\n", fileName);
68 }
69
70 // Get the file's status
71 if(fstat(tf->fd, &lTDFStat) < 0){
72 g_error("Unable to get the status of the input data file %s\n", fileName);
73 }
74
75 // Is the file large enough to contain a trace
963b5f2d 76 if(lTDFStat.st_size < sizeof(BlockStart) + EVENT_HEADER_SIZE){
8710c6c7 77 g_print("The input data file %s does not contain a trace\n", fileName);
663bd9ff 78 g_free(tf->name);
79 close(tf->fd);
80 g_free(tf);
8710c6c7 81 return NULL;
6cd62ccf 82 }
83
84 //store the size of the file
85 tf->file_size = lTDFStat.st_size;
963b5f2d 86 tf->block_size = t->system_description->ltt_block_size;
87 tf->block_number = tf->file_size / tf->block_size;
88 tf->which_block = 0;
6cd62ccf 89
90 //allocate memory to contain the info of a block
963b5f2d 91 tf->buffer = (void *) g_new(char, t->system_description->ltt_block_size);
6cd62ccf 92
963b5f2d 93 //read the first block
94 if(readBlock(tf,1)) exit(1);
6cd62ccf 95
96 return tf;
97}
98
6cd62ccf 99
100/*****************************************************************************
963b5f2d 101 *Open control and per cpu tracefiles
6cd62ccf 102 ****************************************************************************/
103
963b5f2d 104void ltt_tracefile_open_cpu(LttTrace *t, char * tracefile_name)
6cd62ccf 105{
963b5f2d 106 LttTracefile * tf;
107 tf = ltt_tracefile_open(t,tracefile_name);
4a6c8e36 108 if(!tf) return;
963b5f2d 109 t->per_cpu_tracefile_number++;
110 g_ptr_array_add(t->per_cpu_tracefiles, tf);
6cd62ccf 111}
112
963b5f2d 113void ltt_tracefile_open_control(LttTrace *t, char * control_name)
6cd62ccf 114{
963b5f2d 115 LttTracefile * tf;
116 LttEvent * ev;
117 LttFacility * f;
118 uint16_t evId;
119 void * pos;
120 FacilityLoad fLoad;
121 int i;
122
123 tf = ltt_tracefile_open(t,control_name);
8710c6c7 124 if(!tf) return;
963b5f2d 125 t->control_tracefile_number++;
126 g_ptr_array_add(t->control_tracefiles,tf);
127
128 //parse facilities tracefile to get base_id
542ceddd 129 if(strcmp(&control_name[strlen(control_name)-10],"facilities") ==0){
963b5f2d 130 while(1){
40331ba8 131 ev = ltt_tracefile_read(tf);
132 if(!ev)return; // end of file
133
134 if(ev->event_id == TRACE_FACILITY_LOAD){
135 pos = ev->data;
963b5f2d 136 fLoad.name = (char*)pos;
47a166fc 137 fLoad.checksum = *(LttChecksum*)(pos + strlen(fLoad.name));
138 fLoad.base_code = *(uint32_t*)(pos + strlen(fLoad.name) + sizeof(LttChecksum));
963b5f2d 139
140 for(i=0;i<t->facility_number;i++){
141 f = (LttFacility*)g_ptr_array_index(t->facilities,i);
142 if(strcmp(f->name,fLoad.name)==0 && fLoad.checksum==f->checksum){
143 f->base_id = fLoad.base_code;
144 break;
145 }
146 }
147 if(i==t->facility_number)
148 g_error("Facility: %s, checksum: %d is not founded\n",
149 fLoad.name,fLoad.checksum);
40331ba8 150 }else if(ev->event_id == TRACE_BLOCK_START){
151 continue;
152 }else if(ev->event_id == TRACE_BLOCK_END){
153 break;
963b5f2d 154 }else g_error("Not valid facilities trace file\n");
62e55dd6 155 g_free(ev);
963b5f2d 156 }
157 }
6cd62ccf 158}
159
160/*****************************************************************************
161 *Function name
963b5f2d 162 * ltt_tracefile_close: close a trace file,
6cd62ccf 163 *Input params
963b5f2d 164 * t : tracefile which will be closed
6cd62ccf 165 ****************************************************************************/
166
963b5f2d 167void ltt_tracefile_close(LttTracefile *t)
6cd62ccf 168{
963b5f2d 169 g_free(t->name);
170 g_free(t->buffer);
663bd9ff 171 close(t->fd);
963b5f2d 172 g_free(t);
173}
6cd62ccf 174
6cd62ccf 175
963b5f2d 176/*****************************************************************************
177 *Get system information
178 ****************************************************************************/
179void getSystemInfo(LttSystemDescription* des, char * pathname)
180{
181 FILE * fp;
182 int i;
183 int entry_number = 15;
184 char buf[DIR_NAME_SIZE];
185 char description[4*DIR_NAME_SIZE];
186 char * ptr;
187
188 fp = fopen(pathname,"r");
189 if(!fp){
190 g_error("Can not open file : %s\n", pathname);
6cd62ccf 191 }
963b5f2d 192
193 while(fgets(buf,DIR_NAME_SIZE, fp)!= NULL){
194 ptr = buf;
195 while(isspace(*ptr)) ptr++;
196 if(strlen(ptr) == 0) continue;
197 break;
6cd62ccf 198 }
199
963b5f2d 200 if(strlen(ptr) == 0) g_error("Not a valid file: %s\n", pathname);
201 if(strncmp("<system",ptr,7) !=0)g_error("Not a valid file: %s\n", pathname);
202
203 for(i=0;i<entry_number;i++){
204 if(fgets(buf,DIR_NAME_SIZE, fp)== NULL)
205 g_error("Not a valid file: %s\n", pathname);
8710c6c7 206 buf[strlen(buf)-1] = '\0';
963b5f2d 207 ptr = buf;
208 while(isspace(*ptr)) ptr++;
209 switch(i){
210 case 0:
211 if(strncmp("node_name=",ptr,10)!=0)
212 g_error("Not a valid file: %s\n", pathname);
213 des->node_name = g_strdup(ptr+10);
214 break;
215 case 1:
216 if(strncmp("domainname=",ptr,11)!=0)
217 g_error("Not a valid file: %s\n", pathname);
218 des->domain_name = g_strdup(ptr+11);
219 break;
220 case 2:
221 if(strncmp("cpu=",ptr,4)!=0)
222 g_error("Not a valid file: %s\n", pathname);
223 des->nb_cpu = (unsigned)atoi(ptr+4);
224 break;
225 case 3:
226 if(strncmp("arch_size=",ptr,10)!=0)
227 g_error("Not a valid file: %s\n", pathname);
228 if(strcmp(ptr+10,"\"LP32\"") == 0) des->size = LTT_LP32;
229 else if(strcmp(ptr+10,"\"ILP32\"") == 0) des->size = LTT_ILP32;
230 else if(strcmp(ptr+10,"\"LP64\"") == 0) des->size = LTT_LP64;
231 else if(strcmp(ptr+10,"\"ILP64\"") == 0) des->size = LTT_ILP64;
232 else if(strcmp(ptr+10,"\"UNKNOWN\"") == 0) des->size = LTT_UNKNOWN;
233 break;
234 case 4:
235 if(strncmp("endian=",ptr,7)!=0)
236 g_error("Not a valid file: %s\n", pathname);
237 if(strcmp(ptr+7,"\"LITTLE_ENDIAN\"") == 0)
238 des->endian = LTT_LITTLE_ENDIAN;
239 else if(strcmp(ptr+7,"\"BIG_ENDIAN\"") == 0)
240 des->endian = LTT_BIG_ENDIAN;
241 break;
242 case 5:
243 if(strncmp("kernel_name=",ptr,12)!=0)
244 g_error("Not a valid file: %s\n", pathname);
245 des->kernel_name = g_strdup(ptr+12);
246 break;
247 case 6:
248 if(strncmp("kernel_release=",ptr,15)!=0)
249 g_error("Not a valid file: %s\n", pathname);
250 des->kernel_release = g_strdup(ptr+15);
251 break;
252 case 7:
253 if(strncmp("kernel_version=",ptr,15)!=0)
254 g_error("Not a valid file: %s\n", pathname);
255 des->kernel_version = g_strdup(ptr+15);
256 break;
257 case 8:
258 if(strncmp("machine=",ptr,8)!=0)
259 g_error("Not a valid file: %s\n", pathname);
260 des->machine = g_strdup(ptr+8);
261 break;
262 case 9:
263 if(strncmp("processor=",ptr,10)!=0)
264 g_error("Not a valid file: %s\n", pathname);
265 des->processor = g_strdup(ptr+10);
266 break;
267 case 10:
268 if(strncmp("hardware_platform=",ptr,18)!=0)
269 g_error("Not a valid file: %s\n", pathname);
270 des->hardware_platform = g_strdup(ptr+18);
271 break;
272 case 11:
273 if(strncmp("operating_system=",ptr,17)!=0)
274 g_error("Not a valid file: %s\n", pathname);
275 des->operating_system = g_strdup(ptr+17);
276 break;
277 case 12:
278 if(strncmp("ltt_major_version=",ptr,18)!=0)
279 g_error("Not a valid file: %s\n", pathname);
280 ptr += 18;
8710c6c7 281 // ptr++;//skip begining "
282 // ptr[strlen(ptr)-1] = '\0'; //get rid of the ending "
963b5f2d 283 des->ltt_major_version = (unsigned)atoi(ptr);
284 break;
285 case 13:
286 if(strncmp("ltt_minor_version=",ptr,18)!=0)
287 g_error("Not a valid file: %s\n", pathname);
288 ptr += 18;
8710c6c7 289 // ptr++;//skip begining "
290 // ptr[strlen(ptr)-1] = '\0'; //get rid of the ending "
963b5f2d 291 des->ltt_minor_version = (unsigned)atoi(ptr);
292 break;
293 case 14:
294 if(strncmp("ltt_block_size=",ptr,15)!=0)
295 g_error("Not a valid file: %s\n", pathname);
296 ptr += 15;
8710c6c7 297 // ptr++;//skip begining "
298 // ptr[strlen(ptr)-1] = '\0'; //get rid of the ending "
963b5f2d 299 des->ltt_block_size = (unsigned)atoi(ptr);
300 break;
301 default:
302 g_error("Not a valid file: %s\n", pathname);
303 }
6cd62ccf 304 }
305
963b5f2d 306 //get description
307 description[0] = '\0';
308 if(fgets(buf,DIR_NAME_SIZE, fp)== NULL)
309 g_error("Not a valid file: %s\n", pathname);
310 ptr = buf;
311 while(isspace(*ptr)) ptr++;
312 if(*ptr != '>') g_error("Not a valid file: %s\n", pathname);
313 while((ptr=fgets(buf,DIR_NAME_SIZE, fp))!= NULL){
314 ptr = buf;
315 while(isspace(*ptr)) ptr++;
316 if(strncmp("</system>",ptr,9) == 0 )break;
317 strcat(description, buf);
318 }
319 if(!ptr)g_error("Not a valid file: %s\n", pathname);
320 if(description[0] = '\0')des->description = NULL;
321 des->description = g_strdup(description);
6cd62ccf 322
963b5f2d 323 fclose(fp);
6cd62ccf 324}
325
326/*****************************************************************************
963b5f2d 327 *The following functions get facility/tracefile information
6cd62ccf 328 ****************************************************************************/
329
963b5f2d 330void getFacilityInfo(LttTrace *t, char* eventdefs)
6cd62ccf 331{
963b5f2d 332 DIR * dir;
333 struct dirent *entry;
334 char * ptr;
335 int i,j;
336 LttFacility * f;
337 LttEventType * et;
e8bb1a73 338 char name[DIR_NAME_SIZE];
963b5f2d 339
340 dir = opendir(eventdefs);
341 if(!dir) g_error("Can not open directory: %s\n", eventdefs);
342
343 while((entry = readdir(dir)) != NULL){
344 ptr = &entry->d_name[strlen(entry->d_name)-4];
345 if(strcmp(ptr,".xml") != 0) continue;
e8bb1a73 346 strcpy(name,eventdefs);
347 strcat(name,entry->d_name);
348 ltt_facility_open(t,name);
963b5f2d 349 }
350 closedir(dir);
351
963b5f2d 352 for(j=0;j<t->facility_number;j++){
8710c6c7 353 f = (LttFacility*)g_ptr_array_index(t->facilities, j);
963b5f2d 354 for(i=0; i<f->event_number; i++){
355 et = f->events[i];
40331ba8 356 setFieldsOffset(NULL, et, NULL, t);
963b5f2d 357 }
358 }
359}
6cd62ccf 360
963b5f2d 361void getControlFileInfo(LttTrace *t, char* control)
6cd62ccf 362{
963b5f2d 363 DIR * dir;
364 struct dirent *entry;
e8bb1a73 365 char name[DIR_NAME_SIZE];
963b5f2d 366
367 dir = opendir(control);
368 if(!dir) g_error("Can not open directory: %s\n", control);
369
370 while((entry = readdir(dir)) != NULL){
8710c6c7 371 if(strcmp(entry->d_name,"facilities") != 0 &&
372 strcmp(entry->d_name,"interrupts") != 0 &&
963b5f2d 373 strcmp(entry->d_name,"processes") != 0) continue;
374
e8bb1a73 375 strcpy(name,control);
376 strcat(name,entry->d_name);
377 ltt_tracefile_open_control(t,name);
963b5f2d 378 }
379 closedir(dir);
6cd62ccf 380}
381
963b5f2d 382void getCpuFileInfo(LttTrace *t, char* cpu)
6cd62ccf 383{
963b5f2d 384 DIR * dir;
385 struct dirent *entry;
e8bb1a73 386 char name[DIR_NAME_SIZE];
963b5f2d 387
388 dir = opendir(cpu);
389 if(!dir) g_error("Can not open directory: %s\n", cpu);
390
391 while((entry = readdir(dir)) != NULL){
8710c6c7 392 if(strcmp(entry->d_name,".") != 0 &&
963b5f2d 393 strcmp(entry->d_name,"..") != 0 ){
e8bb1a73 394 strcpy(name,cpu);
395 strcat(name,entry->d_name);
396 ltt_tracefile_open_cpu(t,name);
963b5f2d 397 }else continue;
398 }
399 closedir(dir);
6cd62ccf 400}
401
963b5f2d 402/*****************************************************************************
403 *A trace is specified as a pathname to the directory containing all the
404 *associated data (control tracefiles, per cpu tracefiles, event
405 *descriptions...).
406 *
407 *When a trace is closed, all the associated facilities, types and fields
408 *are released as well.
409 ****************************************************************************/
6cd62ccf 410
963b5f2d 411LttTrace *ltt_trace_open(char *pathname)
6cd62ccf 412{
963b5f2d 413 LttTrace * t;
414 LttSystemDescription * sys_description;
415 char eventdefs[DIR_NAME_SIZE];
416 char info[DIR_NAME_SIZE];
417 char control[DIR_NAME_SIZE];
418 char cpu[DIR_NAME_SIZE];
419 char tmp[DIR_NAME_SIZE];
420 gboolean has_slash = FALSE;
421
422 //establish the pathname to different directories
423 if(pathname[strlen(pathname)-1] == '/')has_slash = TRUE;
424 strcpy(eventdefs,pathname);
425 if(!has_slash)strcat(eventdefs,"/");
426 strcat(eventdefs,"eventdefs/");
427
428 strcpy(info,pathname);
429 if(!has_slash)strcat(info,"/");
430 strcat(info,"info/");
431
432 strcpy(control,pathname);
433 if(!has_slash)strcat(control,"/");
434 strcat(control,"control/");
435
436 strcpy(cpu,pathname);
437 if(!has_slash)strcat(cpu,"/");
438 strcat(cpu,"cpu/");
439
440 //new trace
441 t = g_new(LttTrace, 1);
442 sys_description = g_new(LttSystemDescription, 1);
443 t->pathname = g_strdup(pathname);
444 t->facility_number = 0;
445 t->control_tracefile_number = 0;
446 t->per_cpu_tracefile_number = 0;
447 t->system_description = sys_description;
448 t->control_tracefiles = g_ptr_array_new();
449 t->per_cpu_tracefiles = g_ptr_array_new();
450 t->facilities = g_ptr_array_new();
451 getDataEndianType(&(t->my_arch_size), &(t->my_arch_endian));
452
453 //get system description
454 strcpy(tmp,info);
455 strcat(tmp,"system.xml");
456 getSystemInfo(sys_description, tmp);
457
b333a76b 458 //get facilities info
459 getFacilityInfo(t,eventdefs);
460
963b5f2d 461 //get control tracefile info
462 getControlFileInfo(t,control);
463
464 //get cpu tracefile info
465 getCpuFileInfo(t,cpu);
466
963b5f2d 467 return t;
6cd62ccf 468}
469
963b5f2d 470void ltt_trace_close(LttTrace *t)
6cd62ccf 471{
963b5f2d 472 int i;
473 LttTracefile * tf;
474 LttFacility * f;
475
476 g_free(t->pathname);
477
478 //free system_description
479 g_free(t->system_description->description);
480 g_free(t->system_description->node_name);
481 g_free(t->system_description->domain_name);
482 g_free(t->system_description->kernel_name);
483 g_free(t->system_description->kernel_release);
484 g_free(t->system_description->kernel_version);
485 g_free(t->system_description->machine);
486 g_free(t->system_description->processor);
487 g_free(t->system_description->hardware_platform);
488 g_free(t->system_description->operating_system);
489 g_free(t->system_description);
490
491 //free control_tracefiles
492 for(i=0;i<t->control_tracefile_number;i++){
493 tf = (LttTracefile*)g_ptr_array_index(t->control_tracefiles,i);
494 ltt_tracefile_close(tf);
495 }
09ad4797 496 g_ptr_array_free(t->control_tracefiles, TRUE);
963b5f2d 497
498 //free per_cpu_tracefiles
499 for(i=0;i<t->per_cpu_tracefile_number;i++){
500 tf = (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles,i);
501 ltt_tracefile_close(tf);
502 }
09ad4797 503 g_ptr_array_free(t->per_cpu_tracefiles, TRUE);
963b5f2d 504
505 //free facilities
506 for(i=0;i<t->facility_number;i++){
507 f = (LttFacility*)g_ptr_array_index(t->facilities,i);
508 ltt_facility_close(f);
509 }
09ad4797 510 g_ptr_array_free(t->facilities, TRUE);
963b5f2d 511
512 g_free(t);
09ad4797 513
514 g_blow_chunks();
6cd62ccf 515}
516
963b5f2d 517
6cd62ccf 518/*****************************************************************************
963b5f2d 519 *Get the system description of the trace
6cd62ccf 520 ****************************************************************************/
521
963b5f2d 522LttSystemDescription *ltt_trace_system_description(LttTrace *t)
6cd62ccf 523{
963b5f2d 524 return t->system_description;
6cd62ccf 525}
526
527/*****************************************************************************
963b5f2d 528 * The following functions discover the facilities of the trace
6cd62ccf 529 ****************************************************************************/
530
963b5f2d 531unsigned ltt_trace_facility_number(LttTrace *t)
532{
533 return (unsigned)(t->facility_number);
534}
535
536LttFacility *ltt_trace_facility_get(LttTrace *t, unsigned i)
6cd62ccf 537{
963b5f2d 538 return (LttFacility*)g_ptr_array_index(t->facilities, i);
6cd62ccf 539}
540
541/*****************************************************************************
542 *Function name
963b5f2d 543 * ltt_trace_facility_find : find facilities in the trace
6cd62ccf 544 *Input params
963b5f2d 545 * t : the trace
546 * name : facility name
547 *Output params
548 * position : position of the facility in the trace
6cd62ccf 549 *Return value
963b5f2d 550 * : the number of facilities
6cd62ccf 551 ****************************************************************************/
552
963b5f2d 553unsigned ltt_trace_facility_find(LttTrace *t, char *name, unsigned *position)
6cd62ccf 554{
963b5f2d 555 int i, count=0;
556 LttFacility * f;
557 for(i=0;i=t->facility_number;i++){
558 f = (LttFacility*)g_ptr_array_index(t->facilities, i);
559 if(strcmp(f->name,name)==0){
560 count++;
561 if(count==1) *position = i;
562 }else{
563 if(count) break;
564 }
565 }
566 return count;
6cd62ccf 567}
568
569/*****************************************************************************
963b5f2d 570 * Functions to discover all the event types in the trace
6cd62ccf 571 ****************************************************************************/
572
963b5f2d 573unsigned ltt_trace_eventtype_number(LttTrace *t)
6cd62ccf 574{
963b5f2d 575 int i;
576 unsigned count = 0;
577 LttFacility * f;
578 for(i=0;i=t->facility_number;i++){
579 f = (LttFacility*)g_ptr_array_index(t->facilities, i);
580 count += f->event_number;
581 }
582 return count;
6cd62ccf 583}
584
963b5f2d 585LttFacility * ltt_trace_facility_by_id(LttTrace * trace, unsigned id)
6cd62ccf 586{
963b5f2d 587 LttFacility * facility;
588 int i;
589 for(i=0;i<trace->facility_number;i++){
590 facility = (LttFacility*) g_ptr_array_index(trace->facilities,i);
591 if(id >= facility->base_id &&
592 id < facility->base_id + facility->event_number)
593 break;
594 }
595 if(i==trace->facility_number) return NULL;
596 else return facility;
6cd62ccf 597}
598
963b5f2d 599LttEventType *ltt_trace_eventtype_get(LttTrace *t, unsigned evId)
6cd62ccf 600{
963b5f2d 601 LttFacility * f;
602 f = ltt_trace_facility_by_id(t,evId);
603 if(!f) return NULL;
604 return f->events[evId - f->base_id];
6cd62ccf 605}
606
607/*****************************************************************************
963b5f2d 608 *There is one "per cpu" tracefile for each CPU, numbered from 0 to
609 *the maximum number of CPU in the system. When the number of CPU installed
610 *is less than the maximum, some positions are unused. There are also a
611 *number of "control" tracefiles (facilities, interrupts...).
6cd62ccf 612 ****************************************************************************/
963b5f2d 613unsigned ltt_trace_control_tracefile_number(LttTrace *t)
6cd62ccf 614{
963b5f2d 615 return t->control_tracefile_number;
6cd62ccf 616}
617
963b5f2d 618unsigned ltt_trace_per_cpu_tracefile_number(LttTrace *t)
6cd62ccf 619{
963b5f2d 620 return t->per_cpu_tracefile_number;
6cd62ccf 621}
622
623/*****************************************************************************
963b5f2d 624 *It is possible to search for the tracefiles by name or by CPU position.
625 *The index within the tracefiles of the same type is returned if found
626 *and a negative value otherwise.
6cd62ccf 627 ****************************************************************************/
628
963b5f2d 629int ltt_trace_control_tracefile_find(LttTrace *t, char *name)
6cd62ccf 630{
963b5f2d 631 LttTracefile * tracefile;
632 int i;
633 for(i=0;i<t->control_tracefile_number;i++){
634 tracefile = (LttTracefile*)g_ptr_array_index(t->control_tracefiles, i);
635 if(strcmp(tracefile->name, name)==0)break;
636 }
637 if(i == t->control_tracefile_number) return -1;
638 return i;
6cd62ccf 639}
640
963b5f2d 641int ltt_trace_per_cpu_tracefile_find(LttTrace *t, unsigned i)
6cd62ccf 642{
963b5f2d 643 LttTracefile * tracefile;
644 int j, name;
645 for(j=0;j<t->per_cpu_tracefile_number;j++){
646 tracefile = (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles, j);
647 name = atoi(tracefile->name);
648 if(name == (int)i)break;
649 }
650 if(j == t->per_cpu_tracefile_number) return -1;
651 return j;
6cd62ccf 652}
653
654/*****************************************************************************
963b5f2d 655 *Get a specific tracefile
6cd62ccf 656 ****************************************************************************/
657
963b5f2d 658LttTracefile *ltt_trace_control_tracefile_get(LttTrace *t, unsigned i)
6cd62ccf 659{
963b5f2d 660 return (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles, i);
661}
662
663LttTracefile *ltt_trace_per_cpu_tracefile_get(LttTrace *t, unsigned i)
664{
665 return (LttTracefile*)g_ptr_array_index(t->per_cpu_tracefiles, i);
6cd62ccf 666}
667
668/*****************************************************************************
963b5f2d 669 *Get the name of a tracefile
6cd62ccf 670 ****************************************************************************/
671
963b5f2d 672char *ltt_tracefile_name(LttTracefile *tf)
6cd62ccf 673{
963b5f2d 674 return tf->name;
6cd62ccf 675}
676
677/*****************************************************************************
678 *Function name
679 * ltt_tracefile_seek_time: seek to the first event of the trace with time
680 * larger or equal to time
681 *Input params
682 * t : tracefile
683 * time : criteria of the time
6cd62ccf 684 ****************************************************************************/
685
963b5f2d 686void ltt_tracefile_seek_time(LttTracefile *t, LttTime time)
6cd62ccf 687{
688 int err;
963b5f2d 689 LttTime lttTime;
690 int headTime = timecmp(&(t->a_block_start->time), &time);
691 int tailTime = timecmp(&(t->a_block_end->time), &time);
62e55dd6 692 LttEvent * ev;
693
6cd62ccf 694 if(headTime < 0 && tailTime > 0){
695 lttTime = getEventTime(t);
696 err = timecmp(&lttTime, &time);
963b5f2d 697 if(err > 0){
40331ba8 698 if(t->which_event==2 || timecmp(&t->prev_event_time,&time)<0){
963b5f2d 699 return;
700 }else{
6cd62ccf 701 updateTracefile(t);
702 return ltt_tracefile_seek_time(t, time);
703 }
704 }else if(err < 0){
1a3b8cbd 705 while(1){
706 ev = ltt_tracefile_read(t);
707 if(ev == NULL){
708 g_print("End of file\n");
709 return;
710 }
711 g_free(ev);
712 lttTime = getEventTime(t);
713 err = timecmp(&lttTime, &time);
714 if(err >= 0)return;
963b5f2d 715 }
963b5f2d 716 }else return;
6cd62ccf 717 }else if(headTime > 0){
718 if(t->which_block == 1){
719 updateTracefile(t);
720 }else{
40331ba8 721 if(timecmp(&(t->prev_block_end_time),&time) >= 0 ){
6cd62ccf 722 err=readBlock(t,t->which_block-1);
963b5f2d 723 if(err) g_error("Can not read tracefile: %s\n", t->name);
6cd62ccf 724 return ltt_tracefile_seek_time(t, time) ;
725 }else{
726 updateTracefile(t);
727 }
728 }
40331ba8 729 }else if(tailTime < 0){
6cd62ccf 730 if(t->which_block != t->block_number){
731 err=readBlock(t,t->which_block+1);
963b5f2d 732 if(err) g_error("Can not read tracefile: %s\n", t->name);
733 }else {
25975c93 734 g_print("End of file\n");
963b5f2d 735 return;
736 }
6cd62ccf 737 if(tailTime < 0) return ltt_tracefile_seek_time(t, time);
738 }else if(headTime == 0){
739 updateTracefile(t);
40331ba8 740 }else if(tailTime == 0){
1a3b8cbd 741 t->cur_event_pos = t->a_block_end - EVENT_HEADER_SIZE;
62e55dd6 742 t->current_event_time = time;
743 t->cur_heart_beat_number = 0;
744 t->prev_event_time.tv_sec = 0;
745 t->prev_event_time.tv_nsec = 0;
40331ba8 746 return;
6cd62ccf 747 }
6cd62ccf 748}
749
750/*****************************************************************************
751 *Function name
40331ba8 752 * ltt_tracefile_read : read the current event, set the pointer to the next
6cd62ccf 753 *Input params
754 * t : tracefile
755 *Return value
963b5f2d 756 * LttEvent * : an event to be processed
6cd62ccf 757 ****************************************************************************/
758
963b5f2d 759LttEvent *ltt_tracefile_read(LttTracefile *t)
6cd62ccf 760{
963b5f2d 761 LttEvent * lttEvent = (LttEvent *)g_new(LttEvent, 1);
762 int err;
6cd62ccf 763
963b5f2d 764 lttEvent->event_id = (int)(*(uint16_t *)(t->cur_event_pos));
765 if(lttEvent->event_id == TRACE_TIME_HEARTBEAT)
766 t->cur_heart_beat_number++;
6cd62ccf 767
40331ba8 768 t->prev_event_time = t->current_event_time;
62e55dd6 769 // t->current_event_time = getEventTime(t);
6cd62ccf 770
963b5f2d 771 lttEvent->time_delta = *(uint32_t*)(t->cur_event_pos + EVENT_ID_SIZE);
772 lttEvent->event_time = t->current_event_time;
773
774 lttEvent->event_cycle_count = ((uint64_t)1)<<32 * t->cur_heart_beat_number
775 + lttEvent->time_delta;
776
6cd62ccf 777 lttEvent->tracefile = t;
778 lttEvent->data = t->cur_event_pos + EVENT_HEADER_SIZE;
779
40331ba8 780 //update the fields of the current event and go to the next event
781 err = skipEvent(t);
663bd9ff 782 if(err == ENOMEM){
783 g_free(lttEvent);
784 return NULL;
785 }
99ff36b1 786 if(err == ENOENT) return lttEvent;
40331ba8 787 if(err == ERANGE) g_error("event id is out of range\n");
788 if(err)g_error("Can not read tracefile\n");
789
6cd62ccf 790 return lttEvent;
791}
792
793/****************************************************************************
794 *Function name
795 * readFile : wrap function to read from a file
796 *Input Params
797 * fd : file descriptor
798 * buf : buf to contain the content
799 * size : number of bytes to be read
800 * mesg : message to be printed if some thing goes wrong
801 *return value
802 * 0 : success
803 * EIO : can not read from the file
804 ****************************************************************************/
805
806int readFile(int fd, void * buf, size_t size, char * mesg)
807{
808 ssize_t nbBytes;
809 nbBytes = read(fd, buf, size);
810 if(nbBytes != size){
811 printf("%s\n",mesg);
812 return EIO;
813 }
814 return 0;
815}
816
817/****************************************************************************
818 *Function name
819 * readBlock : read a block from the file
820 *Input Params
821 * lttdes : ltt trace file
822 * whichBlock : the block which will be read
823 *return value
824 * 0 : success
825 * EINVAL : lseek fail
826 * EIO : can not read from the file
827 ****************************************************************************/
828
963b5f2d 829int readBlock(LttTracefile * tf, int whichBlock)
6cd62ccf 830{
831 off_t nbBytes;
832 uint32_t lostSize;
833
834 if(whichBlock - tf->which_block == 1 && tf->which_block != 0){
963b5f2d 835 tf->prev_block_end_time = tf->a_block_end->time;
40331ba8 836 tf->prev_event_time = tf->a_block_end->time;
6cd62ccf 837 }else{
838 tf->prev_block_end_time.tv_sec = 0;
839 tf->prev_block_end_time.tv_nsec = 0;
40331ba8 840 tf->prev_event_time.tv_sec = 0;
841 tf->prev_event_time.tv_nsec = 0;
6cd62ccf 842 }
6cd62ccf 843
963b5f2d 844 nbBytes=lseek(tf->fd,(off_t)((whichBlock-1)*tf->block_size), SEEK_SET);
6cd62ccf 845 if(nbBytes == -1) return EINVAL;
846
963b5f2d 847 if(readFile(tf->fd,tf->buffer,tf->block_size,"Unable to read a block"))
848 return EIO;
6cd62ccf 849
963b5f2d 850 tf->a_block_start=(BlockStart *) (tf->buffer + EVENT_HEADER_SIZE);
851 lostSize = *(uint32_t*)(tf->buffer + tf->block_size - sizeof(uint32_t));
852 tf->a_block_end=(BlockEnd *)(tf->buffer + tf->block_size -
853 lostSize + EVENT_HEADER_SIZE);
6cd62ccf 854
6cd62ccf 855 tf->which_block = whichBlock;
963b5f2d 856 tf->which_event = 1;
40331ba8 857 tf->cur_event_pos = tf->buffer;//the beginning of the block, block start ev
6cd62ccf 858 tf->cur_heart_beat_number = 0;
963b5f2d 859
6cd62ccf 860 getCyclePerNsec(tf);
861
62e55dd6 862 tf->current_event_time = getEventTime(tf);
40331ba8 863
6cd62ccf 864 return 0;
865}
866
867/*****************************************************************************
868 *Function name
869 * updateTracefile : reinitialize the info of the block which is already
870 * in the buffer
871 *Input params
872 * tf : tracefile
873 ****************************************************************************/
874
963b5f2d 875void updateTracefile(LttTracefile * tf)
6cd62ccf 876{
963b5f2d 877 tf->which_event = 1;
40331ba8 878 tf->cur_event_pos = tf->buffer;
62e55dd6 879 tf->current_event_time = getEventTime(tf);
6cd62ccf 880 tf->cur_heart_beat_number = 0;
881
882 tf->prev_event_time.tv_sec = 0;
883 tf->prev_event_time.tv_nsec = 0;
884}
885
886/*****************************************************************************
887 *Function name
888 * skipEvent : go to the next event, update the fields of the current event
889 *Input params
890 * t : tracefile
891 *return value
892 * 0 : success
893 * EINVAL : lseek fail
894 * EIO : can not read from the file
99ff36b1 895 * ENOMEM : end of file
896 * ENOENT : last event
6cd62ccf 897 * ERANGE : event id is out of range
898 ****************************************************************************/
899
963b5f2d 900int skipEvent(LttTracefile * t)
6cd62ccf 901{
902 int evId, err;
903 void * evData;
963b5f2d 904 LttEventType * evT;
905 LttField * rootFld;
99ff36b1 906 static int evCount = 0;
907
908 if(evCount){
909 if(t->which_block == t->block_number &&
910 evCount == t->which_event){
911 return ENOMEM;
912 }else evCount = 0;
913 }
6cd62ccf 914
963b5f2d 915 evId = (int)(*(uint16_t *)(t->cur_event_pos));
6cd62ccf 916 evData = t->cur_event_pos + EVENT_HEADER_SIZE;
6cd62ccf 917
47a166fc 918 //regard BLOCK_START, END and HEARTBEAT as special case, there are buildin events
919 if(evId != TRACE_BLOCK_START && evId != TRACE_BLOCK_END && evId != TRACE_TIME_HEARTBEAT){
920 evT = ltt_trace_eventtype_get(t->trace,(unsigned)evId);
921
922 if(evT) rootFld = evT->root_field;
923 else return ERANGE;
6cd62ccf 924
47a166fc 925 if(rootFld){
926 //event has string/sequence or the last event is not the same event
927 if((evT->latest_block!=t->which_block || evT->latest_event!=t->which_event)
928 && rootFld->field_fixed == 0){
929 setFieldsOffset(t, evT, evData, t->trace);
930 }
931 t->cur_event_pos += EVENT_HEADER_SIZE + rootFld->field_size;
932 }else t->cur_event_pos += EVENT_HEADER_SIZE;
933
934 evT->latest_block = t->which_block;
935 evT->latest_event = t->which_event;
936 }else{
937 if(evId == TRACE_BLOCK_START || evId == TRACE_BLOCK_END){
938 t->cur_event_pos += sizeof(BlockStart) + EVENT_HEADER_SIZE;
939 }else{
940 t->cur_event_pos += sizeof(TimeHeartbeat) + EVENT_HEADER_SIZE;
941 }
6cd62ccf 942 }
6cd62ccf 943
944 //the next event is in the next block
963b5f2d 945 if(evId == TRACE_BLOCK_END){
99ff36b1 946 if(t->which_block == t->block_number){
947 t->which_event++;
948 evCount = t->which_event;
949 return ENOENT;
950 }
6cd62ccf 951 err = readBlock(t, t->which_block + 1);
952 if(err) return err;
953 }else{
954 t->which_event++;
62e55dd6 955 t->current_event_time = getEventTime(t);
6cd62ccf 956 }
957
958 return 0;
959}
960
961/*****************************************************************************
962 *Function name
963 * getCyclePerNsec : calculate cycles per nsec for current block
964 *Input Params
965 * t : tracefile
966 ****************************************************************************/
967
963b5f2d 968void getCyclePerNsec(LttTracefile * t)
6cd62ccf 969{
963b5f2d 970 LttTime lBufTotalTime; /* Total time for this buffer */
971 LttCycleCount lBufTotalNSec; /* Total time for this buffer in nsecs */
972 LttCycleCount lBufTotalCycle;/* Total cycles for this buffer */
6cd62ccf 973
974 /* Calculate the total time for this buffer */
963b5f2d 975 TimeSub(lBufTotalTime,t->a_block_end->time, t->a_block_start->time);
6cd62ccf 976
977 /* Calculate the total cycles for this bufffer */
963b5f2d 978 lBufTotalCycle = t->a_block_end->cycle_count
979 - t->a_block_start->cycle_count;
6cd62ccf 980
981 /* Convert the total time to nsecs */
982 lBufTotalNSec = lBufTotalTime.tv_sec * 1000000000 + lBufTotalTime.tv_nsec;
983
984 t->cycle_per_nsec = (double)lBufTotalCycle / (double)lBufTotalNSec;
985}
986
987/****************************************************************************
988 *Function name
989 * getEventTime : obtain the time of an event
990 *Input params
991 * tf : tracefile
992 *Return value
963b5f2d 993 * LttTime : the time of the event
6cd62ccf 994 ****************************************************************************/
995
963b5f2d 996LttTime getEventTime(LttTracefile * tf)
6cd62ccf 997{
963b5f2d 998 LttTime time;
999 LttCycleCount cycle_count; // cycle count for the current event
1000 LttCycleCount lEventTotalCycle; // Total cycles from start for event
1001 double lEventNSec; // Total usecs from start for event
1002 LttTime lTimeOffset; // Time offset in struct LttTime
40331ba8 1003 uint16_t evId;
6cd62ccf 1004
40331ba8 1005 evId = *(uint16_t*)tf->cur_event_pos;
1006 if(evId == TRACE_BLOCK_START)
1007 return tf->a_block_start->time;
1008 else if(evId == TRACE_BLOCK_END)
1009 return tf->a_block_end->time;
1010
1011
963b5f2d 1012 // Calculate total time in cycles from start of buffer for this event
1013 cycle_count = (LttCycleCount)*(uint32_t*)(tf->cur_event_pos + EVENT_ID_SIZE);
6cd62ccf 1014 if(tf->cur_heart_beat_number)
1015 cycle_count += ((uint64_t)1)<<32 * tf->cur_heart_beat_number;
963b5f2d 1016 lEventTotalCycle = cycle_count - tf->a_block_start->cycle_count;
6cd62ccf 1017
963b5f2d 1018 // Convert it to nsecs
6cd62ccf 1019 lEventNSec = lEventTotalCycle / tf->cycle_per_nsec;
1020
963b5f2d 1021 // Determine offset in struct LttTime
6cd62ccf 1022 lTimeOffset.tv_nsec = (long)lEventNSec % 1000000000;
1023 lTimeOffset.tv_sec = (long)lEventNSec / 1000000000;
1024
963b5f2d 1025 TimeAdd(time, tf->a_block_start->time, lTimeOffset);
6cd62ccf 1026
1027 return time;
1028}
1029
1030/*****************************************************************************
1031 *Function name
1032 * setFieldsOffset : set offset of the fields
1033 *Input params
1034 * tracefile : opened trace file
1035 * evT : the event type
1036 * evD : event data, it may be NULL
1037 ****************************************************************************/
1038
40331ba8 1039void setFieldsOffset(LttTracefile *tf,LttEventType *evT,void *evD,LttTrace* t)
6cd62ccf 1040{
963b5f2d 1041 LttField * rootFld = evT->root_field;
6cd62ccf 1042 // rootFld->base_address = evD;
1043
8710c6c7 1044 if(rootFld)
1045 rootFld->field_size = getFieldtypeSize(tf, evT, 0,0,rootFld, evD,t);
6cd62ccf 1046}
1047
1048/*****************************************************************************
1049 *Function name
1050 * getFieldtypeSize: get the size of the field type (primitive type)
1051 *Input params
1052 * tracefile : opened trace file
1053 * evT : event type
1054 * offsetRoot : offset from the root
1055 * offsetParent : offset from the parrent
1056 * fld : field
1057 * evD : event data, it may be NULL
1058 *Return value
1059 * int : size of the field
1060 ****************************************************************************/
1061
963b5f2d 1062int getFieldtypeSize(LttTracefile * t, LttEventType * evT, int offsetRoot,
40331ba8 1063 int offsetParent, LttField * fld, void *evD, LttTrace *trace)
6cd62ccf 1064{
1065 int size, size1, element_number, i, offset1, offset2;
963b5f2d 1066 LttType * type = fld->field_type;
6cd62ccf 1067
8710c6c7 1068 if(t){
963b5f2d 1069 if(evT->latest_block==t->which_block && evT->latest_event==t->which_event){
1070 return fld->field_size;
1071 }
1072 }
6cd62ccf 1073
1074 if(fld->field_fixed == 1){
1075 if(fld == evT->root_field) return fld->field_size;
1076 }
1077
1078 if(type->type_class != LTT_STRUCT && type->type_class != LTT_ARRAY &&
1079 type->type_class != LTT_SEQUENCE && type->type_class != LTT_STRING){
1080 if(fld->field_fixed == -1){
40331ba8 1081 size = (int) ltt_type_size(trace, type);
6cd62ccf 1082 fld->field_fixed = 1;
1083 }else size = fld->field_size;
1084
1085 }else if(type->type_class == LTT_ARRAY){
1086 element_number = (int) type->element_number;
1087 if(fld->field_fixed == -1){
40331ba8 1088 size = getFieldtypeSize(t, evT, offsetRoot,0,fld->child[0], NULL, trace);
6cd62ccf 1089 if(size == 0){ //has string or sequence
1090 fld->field_fixed = 0;
1091 }else{
1092 fld->field_fixed = 1;
1093 size *= element_number;
1094 }
1095 }else if(fld->field_fixed == 0){// has string or sequence
1096 size = 0;
1097 for(i=0;i<element_number;i++){
1098 size += getFieldtypeSize(t, evT, offsetRoot+size,size,
40331ba8 1099 fld->child[0], evD+size, trace);
6cd62ccf 1100 }
1101 }else size = fld->field_size;
1102
1103 }else if(type->type_class == LTT_SEQUENCE){
40331ba8 1104 size1 = (int) ltt_type_size(trace, type);
6cd62ccf 1105 if(fld->field_fixed == -1){
1106 fld->field_fixed = 0;
40331ba8 1107 size = getFieldtypeSize(t, evT, offsetRoot,0,fld->child[0], NULL, trace);
6cd62ccf 1108 fld->element_size = size;
1109 }else{//0: sequence
1110 element_number = getIntNumber(size1,evD);
1111 type->element_number = element_number;
1112 if(fld->element_size > 0){
1113 size = element_number * fld->element_size;
1114 }else{//sequence has string or sequence
1115 size = 0;
1116 for(i=0;i<element_number;i++){
1117 size += getFieldtypeSize(t, evT, offsetRoot+size+size1,size+size1,
40331ba8 1118 fld->child[0], evD+size+size1, trace);
6cd62ccf 1119 }
1120 }
1121 size += size1;
1122 }
1123
1124 }else if(type->type_class == LTT_STRING){
1125 size = 0;
1126 if(fld->field_fixed == -1){
1127 fld->field_fixed = 0;
1128 }else{//0: string
47a166fc 1129 size = strlen((char*)evD) + 1; //include end : '\0'
6cd62ccf 1130 }
1131
1132 }else if(type->type_class == LTT_STRUCT){
1133 element_number = (int) type->element_number;
1134 size = 0;
1135 if(fld->field_fixed == -1){
1136 offset1 = offsetRoot;
1137 offset2 = 0;
1138 for(i=0;i<element_number;i++){
40331ba8 1139 size1=getFieldtypeSize(t, evT,offset1,offset2, fld->child[i], NULL, trace);
6cd62ccf 1140 if(size1 > 0 && size >= 0){
1141 size += size1;
1142 if(offset1 >= 0) offset1 += size1;
1143 offset2 += size1;
1144 }else{
1145 size = -1;
1146 offset1 = -1;
1147 offset2 = -1;
1148 }
1149 }
1150 if(size == -1){
1151 fld->field_fixed = 0;
1152 size = 0;
1153 }else fld->field_fixed = 1;
1154 }else if(fld->field_fixed == 0){
1155 offset1 = offsetRoot;
1156 offset2 = 0;
1157 for(i=0;i<element_number;i++){
40331ba8 1158 size=getFieldtypeSize(t,evT,offset1,offset2,fld->child[i],evD+offset2, trace);
6cd62ccf 1159 offset1 += size;
1160 offset2 += size;
1161 }
1162 size = offset2;
1163 }else size = fld->field_size;
1164 }
1165
1166 fld->offset_root = offsetRoot;
1167 fld->offset_parent = offsetParent;
1168 if(!evD){
1169 fld->fixed_root = (offsetRoot==-1) ? 0 : 1;
1170 fld->fixed_parent = (offsetParent==-1) ? 0 : 1;
1171 }
1172 fld->field_size = size;
1173
1174 return size;
1175}
1176
1177/*****************************************************************************
1178 *Function name
1179 * timecmp : compare two time
1180 *Input params
1181 * t1 : first time
1182 * t2 : second time
1183 *Return value
1184 * int : 0: t1 == t2; -1: t1 < t2; 1: t1 > t2
1185 ****************************************************************************/
1186
963b5f2d 1187int timecmp(LttTime * t1, LttTime * t2)
6cd62ccf 1188{
963b5f2d 1189 LttTime T;
6cd62ccf 1190 TimeSub(T, *t1, *t2);
1191 if(T.tv_sec == 0 && T.tv_nsec == 0) return 0;
1192 else if(T.tv_sec > 0 || (T.tv_sec==0 && T.tv_nsec > 0)) return 1;
1193 else return -1;
1194}
1195
1196/*****************************************************************************
1197 *Function name
1198 * getIntNumber : get an integer number
1199 *Input params
1200 * size : the size of the integer
1201 * evD : the event data
1202 *Return value
1203 * int : an integer
1204 ****************************************************************************/
1205
1206int getIntNumber(int size, void *evD)
1207{
1208 int64_t i;
1209 if(size == 1) i = *(int8_t *)evD;
1210 else if(size == 2) i = *(int16_t *)evD;
1211 else if(size == 4) i = *(int32_t *)evD;
1212 else if(size == 8) i = *(int64_t *)evD;
1213
1214 return (int) i;
1215}
1216
1217/*****************************************************************************
1218 *Function name
1219 * getDataEndianType : get the data type size and endian type of the local
1220 * machine
1221 *Input params
1222 * size : size of data type
1223 * endian : endian type, little or big
1224 ****************************************************************************/
1225
963b5f2d 1226void getDataEndianType(LttArchSize * size, LttArchEndian * endian)
6cd62ccf 1227{
1228 int i = 1;
1229 char c = (char) i;
1230 int sizeInt=sizeof(int), sizeLong=sizeof(long), sizePointer=sizeof(void *);
1231
1232 if(c == 1) *endian = LTT_LITTLE_ENDIAN;
1233 else *endian = LTT_BIG_ENDIAN;
1234
1235 if(sizeInt == 2 && sizeLong == 4 && sizePointer == 4)
1236 *size = LTT_LP32;
1237 else if(sizeInt == 4 && sizeLong == 4 && sizePointer == 4)
1238 *size = LTT_ILP32;
1239 else if(sizeInt == 4 && sizeLong == 8 && sizePointer == 8)
1240 *size = LTT_LP64;
1241 else if(sizeInt == 8 && sizeLong == 8 && sizePointer == 8)
1242 *size = LTT_ILP64;
1243 else *size = LTT_UNKNOWN;
1244}
1245
This page took 0.079654 seconds and 4 git commands to generate.