3 genevent.c: Generate helper declarations and functions to trace events
4 from an event description file.
6 Copyright (C) 2002, Xianxiu Yang
7 Copyright (C) 2002, Michel Dagenais
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 /* This program reads the ".event" event definitions input files
24 specified as command line arguments and generates corresponding
25 ".c" and ".h" files required to trace such events in the kernel.
27 The program uses a very simple tokenizer, called from a hand written
28 recursive descent parser to fill a data structure describing the events.
29 The result is a sequence of events definitions which refer to type
32 A table of named types is maintained to allow refering to types by name
33 when the same type is used at several places. Finally a sequence of
34 all types is maintained to facilitate the freeing of all type
35 information when the processing of an ".event" file is finished. */
42 #include <linux/errno.h>
48 #define max(a,b) ((a)<(b))?(b):(a)
50 /* Named types may be referenced from anywhere */
54 unsigned alignment
= 0;
56 int main(int argc
, char** argv
)
60 char buffer
[BUFFER_SIZE
];
64 printf("At least one event definition file is needed\n");
65 printf("You may specify the default alignment for a facility with\n");
66 printf(" -a x , where x is the desired alignment in bytes.\n");
67 printf("The alignment value will affect all the following xml files.\n");
68 printf("i.e. genevent -a 8 core.xml -a 4 kernel.xml is valid.\n");
73 in
.error
= error_callback
;
75 for(i
= 1 ; i
< argc
; i
++) {
77 if(strcmp("-a", argv
[i
])==0) {
79 printf("Error : missing argument to -a\n");
82 alignment
= atoi(argv
[i
]);
86 in
.name
= allocAndCopy(argv
[i
]);
88 in
.fp
= fopen(in
.name
, "r");
90 in
.error(&in
,"cannot open facility input file");
94 token
= getToken(&in
);
95 if(in
.type
== ENDFILE
) break;
97 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
100 if(strcmp("facility",token
) == 0) {
101 fac
= memAlloc(sizeof(facility
));
103 fac
->description
= NULL
;
104 sequence_init(&(fac
->events
));
105 table_init(&(fac
->named_types
));
106 sequence_init(&(fac
->unnamed_types
));
108 parseFacility(&in
, fac
);
110 //check if any namedType is not defined
111 checkNamedTypesImplemented(&fac
->named_types
);
113 else in
.error(&in
,"facility token was expected");
115 generateFile(argv
[i
]);
118 free(fac
->description
);
119 freeEvents(&fac
->events
);
120 sequence_dispose(&fac
->events
);
121 freeNamedType(&fac
->named_types
);
122 table_dispose(&fac
->named_types
);
123 freeTypes(&fac
->unnamed_types
);
124 sequence_dispose(&fac
->unnamed_types
);
136 /*****************************************************************************
138 * generateFile : generate .c and .h file
140 * name : name of event definition file
141 ****************************************************************************/
142 void generateFile(char *name
){
143 char *loadName
, *hName
, *hIdName
, *cName
, *tmp
, *tmp2
;
144 FILE * lFp
, *hFp
, *iFp
, *cFp
;
146 unsigned long checksum
=0;
148 //remove .xml if it exists
149 tmp
= &name
[strlen(name
)-4];
150 if(strcmp(tmp
, ".xml") == 0){
154 tmp
= strrchr(name
,'/');
161 loadName
= appendString("ltt-facility-loader-", tmp
);
162 tmp2
= appendString(loadName
,".h");
165 hName
= appendString("ltt-facility-", tmp
);
166 tmp2
= appendString(hName
,".h");
169 hIdName
= appendString("ltt-facility-id-", tmp
);
170 tmp2
= appendString(hIdName
,".h");
173 cName
= appendString("ltt-facility-loader-", tmp
);
174 tmp2
= appendString(cName
,".c");
177 lFp
= fopen(loadName
,"w");
179 printf("Cannot open the file : %s\n",loadName
);
183 hFp
= fopen(hName
,"w");
185 printf("Cannot open the file : %s\n",hName
);
189 iFp
= fopen(hIdName
,"w");
191 printf("Cannot open the file : %s\n",hIdName
);
195 cFp
= fopen(cName
,"w");
197 printf("Cannot open the file : %s\n",cName
);
206 generateChecksum(fac
->name
, &checksum
, &(fac
->events
));
208 /* generate .h file, event enumeration then structures and functions */
209 fprintf(iFp
, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac
->capname
);
210 fprintf(iFp
, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac
->capname
);
211 fprintf(iFp
, "#ifdef CONFIG_LTT\n");
212 generateEnumEvent(iFp
, fac
->name
, &nbEvent
, checksum
);
213 fprintf(iFp
, "#endif //CONFIG_LTT\n");
214 fprintf(iFp
, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac
->capname
);
217 fprintf(hFp
, "#ifndef _LTT_FACILITY_%s_H_\n",fac
->capname
);
218 fprintf(hFp
, "#define _LTT_FACILITY_%s_H_\n\n",fac
->capname
);
219 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
220 generateTypeDefs(hFp
, fac
->name
);
221 generateStructFunc(hFp
, fac
->name
,checksum
);
222 //fprintf(hFp, "#endif //CONFIG_LTT\n");
223 fprintf(hFp
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
225 /* generate .h file, calls to register the facility at init time */
226 generateLoaderfile(lFp
,fac
->name
,nbEvent
,checksum
,fac
->capname
);
228 // create ltt-facility-loader-facname.c
229 generateCfile(cFp
, tmp
);
239 /*****************************************************************************
241 * generateEnumEvent : output event enum to .h file
243 * fp : file to be written to
244 * facName : name of facility
246 * nbEvent : number of events in the facility
247 ****************************************************************************/
248 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
, unsigned long checksum
) {
251 fprintf(fp
,"#include <linux/ltt-facilities.h>\n\n");
253 fprintf(fp
,"/**** facility handle ****/\n\n");
254 fprintf(fp
,"extern ltt_facility_t ltt_facility_%s_%X;\n",facName
, checksum
);
255 fprintf(fp
,"extern ltt_facility_t ltt_facility_%s;\n\n\n",facName
, checksum
);
257 fprintf(fp
,"/**** event type ****/\n\n");
258 fprintf(fp
,"enum %s_event {\n",facName
);
260 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
261 fprintf(fp
,"\tevent_%s", ((event
*)(fac
->events
.array
[pos
]))->name
);
262 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
264 fprintf(fp
,"\n};\n\n\n");
266 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
267 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
268 *nbEvent
= fac
->events
.position
;
272 /*****************************************************************************
274 * printStruct : Generic struct printing function
276 * fp : file to be written to
277 * len : number of fields
278 * array : array of field info
279 * name : basic struct name
280 * facName : name of facility
281 * whichTypeFirst : struct or array/sequence first
282 * hasStrSeq : string or sequence present?
283 * structCount : struct postfix
284 ****************************************************************************/
287 printStruct(FILE * fp
, int len
, void ** array
, char * name
, char * facName
,
288 int * whichTypeFirst
, int * hasStrSeq
, int * structCount
,
289 type_descriptor
*type
)
294 type_descriptor
* td
;
296 for (pos
= 0; pos
< len
; pos
++) {
297 fld
= (field
*)array
[pos
];
299 if( td
->type
== STRING
|| td
->type
== SEQUENCE
||
303 // if (*whichTypeFirst == 0) {
304 // *whichTypeFirst = 1; //struct first
309 fprintf(fp
,"struct %s_%s",name
, facName
);
311 fprintf(fp
, "_%d {\n",++*structCount
);
316 fprintf(fp
, "\t%s %s; /* %s */\n",
317 getTypeStr(td
),fld
->name
,fld
->description
);
320 if (*whichTypeFirst
== 0) {
321 //string or sequence or array first
326 fprintf(fp
,"} __attribute__ ((packed));\n\n");
334 unsigned align
= max(alignment
, type
->alignment
);
337 fprintf(fp
,"} __attribute__ ((packed));\n\n");
339 if(align
!= 1 && align
!= 2
340 && align
!= 4 && align
!= 8) {
341 printf("Wrong alignment %i, using packed.\n", align
);
342 fprintf(fp
,"} __attribute__ ((packed));\n\n");
344 fprintf(fp
,"} __attribute__ ((aligned(%i)));\n\n", align
);
350 /*****************************************************************************
352 * generateHfile : Create the typedefs
354 * fp : file to be written to
355 ****************************************************************************/
357 generateTypeDefs(FILE * fp
, char *facName
)
361 fprintf(fp
,"#include <linux/types.h>\n");
362 fprintf(fp
,"#include <linux/spinlock.h>\n");
363 fprintf(fp
,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName
);
364 fprintf(fp
,"#include <linux/ltt-core.h>\n");
367 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
369 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
370 type_descriptor
* type
=
371 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
372 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
373 "", type
->type_name
, &tmp
, &tmp
, NULL
);
374 fprintf(fp
, "typedef struct _%s %s;\n\n",
375 type
->type_name
, type
->type_name
);
381 /*****************************************************************************
383 * generateEnumDefinition: generate enum definition if it exists
385 * fp : file to be written to
387 ****************************************************************************/
388 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
391 if(type
->already_printed
) return;
393 fprintf(fp
,"enum {\n");
394 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
395 fprintf(fp
,"\tLTT_ENUM_%s", type
->labels
.array
[pos
]);
396 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",");
397 if(type
->labels_description
.array
[pos
] != NULL
)
398 fprintf(fp
,"\t/* %s */\n",type
->labels_description
.array
[pos
]);
402 fprintf(fp
,"};\n\n\n");
404 type
->already_printed
= 1;
407 /*****************************************************************************
409 * generateStrucTFunc: output structure and function to .h file
411 * fp : file to be written to
412 * facName : name of facility
413 ****************************************************************************/
414 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
417 type_descriptor
* td
;
419 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
421 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
422 ev
= (event
*) fac
->events
.array
[pos
];
423 //yxx if(ev->nested)continue;
424 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",
426 //if(ev->type == 0){ // event without type
427 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
428 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
429 // facName,checksum,ev->name);
430 // fprintf(fp,"};\n\n\n");
434 //if fields contain enum, print out enum definition
435 //MD : fixed in generateEnumDefinition to do not print the same enum
438 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
439 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
440 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
443 //default: no string, array or sequence in the event
448 //structure for kernel
450 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
451 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
,
455 //trace function : function name and parameters : stub function.
458 fprintf(fp
, "#ifndef CONFIG_LTT\n");
459 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
463 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
464 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
466 if(td
->type
== ARRAY
){
467 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
468 }else if(td
->type
== STRING
){
469 fprintf(fp
,"short int strlength_%d, %s * %s",
470 ++strCount
, getTypeStr(td
), fld
->name
);
471 }else if(td
->type
== SEQUENCE
){
472 fprintf(fp
,"%s seqlength_%d, %s * %s",
473 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
474 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
475 if(pos1
!= ev
->type
->fields
.position
- 1) fprintf(fp
,", ");
477 fprintf(fp
,")\n{\n");
479 fprintf(fp
,"#else\n");
481 //trace function : function name and parameters
484 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
488 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
489 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
491 if(td
->type
== ARRAY
){
492 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
493 }else if(td
->type
== STRING
){
494 fprintf(fp
,"short int strlength_%d, %s * %s",
495 ++strCount
, getTypeStr(td
), fld
->name
);
496 }else if(td
->type
== SEQUENCE
){
497 fprintf(fp
,"%s seqlength_%d, %s * %s",
498 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
499 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
500 if(pos1
!= ev
->type
->fields
.position
- 1) fprintf(fp
,", ");
502 fprintf(fp
,")\n{\n");
507 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
508 // write directly to the channel
509 fprintf(fp
, "\tunsigned int index;\n");
510 fprintf(fp
, "\tstruct ltt_channel_struct *channel;\n");
511 fprintf(fp
, "\tstruct ltt_trace_struct *trace;\n");
512 fprintf(fp
, "\tunsigned long _flags;\n");
513 fprintf(fp
, "\tvoid *buff;\n");
514 fprintf(fp
, "\tunsigned old_offset;\n");
515 fprintf(fp
, "\tunsigned int header_length;\n");
516 fprintf(fp
, "\tunsigned int event_length;\n"); // total size (incl hdr)
517 fprintf(fp
, "\tunsigned int length;\n"); // Size of the event var data.
518 fprintf(fp
, "\tunsigned char _offset;\n");
519 fprintf(fp
, "\tstruct rchan_buf *buf;\n");
520 fprintf(fp
, "\tstruct timeval delta;\n");
521 fprintf(fp
, "\tu64 tsc;\n");
522 fprintf(fp
, "\tchar *ptr;\n");
525 fprintf(fp
, "\tstruct %s_%s_1* __1;\n\n", ev
->name
, facName
);
527 /* Warning : this is done prior to taking locks :
528 * setting this value must be done at the end of the trace activation.
529 * (we don't care for trace removal, as the list of traces is protected : it
530 * just won't iterate on any trace). */
532 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
534 fprintf(fp
, "\t/* Disable interrupts. */\n");
535 fprintf(fp
, "\tlocal_irq_save(_flags);\n");
536 fprintf(fp
, "\tpreempt_disable();\n\n");
538 fprintf(fp
, "\tltt_nesting[smp_processor_id()]++;\n");
539 fprintf(fp
, "\tbarrier();\n");
540 fprintf(fp
, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
541 fprintf(fp
, "\tspin_lock(<t_traces.locks[smp_processor_id()]);\n\n");
544 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
545 "\t\t\t\tevent_%s);\n",
546 facName
, checksum
, ev
->name
);
550 fprintf(fp
, "\tlist_for_each_entry(trace, <t_traces.head, list) {\n");
551 fprintf(fp
, "\t\tif(!trace->active) continue;\n\n");
553 //length of buffer : length of all structures
554 // if(ev->type == 0) fprintf(fp, "0");
556 fprintf(fp
, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
557 fprintf(fp
, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
559 /* Warning : not atomic reservation : event size depends on the current
560 * address for alignment */
561 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
563 /* NOTE2 : as the read old address from memory must come before any
564 * protected event, let's add a memory barrier() to make sure the compiler
565 * will not reorder this read. */
566 fprintf(fp
, "\t\tdo {\n");
567 fprintf(fp
, "\t\t\told_offset = buf->offset;\n");
568 fprintf(fp
, "\t\t\tbarrier();\n");
569 fprintf(fp
, "\t\t\tptr = (char*)buf->data + old_offset;\n");
572 fprintf(fp
, "\t\t\theader_length = ltt_get_event_header_data(trace, "
574 "\t\t\t\t\t\t\t\t\t\tptr, &_offset, &delta, &tsc);\n");
576 fprintf(fp
, "\t\t\tptr += _offset + header_length;\n");
578 for(pos1
=0;pos1
<structCount
;pos1
++){
580 unsigned align
= max(alignment
, ev
->type
->alignment
);
582 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
583 align
, align
, align
);
585 fprintf(fp
,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev
->name
,
587 // if(pos1 != structCount-1) fprintf(fp," + ");
590 //length of buffer : length of all arrays, sequences and strings
595 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
596 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
598 if(td
->type
== SEQUENCE
|| td
->type
==STRING
|| td
->type
==ARRAY
){
599 if(td
->type
== SEQUENCE
) {
601 unsigned align
= max(alignment
, td
->alignment
);
603 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
604 align
, align
, align
);
606 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
608 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
609 align
, align
, align
);
611 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
612 getTypeStr(td
), seqCount
);
614 } else if(td
->type
==STRING
) {
615 unsigned align
= max(alignment
, td
->alignment
);
617 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
618 align
, align
, align
);
620 fprintf(fp
,"ptr += strlength_%d + 1;\n",
623 else if(td
->type
==ARRAY
) {
624 unsigned align
= max(alignment
, td
->alignment
);
626 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
627 align
, align
, align
);
629 fprintf(fp
,"\t\t\tptr += sizeof(%s) * %d;\n",
630 getTypeStr(td
),td
->size
);
631 if(structCount
== 0) flag
= 1;
635 fprintf(fp
, "\t\t\tevent_length = (unsigned long)ptr -"
636 "(unsigned long)(buf->data + old_offset);\n");
638 /* let's put some protection before the cmpxchg : the space reservation and
639 * the get TSC are not dependant from each other. I don't want the compiler
640 * to reorder those in the wrong order. And relay_reserve is inline, so
641 * _yes_, the compiler could mess it up. */
642 fprintf(fp
, "\t\t\tbarrier();\n");
643 fprintf(fp
, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
646 fprintf(fp
, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
650 /* Reserve the channel */
651 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
652 fprintf(fp
, "\t\tif(buff == NULL) {\n");
653 fprintf(fp
, "\t\t\t/* Buffer is full*/\n");
654 fprintf(fp
, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
655 fprintf(fp
, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
656 fprintf(fp
, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
657 fprintf(fp
, "\t\t}\n");
660 //fprintf(fp, "\t\tif(resret == 1) {\n");
661 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
662 // facName, checksum, ev->name);
663 //fprintf(fp, "\t\t}\n");
665 /* Write the header */
667 fprintf(fp
,"\t\tlength = event_length - _offset - header_length;\n");
669 fprintf(fp
, "\t\tltt_write_event_header(trace, channel, buff, \n"
670 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
671 "\t\t\t\t&delta, &tsc);\n",
672 facName
, checksum
, ev
->name
);
676 fprintf(fp
, "\t\tchar *ptr = (char*)buff + _offset + header_length;\n");
679 //declare a char pointer if needed : starts at the end of the structs.
680 //if(structCount + hasStrSeq > 1) {
681 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
682 // for(pos1=0;pos1<structCount;pos1++){
683 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
685 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
688 // Declare an alias pointer of the struct type to the beginning
689 // of the reserved area, just after the event header.
691 unsigned align
= max(alignment
, td
->alignment
);
693 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
694 align
, align
, align
);
697 fprintf(fp
, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
700 //allocate memory for new struct and initialize it
701 //if(whichTypeFirst == 1){ //struct first
702 //for(pos1=0;pos1<structCount;pos1++){
703 // if(pos1==0) fprintf(fp,
704 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
705 // ev->name, facName,ev->name, facName);
706 //MD disabled else fprintf(fp,
707 // "\tstruct %s_%s_%d __%d;\n",
708 // ev->name, facName,pos1+1,pos1+1);
710 //}else if(whichTypeFirst == 2){
711 // for(pos1=0;pos1<structCount;pos1++)
712 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
713 // ev->name, facName,pos1+1,pos1+1);
717 if(structCount
) fprintf(fp
,"\t\t//initialize structs\n");
721 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
722 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
724 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
728 // if(structCount > 1) fprintf(fp,"\n");
730 fprintf(fp
, "\t\t__1->%s = %s;\n", fld
->name
, fld
->name
);
732 //if(structCount == 1 && whichTypeFirst == 1)
733 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
735 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
739 if(structCount
) fprintf(fp
,"\n");
740 //set ptr to the end of first struct if needed;
741 //if(structCount + hasStrSeq > 1){
742 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
743 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
746 //copy struct, sequence and string to buffer
752 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
753 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
755 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
756 // if(flag == 0) structCount++;
758 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
759 // assert(0); // MD : disabled !
760 // fprintf(fp,"\t//copy struct to buffer\n");
761 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
762 // structCount, ev->name, facName,structCount);
763 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
764 // ev->name, facName,structCount);
767 //else if(td->type == SEQUENCE){
768 if(td
->type
== SEQUENCE
){
770 fprintf(fp
,"\t\t//copy sequence length and sequence to buffer\n");
772 unsigned align
= max(alignment
, td
->alignment
);
774 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
775 align
, align
, align
);
777 fprintf(fp
,"\t\t*ptr = seqlength_%d;\n",++seqCount
);
778 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
780 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
781 align
, align
, align
);
783 fprintf(fp
,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
784 fld
->name
, getTypeStr(td
), seqCount
);
785 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
786 getTypeStr(td
), seqCount
);
788 else if(td
->type
==STRING
){
790 fprintf(fp
,"\t\t//copy string to buffer\n");
791 fprintf(fp
,"\t\tif(strlength_%d > 0){\n",++strCount
);
792 unsigned align
= max(alignment
, td
->alignment
);
794 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
795 align
, align
, align
);
797 fprintf(fp
,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
798 fld
->name
, strCount
);
799 fprintf(fp
,"\t\t\tptr += strlength_%d + 1;\n",strCount
);
800 fprintf(fp
,"\t\t}else{\n");
801 fprintf(fp
,"\t\t\t*ptr = '\\0';\n");
802 fprintf(fp
,"\t\t\tptr += 1;\n");
803 fprintf(fp
,"\t\t}\n\n");
804 }else if(td
->type
==ARRAY
){
806 fprintf(fp
,"\t//copy array to buffer\n");
807 unsigned align
= max(alignment
, td
->alignment
);
809 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
810 align
, align
, align
);
812 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
813 fld
->name
, getTypeStr(td
), td
->size
);
814 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td
), td
->size
);
817 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
820 fprintf(fp
, "\t\t/* Commit the work */\n");
821 fprintf(fp
, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
822 "\t\t\t\tbuff, event_length);\n");
823 fprintf(fp
, "\t\tltt_write_commit_counter("
824 "channel->rchan->buf[smp_processor_id()],\n"
827 /* End of traces iteration */
828 fprintf(fp
, "\t}\n\n");
831 // The generated preempt_check_resched is not dangerous because
832 // interrupts are disabled.
833 fprintf(fp
, "\tspin_unlock(<t_traces.locks[smp_processor_id()]);\n");
835 fprintf(fp
, "unlock:\n");
836 fprintf(fp
, "\tbarrier();\n");
837 fprintf(fp
, "\tltt_nesting[smp_processor_id()]--;\n");
838 fprintf(fp
, "\t/* Re-enable interrupts */\n");
839 fprintf(fp
, "\tlocal_irq_restore(_flags);\n");
840 fprintf(fp
, "\tpreempt_enable_no_resched();\n");
841 //fprintf(fp, "\tpreempt_check_resched();\n");
843 //call trace function
844 //fprintf(fp,"\n\t//call trace function\n");
845 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
847 fprintf(fp
, "#endif //CONFIG_LTT\n\n");
852 /*****************************************************************************
854 * getTypeStr : generate type string
856 * td : a type descriptor
858 * char * : type string
859 ****************************************************************************/
860 char * getTypeStr(type_descriptor
* td
){
861 type_descriptor
* t
;
865 return intOutputTypes
[td
->size
];
867 return uintOutputTypes
[td
->size
];
873 return "unsigned long";
881 return floatOutputTypes
[td
->size
];
885 return uintOutputTypes
[td
->size
];
891 return intOutputTypes
[t
->size
];
893 return uintOutputTypes
[t
->size
];
899 return "unsigned long";
907 return floatOutputTypes
[t
->size
];
911 return uintOutputTypes
[t
->size
];
913 error_callback(NULL
,"Nested struct is not supportted");
917 case STRUCT
: //for now we do not support nested struct
918 error_callback(NULL
,"Nested struct is not supportted");
921 error_callback(NULL
,"No type information");
927 /*****************************************************************************
929 * generateLoaderfile: generate a facility loaded .h file
931 * fp : file to be written to
932 * facName : name of facility
933 * nbEvent : number of events in the facility
934 * checksum : checksum for the facility
935 ****************************************************************************/
936 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
, char *capname
){
937 fprintf(fp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname
);
938 fprintf(fp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname
);
939 fprintf(fp
,"#include <linux/ltt-facilities.h>\n", facName
, checksum
);
940 fprintf(fp
,"ltt_facility_t\tltt_facility_%s;\n", facName
, checksum
);
941 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
943 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
945 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
947 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum
);
948 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName
);
949 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent
);
950 fprintf(fp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname
);
953 void generateCfile(FILE * fp
, char * filefacname
){
956 fprintf(fp
, " * ltt-facility-loader-%s.c\n", filefacname
);
958 fprintf(fp
, " * (C) Copyright 2005 - \n");
959 fprintf(fp
, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
961 fprintf(fp
, " * Contains the LTT facility loader.\n");
963 fprintf(fp
, " */\n");
966 fprintf(fp
, "#include <linux/ltt-facilities.h>\n");
967 fprintf(fp
, "#include <linux/module.h>\n");
968 fprintf(fp
, "#include <linux/init.h>\n");
969 fprintf(fp
, "#include <linux/config.h>\n");
970 fprintf(fp
, "#include \"ltt-facility-loader-%s.h\"\n", filefacname
);
973 fprintf(fp
, "#ifdef CONFIG_LTT\n");
975 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
976 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
978 fprintf(fp
, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
980 fprintf(fp
, "#define SYMBOL_STRING(sym) #sym\n");
982 fprintf(fp
, "static struct ltt_facility facility = {\n");
983 fprintf(fp
, "\t.name = ltt_facility_name,\n");
984 fprintf(fp
, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
985 fprintf(fp
, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
986 fprintf(fp
, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
987 fprintf(fp
, "\t.alignment = %u\n", alignment
); /* default alignment */
990 fprintf(fp
, "#ifndef MODULE\n");
992 fprintf(fp
, "/* Built-in facility. */\n");
994 fprintf(fp
, "static int __init facility_init(void)\n");
996 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname
);
998 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
999 fprintf(fp
, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1000 fprintf(fp
, "\t\n");
1001 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
1003 fprintf(fp
, "__initcall(facility_init);\n");
1007 fprintf(fp
, "#else \n");
1009 fprintf(fp
, "/* Dynamic facility. */\n");
1011 fprintf(fp
, "static int __init facility_init(void)\n");
1013 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname
);
1015 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
1016 fprintf(fp
, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
1018 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
1021 fprintf(fp
, "static void __exit facility_exit(void)\n");
1023 fprintf(fp
, "\tint err;\n");
1025 fprintf(fp
, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
1026 fprintf(fp
, "\tif(err != 0)\n");
1027 fprintf(fp
, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
1031 fprintf(fp
, "module_init(facility_init)\n");
1032 fprintf(fp
, "module_exit(facility_exit)\n");
1035 fprintf(fp
, "MODULE_LICENSE(\"GPL\");\n");
1036 fprintf(fp
, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1037 fprintf(fp
, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1039 fprintf(fp
, "#endif //MODULE\n");
1041 fprintf(fp
, "#endif //CONFIG_LTT\n");
This page took 0.05779 seconds and 4 git commands to generate.