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
||
305 fprintf(fp
,"struct %s_%s",name
, facName
);
307 fprintf(fp
, "_%d {\n",++*structCount
);
312 fprintf(fp
, "\t%s %s; /* %s */\n",
313 getTypeStr(td
),fld
->name
,fld
->description
);
318 unsigned align
= max(alignment
, type
->alignment
);
321 fprintf(fp
,"} __attribute__ ((packed));\n\n");
323 if(align
!= 1 && align
!= 2
324 && align
!= 4 && align
!= 8) {
325 printf("Wrong alignment %i, using packed.\n", align
);
326 fprintf(fp
,"} __attribute__ ((packed));\n\n");
328 fprintf(fp
,"} __attribute__ ((aligned(%i)));\n\n", align
);
334 /*****************************************************************************
336 * generateHfile : Create the typedefs
338 * fp : file to be written to
339 ****************************************************************************/
341 generateTypeDefs(FILE * fp
, char *facName
)
345 fprintf(fp
,"#include <linux/types.h>\n");
346 fprintf(fp
,"#include <linux/spinlock.h>\n");
347 fprintf(fp
,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName
);
348 fprintf(fp
,"#include <linux/ltt-core.h>\n");
351 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
353 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
354 type_descriptor
* type
=
355 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
356 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
357 "", type
->type_name
, &tmp
, &tmp
, NULL
);
358 fprintf(fp
, "typedef struct _%s %s;\n\n",
359 type
->type_name
, type
->type_name
);
365 /*****************************************************************************
367 * generateEnumDefinition: generate enum definition if it exists
369 * fp : file to be written to
371 ****************************************************************************/
372 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
375 if(type
->already_printed
) return;
377 fprintf(fp
,"enum {\n");
378 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
379 fprintf(fp
,"\tLTT_ENUM_%s", type
->labels
.array
[pos
]);
380 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",");
381 if(type
->labels_description
.array
[pos
] != NULL
)
382 fprintf(fp
,"\t/* %s */\n",type
->labels_description
.array
[pos
]);
386 fprintf(fp
,"};\n\n\n");
388 type
->already_printed
= 1;
391 /*****************************************************************************
393 * generateStrucTFunc: output structure and function to .h file
395 * fp : file to be written to
396 * facName : name of facility
397 ****************************************************************************/
398 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
401 type_descriptor
* td
;
403 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
406 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
407 ev
= (event
*) fac
->events
.array
[pos
];
408 //yxx if(ev->nested)continue;
409 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",
411 //if(ev->type == 0){ // event without type
412 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
413 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
414 // facName,checksum,ev->name);
415 // fprintf(fp,"};\n\n\n");
419 //if fields contain enum, print out enum definition
420 //MD : fixed in generateEnumDefinition to do not print the same enum
423 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
424 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
425 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
428 //default: no string, array or sequence in the event
433 //structure for kernel
435 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
436 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
,
440 //trace function : function name and parameters : stub function.
443 fprintf(fp
, "#ifndef CONFIG_LTT\n");
444 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
448 /* Does it support per trace tracing ? */
450 fprintf(fp
, "struct ltt_trace_struct *dest_trace");
454 /* Does it support per tracefile tracing ? */
455 if(ev
->per_tracefile
) {
456 if(!args_empty
) fprintf(fp
, ", ");
457 fprintf(fp
, "unsigned int tracefile_index");
462 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
463 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
465 if(!args_empty
) fprintf(fp
, ", ");
466 if(td
->type
== ARRAY
){
467 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
469 }else if(td
->type
== STRING
){
470 fprintf(fp
,"short int strlength_%d, %s * %s",
471 ++strCount
, getTypeStr(td
), fld
->name
);
473 }else if(td
->type
== SEQUENCE
){
474 fprintf(fp
,"%s seqlength_%d, %s * %s",
475 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
478 fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
483 if(args_empty
) fprintf(fp
, "void");
485 fprintf(fp
,")\n{\n");
487 fprintf(fp
,"#else\n");
489 //trace function : function name and parameters
492 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
496 /* Does it support per trace tracing ? */
498 fprintf(fp
, "struct ltt_trace_struct *dest_trace");
502 /* Does it support per tracefile tracing ? */
503 if(ev
->per_tracefile
) {
504 if(!args_empty
) fprintf(fp
, ", ");
505 fprintf(fp
, "unsigned int tracefile_index");
510 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
511 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
513 if(!args_empty
) fprintf(fp
, ", ");
514 if(td
->type
== ARRAY
){
515 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
517 }else if(td
->type
== STRING
){
518 fprintf(fp
,"short int strlength_%d, %s * %s",
519 ++strCount
, getTypeStr(td
), fld
->name
);
521 }else if(td
->type
== SEQUENCE
){
522 fprintf(fp
,"%s seqlength_%d, %s * %s",
523 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
526 fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
531 if(args_empty
) fprintf(fp
, "void");
533 fprintf(fp
,")\n{\n");
536 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
537 // write directly to the channel
538 fprintf(fp
, "\tunsigned int index;\n");
539 fprintf(fp
, "\tstruct ltt_channel_struct *channel;\n");
540 fprintf(fp
, "\tstruct ltt_trace_struct *trace;\n");
541 fprintf(fp
, "\tunsigned long _flags;\n");
542 fprintf(fp
, "\tvoid *buff;\n");
543 fprintf(fp
, "\tunsigned old_offset;\n");
544 fprintf(fp
, "\tunsigned int header_length;\n");
545 fprintf(fp
, "\tunsigned int event_length;\n"); // total size (incl hdr)
546 fprintf(fp
, "\tunsigned int length;\n"); // Size of the event var data.
547 fprintf(fp
, "\tunsigned char _offset;\n");
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 fprintf(fp
, "\t/* Disable interrupts. */\n");
564 fprintf(fp
, "\tlocal_irq_save(_flags);\n");
565 fprintf(fp
, "\tpreempt_disable();\n\n");
567 fprintf(fp
, "\tltt_nesting[smp_processor_id()]++;\n");
568 fprintf(fp
, "\tbarrier();\n");
569 fprintf(fp
, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
570 fprintf(fp
, "\tspin_lock(<t_traces.locks[smp_processor_id()]);\n\n");
572 if(ev
->per_tracefile
) {
573 fprintf(fp
, "\tindex = tracefile_index;\n");
576 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
577 "\t\t\t\tevent_%s);\n",
578 facName
, checksum
, ev
->name
);
583 fprintf(fp
, "\tlist_for_each_entry(trace, <t_traces.head, list) {\n");
584 fprintf(fp
, "\t\tif(!trace->active) continue;\n\n");
587 fprintf(fp
, "\t\tif(dest_trace != trace) continue;\n\n");
589 //length of buffer : length of all structures
590 // if(ev->type == 0) fprintf(fp, "0");
592 fprintf(fp
, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
593 fprintf(fp
, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
595 /* Warning : not atomic reservation : event size depends on the current
596 * address for alignment */
597 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
599 /* NOTE2 : as the read old address from memory must come before any
600 * protected event, let's add a memory barrier() to make sure the compiler
601 * will not reorder this read. */
602 fprintf(fp
, "\t\tdo {\n");
603 fprintf(fp
, "\t\t\told_offset = buf->offset;\n");
604 fprintf(fp
, "\t\t\tbarrier();\n");
605 fprintf(fp
, "\t\t\tptr = (char*)buf->data + old_offset;\n");
608 fprintf(fp
, "\t\t\theader_length = ltt_get_event_header_data(trace, "
610 "\t\t\t\t\t\t\t\t\t\tptr, &_offset, &delta, &tsc);\n");
612 fprintf(fp
, "\t\t\tptr += _offset + header_length;\n");
614 for(pos1
=0;pos1
<structCount
;pos1
++){
616 unsigned align
= max(alignment
, ev
->type
->alignment
);
618 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
619 align
, align
, align
);
621 fprintf(fp
,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev
->name
,
623 // if(pos1 != structCount-1) fprintf(fp," + ");
626 //length of buffer : length of all arrays, sequences and strings
631 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
632 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
634 if(td
->type
== SEQUENCE
|| td
->type
==STRING
|| td
->type
==ARRAY
){
635 if(td
->type
== SEQUENCE
) {
637 unsigned align
= max(alignment
, td
->alignment
);
639 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
640 align
, align
, align
);
642 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
644 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
645 align
, align
, align
);
647 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
648 getTypeStr(td
), seqCount
);
650 } else if(td
->type
==STRING
) {
651 unsigned align
= max(alignment
, td
->alignment
);
653 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
654 align
, align
, align
);
656 fprintf(fp
,"ptr += strlength_%d + 1;\n",
659 else if(td
->type
==ARRAY
) {
660 unsigned align
= max(alignment
, td
->alignment
);
662 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
663 align
, align
, align
);
665 fprintf(fp
,"\t\t\tptr += sizeof(%s) * %d;\n",
666 getTypeStr(td
),td
->size
);
667 if(structCount
== 0) flag
= 1;
671 fprintf(fp
, "\t\t\tevent_length = (unsigned long)ptr -"
672 "(unsigned long)(buf->data + old_offset);\n");
674 /* let's put some protection before the cmpxchg : the space reservation and
675 * the get TSC are not dependant from each other. I don't want the compiler
676 * to reorder those in the wrong order. And relay_reserve is inline, so
677 * _yes_, the compiler could mess it up. */
678 fprintf(fp
, "\t\t\tbarrier();\n");
679 fprintf(fp
, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
682 fprintf(fp
, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
686 /* Reserve the channel */
687 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
688 fprintf(fp
, "\t\tif(buff == NULL) {\n");
689 fprintf(fp
, "\t\t\t/* Buffer is full*/\n");
690 fprintf(fp
, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
691 fprintf(fp
, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
692 fprintf(fp
, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
693 fprintf(fp
, "\t\t}\n");
696 //fprintf(fp, "\t\tif(resret == 1) {\n");
697 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
698 // facName, checksum, ev->name);
699 //fprintf(fp, "\t\t}\n");
701 /* Write the header */
703 fprintf(fp
,"\t\tlength = event_length - _offset - header_length;\n");
705 fprintf(fp
, "\t\tltt_write_event_header(trace, channel, buff, \n"
706 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
707 "\t\t\t\t&delta, &tsc);\n",
708 facName
, checksum
, ev
->name
);
712 fprintf(fp
, "\t\tptr = (char*)buff + _offset + header_length;\n");
714 //copy struct, sequence and string to buffer
715 //FIXME : they always come before the structs.
721 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
722 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
724 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
725 // if(flag == 0) structCount++;
727 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
728 // assert(0); // MD : disabled !
729 // fprintf(fp,"\t//copy struct to buffer\n");
730 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
731 // structCount, ev->name, facName,structCount);
732 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
733 // ev->name, facName,structCount);
736 //else if(td->type == SEQUENCE){
737 if(td
->type
== SEQUENCE
){
739 fprintf(fp
,"\t\t//copy sequence length and sequence to buffer\n");
741 unsigned align
= max(alignment
, td
->alignment
);
743 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
744 align
, align
, align
);
746 fprintf(fp
,"\t\t*ptr = seqlength_%d;\n",++seqCount
);
747 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
749 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
750 align
, align
, align
);
752 fprintf(fp
,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
753 fld
->name
, getTypeStr(td
), seqCount
);
754 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
755 getTypeStr(td
), seqCount
);
757 else if(td
->type
==STRING
){
759 fprintf(fp
,"\t\t//copy string to buffer\n");
760 fprintf(fp
,"\t\tif(strlength_%d > 0){\n",++strCount
);
761 unsigned align
= max(alignment
, td
->alignment
);
763 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
764 align
, align
, align
);
766 fprintf(fp
,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
767 fld
->name
, strCount
);
768 fprintf(fp
,"\t\t\tptr += strlength_%d + 1;\n",strCount
);
769 fprintf(fp
,"\t\t}else{\n");
770 fprintf(fp
,"\t\t\t*ptr = '\\0';\n");
771 fprintf(fp
,"\t\t\tptr += 1;\n");
772 fprintf(fp
,"\t\t}\n\n");
773 }else if(td
->type
==ARRAY
){
775 fprintf(fp
,"\t//copy array to buffer\n");
776 unsigned align
= max(alignment
, td
->alignment
);
778 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
779 align
, align
, align
);
781 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
782 fld
->name
, getTypeStr(td
), td
->size
);
783 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td
), td
->size
);
786 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
791 //declare a char pointer if needed : starts at the end of the structs.
792 //if(structCount + hasStrSeq > 1) {
793 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
794 // for(pos1=0;pos1<structCount;pos1++){
795 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
797 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
800 // Declare an alias pointer of the struct type to the beginning
801 // of the reserved area, just after the event header.
803 unsigned align
= max(alignment
, td
->alignment
);
805 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
806 align
, align
, align
);
809 fprintf(fp
, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
812 //allocate memory for new struct and initialize it
813 //if(whichTypeFirst == 1){ //struct first
814 //for(pos1=0;pos1<structCount;pos1++){
815 // if(pos1==0) fprintf(fp,
816 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
817 // ev->name, facName,ev->name, facName);
818 //MD disabled else fprintf(fp,
819 // "\tstruct %s_%s_%d __%d;\n",
820 // ev->name, facName,pos1+1,pos1+1);
822 //}else if(whichTypeFirst == 2){
823 // for(pos1=0;pos1<structCount;pos1++)
824 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
825 // ev->name, facName,pos1+1,pos1+1);
829 if(structCount
) fprintf(fp
,"\t\t//initialize structs\n");
833 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
834 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
836 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
840 // if(structCount > 1) fprintf(fp,"\n");
842 fprintf(fp
, "\t\t__1->%s = %s;\n", fld
->name
, fld
->name
);
844 //if(structCount == 1 && whichTypeFirst == 1)
845 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
847 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
851 if(structCount
) fprintf(fp
,"\n");
852 //set ptr to the end of first struct if needed;
853 //if(structCount + hasStrSeq > 1){
854 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
855 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
859 fprintf(fp
, "\t\t/* Commit the work */\n");
860 fprintf(fp
, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
861 "\t\t\t\tbuff, event_length);\n");
862 fprintf(fp
, "\t\tltt_write_commit_counter("
863 "channel->rchan->buf[smp_processor_id()],\n"
866 /* End of traces iteration */
867 fprintf(fp
, "\t}\n\n");
870 // The generated preempt_check_resched is not dangerous because
871 // interrupts are disabled.
872 fprintf(fp
, "\tspin_unlock(<t_traces.locks[smp_processor_id()]);\n");
874 fprintf(fp
, "unlock:\n");
875 fprintf(fp
, "\tbarrier();\n");
876 fprintf(fp
, "\tltt_nesting[smp_processor_id()]--;\n");
877 fprintf(fp
, "\t/* Re-enable interrupts */\n");
878 fprintf(fp
, "\tlocal_irq_restore(_flags);\n");
879 fprintf(fp
, "\tpreempt_enable_no_resched();\n");
880 //fprintf(fp, "\tpreempt_check_resched();\n");
882 //call trace function
883 //fprintf(fp,"\n\t//call trace function\n");
884 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
886 fprintf(fp
, "#endif //CONFIG_LTT\n\n");
891 /*****************************************************************************
893 * getTypeStr : generate type string
895 * td : a type descriptor
897 * char * : type string
898 ****************************************************************************/
899 char * getTypeStr(type_descriptor
* td
){
900 type_descriptor
* t
;
904 return intOutputTypes
[td
->size
];
906 return uintOutputTypes
[td
->size
];
912 return "unsigned long";
920 return floatOutputTypes
[td
->size
];
924 return uintOutputTypes
[td
->size
];
930 return intOutputTypes
[t
->size
];
932 return uintOutputTypes
[t
->size
];
938 return "unsigned long";
946 return floatOutputTypes
[t
->size
];
950 return uintOutputTypes
[t
->size
];
952 error_callback(NULL
,"Nested struct is not supportted");
956 case STRUCT
: //for now we do not support nested struct
957 error_callback(NULL
,"Nested struct is not supportted");
960 error_callback(NULL
,"No type information");
966 /*****************************************************************************
968 * generateLoaderfile: generate a facility loaded .h file
970 * fp : file to be written to
971 * facName : name of facility
972 * nbEvent : number of events in the facility
973 * checksum : checksum for the facility
974 ****************************************************************************/
975 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
, char *capname
){
976 fprintf(fp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname
);
977 fprintf(fp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname
);
978 fprintf(fp
,"#include <linux/ltt-facilities.h>\n", facName
, checksum
);
979 fprintf(fp
,"ltt_facility_t\tltt_facility_%s;\n", facName
, checksum
);
980 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
982 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
984 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
986 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum
);
987 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName
);
988 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent
);
989 fprintf(fp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname
);
992 void generateCfile(FILE * fp
, char * filefacname
){
995 fprintf(fp
, " * ltt-facility-loader-%s.c\n", filefacname
);
997 fprintf(fp
, " * (C) Copyright 2005 - \n");
998 fprintf(fp
, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
1000 fprintf(fp
, " * Contains the LTT facility loader.\n");
1001 fprintf(fp
, " *\n");
1002 fprintf(fp
, " */\n");
1005 fprintf(fp
, "#include <linux/ltt-facilities.h>\n");
1006 fprintf(fp
, "#include <linux/module.h>\n");
1007 fprintf(fp
, "#include <linux/init.h>\n");
1008 fprintf(fp
, "#include <linux/config.h>\n");
1009 fprintf(fp
, "#include \"ltt-facility-loader-%s.h\"\n", filefacname
);
1012 fprintf(fp
, "#ifdef CONFIG_LTT\n");
1014 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
1015 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
1017 fprintf(fp
, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
1019 fprintf(fp
, "#define SYMBOL_STRING(sym) #sym\n");
1021 fprintf(fp
, "static struct ltt_facility facility = {\n");
1022 fprintf(fp
, "\t.name = ltt_facility_name,\n");
1023 fprintf(fp
, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
1024 fprintf(fp
, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
1025 fprintf(fp
, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
1026 fprintf(fp
, "\t.alignment = %u\n", alignment
); /* default alignment */
1027 fprintf(fp
, "};\n");
1029 fprintf(fp
, "#ifndef MODULE\n");
1031 fprintf(fp
, "/* Built-in facility. */\n");
1033 fprintf(fp
, "static int __init facility_init(void)\n");
1035 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname
);
1037 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
1038 fprintf(fp
, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1039 fprintf(fp
, "\t\n");
1040 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
1042 fprintf(fp
, "__initcall(facility_init);\n");
1046 fprintf(fp
, "#else \n");
1048 fprintf(fp
, "/* Dynamic facility. */\n");
1050 fprintf(fp
, "static int __init facility_init(void)\n");
1052 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname
);
1054 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
1055 fprintf(fp
, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
1057 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
1060 fprintf(fp
, "static void __exit facility_exit(void)\n");
1062 fprintf(fp
, "\tint err;\n");
1064 fprintf(fp
, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
1065 fprintf(fp
, "\tif(err != 0)\n");
1066 fprintf(fp
, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
1070 fprintf(fp
, "module_init(facility_init)\n");
1071 fprintf(fp
, "module_exit(facility_exit)\n");
1074 fprintf(fp
, "MODULE_LICENSE(\"GPL\");\n");
1075 fprintf(fp
, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1076 fprintf(fp
, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1078 fprintf(fp
, "#endif //MODULE\n");
1080 fprintf(fp
, "#endif //CONFIG_LTT\n");
This page took 0.191092 seconds and 4 git commands to generate.