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_t
));
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
)
144 char *loadName
, *hName
, *hIdName
, *cName
, *tmp
, *tmp2
;
145 FILE * lFp
, *hFp
, *iFp
, *cFp
;
147 unsigned long checksum
=0;
149 //remove .xml if it exists
150 tmp
= &name
[strlen(name
)-4];
151 if(strcmp(tmp
, ".xml") == 0){
155 tmp
= strrchr(name
,'/');
162 loadName
= appendString("ltt-facility-loader-", tmp
);
163 tmp2
= appendString(loadName
,".h");
166 hName
= appendString("ltt-facility-", tmp
);
167 tmp2
= appendString(hName
,".h");
170 hIdName
= appendString("ltt-facility-id-", tmp
);
171 tmp2
= appendString(hIdName
,".h");
174 cName
= appendString("ltt-facility-loader-", tmp
);
175 tmp2
= appendString(cName
,".c");
178 lFp
= fopen(loadName
,"w");
180 printf("Cannot open the file : %s\n",loadName
);
184 hFp
= fopen(hName
,"w");
186 printf("Cannot open the file : %s\n",hName
);
190 iFp
= fopen(hIdName
,"w");
192 printf("Cannot open the file : %s\n",hIdName
);
196 cFp
= fopen(cName
,"w");
198 printf("Cannot open the file : %s\n",cName
);
207 generateChecksum(fac
->name
, &checksum
, &(fac
->events
));
209 /* generate .h file, event enumeration then structures and functions */
210 fprintf(iFp
, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac
->capname
);
211 fprintf(iFp
, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac
->capname
);
212 fprintf(iFp
, "#ifdef CONFIG_LTT\n");
213 generateEnumEvent(iFp
, fac
->name
, &nbEvent
, checksum
);
214 fprintf(iFp
, "#endif //CONFIG_LTT\n");
215 fprintf(iFp
, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac
->capname
);
218 fprintf(hFp
, "#ifndef _LTT_FACILITY_%s_H_\n",fac
->capname
);
219 fprintf(hFp
, "#define _LTT_FACILITY_%s_H_\n\n",fac
->capname
);
220 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
221 generateTypeDefs(hFp
, fac
->name
);
222 generateStructFunc(hFp
, fac
->name
,checksum
);
223 //fprintf(hFp, "#endif //CONFIG_LTT\n");
224 fprintf(hFp
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
226 /* generate .h file, calls to register the facility at init time */
227 generateLoaderfile(lFp
,fac
->name
,nbEvent
,checksum
,fac
->capname
);
229 // create ltt-facility-loader-facname.c
230 generateCfile(cFp
, tmp
);
240 /*****************************************************************************
242 * generateEnumEvent : output event enum to .h file
244 * fp : file to be written to
245 * facName : name of facility
247 * nbEvent : number of events in the facility
248 ****************************************************************************/
249 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
,
250 unsigned long checksum
) {
253 fprintf(fp
,"#include <linux/ltt-facilities.h>\n\n");
255 fprintf(fp
,"/**** facility handle ****/\n\n");
256 fprintf(fp
,"extern ltt_facility_t ltt_facility_%s_%X;\n",facName
, checksum
);
257 fprintf(fp
,"extern ltt_facility_t ltt_facility_%s;\n\n\n",facName
, checksum
);
259 fprintf(fp
,"/**** event type ****/\n\n");
260 fprintf(fp
,"enum %s_event {\n",facName
);
262 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
263 fprintf(fp
,"\tevent_%s", ((event_t
*)(fac
->events
.array
[pos
]))->name
);
264 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
266 fprintf(fp
,"\n};\n\n\n");
268 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
269 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
270 *nbEvent
= fac
->events
.position
;
274 /*****************************************************************************
276 * printStruct : Generic struct printing function
278 * fp : file to be written to
279 * len : number of fields
280 * array : array of field info
281 * name : basic struct name
282 * facName : name of facility
283 * whichTypeFirst : struct or array/sequence first
284 * hasStrSeq : string or sequence present?
285 * structCount : struct postfix
286 ****************************************************************************/
289 printStruct(FILE * fp
, int len
, void ** array
, char * name
, char * facName
,
290 int * whichTypeFirst
, int * hasStrSeq
, int * structCount
,
291 type_descriptor_t
*type
)
296 type_descriptor_t
* td
;
298 for (pos
= 0; pos
< len
; pos
++) {
299 fld
= (field_t
*)array
[pos
];
301 if( td
->type
== STRING
|| td
->type
== SEQUENCE
||
307 fprintf(fp
,"struct %s_%s",name
, facName
);
309 fprintf(fp
, "_%d {\n",++*structCount
);
314 fprintf(fp
, "\t%s %s; /* %s */\n",
315 getTypeStr(td
),fld
->name
,fld
->description
);
320 unsigned align
= max(alignment
, type
->alignment
);
323 fprintf(fp
,"} __attribute__ ((packed));\n\n");
325 if(align
!= 1 && align
!= 2
326 && align
!= 4 && align
!= 8) {
327 printf("Wrong alignment %i, using packed.\n", align
);
328 fprintf(fp
,"} __attribute__ ((packed));\n\n");
330 fprintf(fp
,"} __attribute__ ((aligned(%i)));\n\n", align
);
336 /*****************************************************************************
338 * generateHfile : Create the typedefs
340 * fp : file to be written to
341 ****************************************************************************/
343 generateTypeDefs(FILE * fp
, char *facName
)
347 fprintf(fp
,"#include <linux/types.h>\n");
348 fprintf(fp
,"#include <linux/spinlock.h>\n");
349 fprintf(fp
,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName
);
350 fprintf(fp
,"#include <linux/ltt-core.h>\n");
353 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
355 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
356 type_descriptor
* type
=
357 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
358 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
359 "", type
->type_name
, &tmp
, &tmp
, NULL
);
360 fprintf(fp
, "typedef struct _%s %s;\n\n",
361 type
->type_name
, type
->type_name
);
367 /*****************************************************************************
369 * generateEnumDefinition: generate enum definition if it exists
371 * fp : file to be written to
373 ****************************************************************************/
374 void generateEnumDefinition(FILE * fp
, type_descriptor_t
* type
){
377 if(type
->already_printed
) return;
379 fprintf(fp
,"enum {\n");
380 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
381 fprintf(fp
,"\tLTT_ENUM_%s", type
->labels
.array
[pos
]);
382 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",");
383 if(type
->labels_description
.array
[pos
] != NULL
)
384 fprintf(fp
,"\t/* %s */\n",type
->labels_description
.array
[pos
]);
388 fprintf(fp
,"};\n\n\n");
390 type
->already_printed
= 1;
393 /*****************************************************************************
395 * generateStrucTFunc: output structure and function to .h file
397 * fp : file to be written to
398 * facName : name of facility
399 ****************************************************************************/
400 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
403 type_descriptor_t
* td
;
405 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
408 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
409 ev
= (event_t
*) fac
->events
.array
[pos
];
410 //yxx if(ev->nested)continue;
411 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",
413 //if(ev->type == 0){ // event without type
414 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
415 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
416 // facName,checksum,ev->name);
417 // fprintf(fp,"};\n\n\n");
421 //if fields contain enum, print out enum definition
422 //MD : fixed in generateEnumDefinition to do not print the same enum
425 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
426 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
427 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
430 //default: no string, array or sequence in the event
435 //structure for kernel
437 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
438 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
,
442 //trace function : function name and parameters : stub function.
445 fprintf(fp
, "#ifndef CONFIG_LTT\n");
446 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
450 /* Does it support per trace tracing ? */
452 fprintf(fp
, "struct ltt_trace_struct *dest_trace");
456 /* Does it support per tracefile tracing ? */
457 if(ev
->per_tracefile
) {
458 if(!args_empty
) fprintf(fp
, ", ");
459 fprintf(fp
, "unsigned int tracefile_index");
464 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
465 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
467 if(!args_empty
) fprintf(fp
, ", ");
468 if(td
->type
== ARRAY
){
469 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
471 }else if(td
->type
== STRING
){
472 fprintf(fp
,"short int strlength_%d, %s * %s",
473 ++strCount
, getTypeStr(td
), fld
->name
);
475 }else if(td
->type
== SEQUENCE
){
476 fprintf(fp
,"%s seqlength_%d, %s * %s",
477 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
480 fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
485 if(args_empty
) fprintf(fp
, "void");
487 fprintf(fp
,")\n{\n");
489 fprintf(fp
,"#else\n");
491 //trace function : function name and parameters
494 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
498 /* Does it support per trace tracing ? */
500 fprintf(fp
, "struct ltt_trace_struct *dest_trace");
504 /* Does it support per tracefile tracing ? */
505 if(ev
->per_tracefile
) {
506 if(!args_empty
) fprintf(fp
, ", ");
507 fprintf(fp
, "unsigned int tracefile_index");
512 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
513 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
515 if(!args_empty
) fprintf(fp
, ", ");
516 if(td
->type
== ARRAY
){
517 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
519 }else if(td
->type
== STRING
){
520 fprintf(fp
,"short int strlength_%d, %s * %s",
521 ++strCount
, getTypeStr(td
), fld
->name
);
523 }else if(td
->type
== SEQUENCE
){
524 fprintf(fp
,"%s seqlength_%d, %s * %s",
525 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
528 fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
533 if(args_empty
) fprintf(fp
, "void");
535 fprintf(fp
,")\n{\n");
538 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
539 // write directly to the channel
540 fprintf(fp
, "\tunsigned int index;\n");
541 fprintf(fp
, "\tstruct ltt_channel_struct *channel;\n");
542 fprintf(fp
, "\tstruct ltt_trace_struct *trace;\n");
543 fprintf(fp
, "\tvoid *buff;\n");
544 fprintf(fp
, "\tunsigned int slot_size;\n"); // total size (incl hdr)
545 fprintf(fp
, "\tunsigned int data_size;\n"); // Size of the event var data.
546 fprintf(fp
, "\tunsigned int before_hdr_pad;\n");// Dynamic padding before event header
547 fprintf(fp
, "\tunsigned int after_hdr_pad;\n"); // Dynamic padding after event header
548 fprintf(fp
, "\tstruct rchan_buf *buf;\n");
549 fprintf(fp
, "\tstruct timeval delta;\n");
550 fprintf(fp
, "\tu64 tsc;\n");
551 fprintf(fp
, "\tchar *ptr;\n");
554 fprintf(fp
, "\tstruct %s_%s_1* __1;\n\n", ev
->name
, facName
);
556 /* Warning : this is done prior to taking locks :
557 * setting this value must be done at the end of the trace activation.
558 * (we don't care for trace removal, as the list of traces is protected : it
559 * just won't iterate on any trace). */
561 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
563 /* Calculate event variable len + event alignment offset.
564 * Assume that the padding for alignment starts at a void*
566 fprintf(fp
, "\t\tdata_size = 0;\n");
568 for(pos1
=0;pos1
<structCount
;pos1
++){
569 if(ev
->type
->alignment
> 1) {
570 fprintf(fp
,"\t\t\tdata_size += ltt_align(data_size, %u);\n",
571 ev
->type
->alignment
);
573 fprintf(fp
,"\t\t\tdata_size += sizeof(struct %s_%s_%d);\n",
574 ev
->name
,facName
,pos1
+1);
575 // if(pos1 != structCount-1) fprintf(fp," + ");
578 //length of buffer : length of all arrays, sequences and strings
583 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
584 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
586 if(td
->type
== SEQUENCE
|| td
->type
==STRING
|| td
->type
==ARRAY
){
587 if(td
->type
== SEQUENCE
) {
589 if(td
->alignment
> 1) {
590 fprintf(fp
,"\t\t\tdata_size += ltt_align(data_size, %u);\n",
593 fprintf(fp
,"\t\t\tdata_size += sizeof(%s);\n",
594 uintOutputTypes
[td
->size
]);
596 if(td
->alignment
> 1) {
597 fprintf(fp
,"\t\tdata_size += ltt_align(data_size, %u);\n",
600 fprintf(fp
,"\t\tdata_size += sizeof(%s) * seqlength_%d;\n",
601 getTypeStr(td
), seqCount
);
603 } else if(td
->type
==STRING
) {
604 if(td
->alignment
> 1) {
605 fprintf(fp
,"\t\tdata_size += ltt_align(data_size, %u);\n",
609 fprintf(fp
,"\t\tdata_size += strlength_%d + 1;\n",
612 else if(td
->type
==ARRAY
) {
613 if(td
->alignment
> 1) {
614 fprintf(fp
,"\t\tdata_size += ltt_align(data_size, %u);\n",
617 fprintf(fp
,"\t\tdata_size += sizeof(%s) * %d;\n",
618 getTypeStr(td
), td
->size
);
620 if(structCount
== 0) flag
= 1;
625 /* We use preempt_disable instead of rcu_read_lock because we want to
626 * use preempt_enable_no_resched : the only way to be called from the
627 * scheduler code safely! */
628 fprintf(fp
, "\tpreempt_disable();\n\n");
629 fprintf(fp
, "\tltt_nesting[smp_processor_id()]++;\n");
630 fprintf(fp
, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
632 if(ev
->per_tracefile
) {
633 fprintf(fp
, "\tindex = tracefile_index;\n");
636 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
637 "\t\t\t\tevent_%s);\n",
638 facName
, checksum
, ev
->name
);
643 fprintf(fp
, "\tlist_for_each_entry_rcu(trace, <t_traces.head, list) {\n");
644 fprintf(fp
, "\t\tif(!trace->active) continue;\n\n");
647 fprintf(fp
, "\t\tif(dest_trace != trace) continue;\n\n");
649 //length of buffer : length of all structures
650 // if(ev->type == 0) fprintf(fp, "0");
652 fprintf(fp
, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
653 fprintf(fp
, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
658 fprintf(fp
, "\t\tslot_size = 0;\n");
659 fprintf(fp
, "\t\tbuff = ltt_reserve_slot(trace, buf, event_length, &slot_size, &tsc,\n"
660 "\t\t&before_hdr_pad, &after_hdr_pad);\n");
661 /* If error, return */
662 fprintf(fp
, "if(!buff) return;\n");
666 /* Write the header */
667 /* FIXME : delta is not set ! */
669 fprintf(fp
, "\t\tltt_write_event_header(trace, channel, buff, \n"
670 "\t\t\t\tltt_facility_%s_%X, event_%s, data_size, before_hdr_pad,\n"
671 "\t\t\t\t&delta, &tsc);\n",
672 facName
, checksum
, ev
->name
);
676 fprintf(fp
,"\t\tptr = (char*)buff + before_hdr_pad + header_length + after_hdr_pad;\n");
678 /* Write structures */
679 for(pos1
=0;pos1
<structCount
;pos1
++){
680 if(ev
->type
->alignment
> 1) {
681 fprintf(fp
,"\t\tptr += ltt_align((unsigned long)ptr, %u);\n",
682 ev
->type
->alignment
);
684 fprintf(fp
,"\t\t__%d = (struct %s_%s_%d *)(ptr);\n",
685 pos1
+1, ev
->name
,facName
,pos1
+1);
687 fprintf(fp
,"\t\t/* initialize structs */\n");
689 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
690 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
692 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
693 fprintf(fp
, "\t\t__%d->%s = %s;\n", pos1
+1, fld
->name
, fld
->name
);
696 if(structCount
) fprintf(fp
,"\n");
702 //declare a char pointer if needed : starts at the end of the structs.
703 //if(structCount + hasStrSeq > 1) {
704 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
705 // for(pos1=0;pos1<structCount;pos1++){
706 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
708 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
711 // Declare an alias pointer of the struct type to the beginning
712 // of the reserved area, just after the event header.
715 unsigned align
= max(alignment
, td
->alignment
);
717 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
718 align
, align
, align
);
721 fprintf(fp
, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
724 //allocate memory for new struct and initialize it
725 //if(whichTypeFirst == 1){ //struct first
726 //for(pos1=0;pos1<structCount;pos1++){
727 // if(pos1==0) fprintf(fp,
728 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
729 // ev->name, facName,ev->name, facName);
730 //MD disabled else fprintf(fp,
731 // "\tstruct %s_%s_%d __%d;\n",
732 // ev->name, facName,pos1+1,pos1+1);
734 //}else if(whichTypeFirst == 2){
735 // for(pos1=0;pos1<structCount;pos1++)
736 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
737 // ev->name, facName,pos1+1,pos1+1);
741 if(structCount
) fprintf(fp
,"\t\t//initialize structs\n");
745 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
746 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
748 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
752 // if(structCount > 1) fprintf(fp,"\n");
754 fprintf(fp
, "\t\t__1->%s = %s;\n", fld
->name
, fld
->name
);
756 //if(structCount == 1 && whichTypeFirst == 1)
757 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
759 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
763 if(structCount
) fprintf(fp
,"\n");
766 //copy sequence and string to buffer
772 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
773 fld
= (field_t
*)ev
->type
->fields
.array
[pos1
];
775 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
776 // if(flag == 0) structCount++;
778 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
779 // assert(0); // MD : disabled !
780 // fprintf(fp,"\t//copy struct to buffer\n");
781 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
782 // structCount, ev->name, facName,structCount);
783 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
784 // ev->name, facName,structCount);
787 //else if(td->type == SEQUENCE){
788 if(td
->type
== SEQUENCE
){
790 fprintf(fp
,"\t\t//copy sequence length and sequence to buffer\n");
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*ptr = seqlength_%d;\n",++seqCount
);
798 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
800 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
801 align
, align
, align
);
803 fprintf(fp
,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
804 fld
->name
, getTypeStr(td
), seqCount
);
805 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
806 getTypeStr(td
), seqCount
);
808 else if(td
->type
==STRING
){
810 fprintf(fp
,"\t\t//copy string to buffer\n");
811 fprintf(fp
,"\t\tif(strlength_%d > 0){\n",++strCount
);
812 unsigned align
= max(alignment
, td
->alignment
);
814 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
815 align
, align
, align
);
817 fprintf(fp
,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
818 fld
->name
, strCount
);
819 fprintf(fp
,"\t\t\tptr += strlength_%d + 1;\n",strCount
);
820 fprintf(fp
,"\t\t}else{\n");
821 fprintf(fp
,"\t\t\t*ptr = '\\0';\n");
822 fprintf(fp
,"\t\t\tptr += 1;\n");
823 fprintf(fp
,"\t\t}\n\n");
824 }else if(td
->type
==ARRAY
){
826 fprintf(fp
,"\t//copy array to buffer\n");
827 unsigned align
= max(alignment
, td
->alignment
);
829 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
830 align
, align
, align
);
832 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
833 fld
->name
, getTypeStr(td
), td
->size
);
834 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td
), td
->size
);
837 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
843 ltt_commit_slot(buf
, buff
, slot_size
);
849 fprintf(fp
, "\t\tdo {\n");
850 fprintf(fp
, "\t\t\told_offset = buf->offset;\n");
851 fprintf(fp
, "\t\t\tptr = (char*)buf->data + old_offset;\n");
854 fprintf(fp
, "\t\t\theader_length = ltt_get_event_header_data(trace, "
856 "\t\t\t\t\t\t\t\t\t\tptr, &_offset, &delta, &tsc);\n");
858 fprintf(fp
, "\t\t\tptr += _offset + header_length;\n");
860 fprintf(fp
, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
863 fprintf(fp
, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
867 /* Reserve the channel */
868 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
869 fprintf(fp
, "\t\tif(buff == NULL) {\n");
870 fprintf(fp
, "\t\t\t/* Buffer is full*/\n");
871 fprintf(fp
, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
872 fprintf(fp
, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
873 fprintf(fp
, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
874 fprintf(fp
, "\t\t}\n");
877 //fprintf(fp, "\t\tif(resret == 1) {\n");
878 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
879 // facName, checksum, ev->name);
880 //fprintf(fp, "\t\t}\n");
882 //set ptr to the end of first struct if needed;
883 //if(structCount + hasStrSeq > 1){
884 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
885 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
889 fprintf(fp
, "\t\t/* Commit the work */\n");
890 fprintf(fp
, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
891 "\t\t\t\tbuff, event_length);\n");
892 fprintf(fp
, "\t\tltt_write_commit_counter("
893 "channel->rchan->buf[smp_processor_id()],\n"
897 /* End of traces iteration */
898 fprintf(fp
, "\t}\n\n");
902 fprintf(fp
, "unlock:\n");
903 fprintf(fp
, "\tltt_nesting[smp_processor_id()]--;\n");
904 fprintf(fp
, "\tpreempt_enable_no_resched();\n");
905 //fprintf(fp, "\tpreempt_check_resched();\n");
907 //call trace function
908 //fprintf(fp,"\n\t//call trace function\n");
909 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
911 fprintf(fp
, "#endif //CONFIG_LTT\n\n");
916 /*****************************************************************************
918 * getTypeStr : generate type string
920 * td : a type descriptor
922 * char * : type string
923 ****************************************************************************/
924 char * getTypeStr(type_descriptor_t
* td
){
925 type_descriptor_t
* t
;
929 return intOutputTypes
[td
->size
];
931 return uintOutputTypes
[td
->size
];
937 return "unsigned long";
945 return floatOutputTypes
[td
->size
];
949 return uintOutputTypes
[td
->size
];
955 return intOutputTypes
[t
->size
];
957 return uintOutputTypes
[t
->size
];
963 return "unsigned long";
971 return floatOutputTypes
[t
->size
];
975 return uintOutputTypes
[t
->size
];
977 error_callback(NULL
,"Nested struct is not supportted");
981 case STRUCT
: //for now we do not support nested struct
982 error_callback(NULL
,"Nested struct is not supportted");
985 error_callback(NULL
,"No type information");
991 /*****************************************************************************
993 * generateLoaderfile: generate a facility loaded .h file
995 * fp : file to be written to
996 * facName : name of facility
997 * nbEvent : number of events in the facility
998 * checksum : checksum for the facility
999 ****************************************************************************/
1000 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
, char *capname
){
1001 fprintf(fp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname
);
1002 fprintf(fp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname
);
1003 fprintf(fp
,"#include <linux/ltt-facilities.h>\n", facName
, checksum
);
1004 fprintf(fp
,"ltt_facility_t\tltt_facility_%s;\n", facName
, checksum
);
1005 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
1007 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
1009 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
1011 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum
);
1012 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName
);
1013 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent
);
1014 fprintf(fp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname
);
1017 void generateCfile(FILE * fp
, char * filefacname
){
1019 fprintf(fp
, "/*\n");
1020 fprintf(fp
, " * ltt-facility-loader-%s.c\n", filefacname
);
1021 fprintf(fp
, " *\n");
1022 fprintf(fp
, " * (C) Copyright 2005 - \n");
1023 fprintf(fp
, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
1024 fprintf(fp
, " *\n");
1025 fprintf(fp
, " * Contains the LTT facility loader.\n");
1026 fprintf(fp
, " *\n");
1027 fprintf(fp
, " */\n");
1030 fprintf(fp
, "#include <linux/ltt-facilities.h>\n");
1031 fprintf(fp
, "#include <linux/module.h>\n");
1032 fprintf(fp
, "#include <linux/init.h>\n");
1033 fprintf(fp
, "#include <linux/config.h>\n");
1034 fprintf(fp
, "#include \"ltt-facility-loader-%s.h\"\n", filefacname
);
1037 fprintf(fp
, "#ifdef CONFIG_LTT\n");
1039 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
1040 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
1042 fprintf(fp
, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
1044 fprintf(fp
, "#define SYMBOL_STRING(sym) #sym\n");
1046 fprintf(fp
, "static struct ltt_facility facility = {\n");
1047 fprintf(fp
, "\t.name = ltt_facility_name,\n");
1048 fprintf(fp
, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
1049 fprintf(fp
, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
1050 fprintf(fp
, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
1051 fprintf(fp
, "\t.alignment = %u\n", alignment
); /* default alignment */
1052 fprintf(fp
, "};\n");
1054 fprintf(fp
, "#ifndef MODULE\n");
1056 fprintf(fp
, "/* Built-in facility. */\n");
1058 fprintf(fp
, "static int __init facility_init(void)\n");
1060 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname
);
1062 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
1063 fprintf(fp
, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1064 fprintf(fp
, "\t\n");
1065 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
1067 fprintf(fp
, "__initcall(facility_init);\n");
1071 fprintf(fp
, "#else \n");
1073 fprintf(fp
, "/* Dynamic facility. */\n");
1075 fprintf(fp
, "static int __init facility_init(void)\n");
1077 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname
);
1079 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
1080 fprintf(fp
, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1082 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
1085 fprintf(fp
, "static void __exit facility_exit(void)\n");
1087 fprintf(fp
, "\tint err;\n");
1089 fprintf(fp
, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
1090 fprintf(fp
, "\tif(err != 0)\n");
1091 fprintf(fp
, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
1095 fprintf(fp
, "module_init(facility_init)\n");
1096 fprintf(fp
, "module_exit(facility_exit)\n");
1099 fprintf(fp
, "MODULE_LICENSE(\"GPL\");\n");
1100 fprintf(fp
, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1101 fprintf(fp
, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1103 fprintf(fp
, "#endif //MODULE\n");
1105 fprintf(fp
, "#endif //CONFIG_LTT\n");
This page took 0.074302 seconds and 4 git commands to generate.