62db1274f173941dd20ff4065b0127f0e58a1283
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 /* Named types may be referenced from anywhere */
52 int main(int argc
, char** argv
)
56 char buffer
[BUFFER_SIZE
];
60 printf("At least one event definition file is needed\n");
65 in
.error
= error_callback
;
67 for(i
= 1 ; i
< argc
; i
++) {
69 in
.name
= allocAndCopy(argv
[i
]);
71 in
.fp
= fopen(in
.name
, "r");
73 in
.error(&in
,"cannot open facility input file");
77 token
= getToken(&in
);
78 if(in
.type
== ENDFILE
) break;
80 if(strcmp(token
, "<")) in
.error(&in
,"not a facility file");
83 if(strcmp("facility",token
) == 0) {
84 fac
= memAlloc(sizeof(facility
));
86 fac
->description
= NULL
;
87 sequence_init(&(fac
->events
));
88 table_init(&(fac
->named_types
));
89 sequence_init(&(fac
->unnamed_types
));
91 parseFacility(&in
, fac
);
93 //check if any namedType is not defined
94 checkNamedTypesImplemented(&fac
->named_types
);
96 else in
.error(&in
,"facility token was expected");
98 generateFile(argv
[i
]);
101 free(fac
->description
);
102 freeEvents(&fac
->events
);
103 sequence_dispose(&fac
->events
);
104 freeNamedType(&fac
->named_types
);
105 table_dispose(&fac
->named_types
);
106 freeTypes(&fac
->unnamed_types
);
107 sequence_dispose(&fac
->unnamed_types
);
119 /*****************************************************************************
121 * generateFile : generate .c and .h file
123 * name : name of event definition file
124 ****************************************************************************/
125 void generateFile(char *name
){
126 char *loadName
, *hName
, *hIdName
, *cName
, *tmp
, *tmp2
;
127 FILE * lFp
, *hFp
, *iFp
, *cFp
;
129 unsigned long checksum
=0;
131 //remove .xml if it exists
132 tmp
= &name
[strlen(name
)-4];
133 if(strcmp(tmp
, ".xml") == 0){
137 tmp
= strrchr(name
,'/');
144 loadName
= appendString("ltt-facility-loader-", tmp
);
145 tmp2
= appendString(loadName
,".h");
148 hName
= appendString("ltt-facility-", tmp
);
149 tmp2
= appendString(hName
,".h");
152 hIdName
= appendString("ltt-facility-id-", tmp
);
153 tmp2
= appendString(hIdName
,".h");
156 cName
= appendString("ltt-facility-loader-", tmp
);
157 tmp2
= appendString(cName
,".c");
160 lFp
= fopen(loadName
,"w");
162 printf("Cannot open the file : %s\n",loadName
);
166 hFp
= fopen(hName
,"w");
168 printf("Cannot open the file : %s\n",hName
);
172 iFp
= fopen(hIdName
,"w");
174 printf("Cannot open the file : %s\n",hIdName
);
178 cFp
= fopen(cName
,"w");
180 printf("Cannot open the file : %s\n",cName
);
189 generateChecksum(fac
->name
, &checksum
, &(fac
->events
));
191 /* generate .h file, event enumeration then structures and functions */
192 fprintf(iFp
, "#ifndef _LTT_FACILITY_ID_%s_H_\n",fac
->capname
);
193 fprintf(iFp
, "#define _LTT_FACILITY_ID_%s_H_\n\n",fac
->capname
);
194 fprintf(iFp
, "#ifdef CONFIG_LTT\n");
195 generateEnumEvent(iFp
, fac
->name
, &nbEvent
, checksum
);
196 fprintf(iFp
, "#endif //CONFIG_LTT\n");
197 fprintf(iFp
, "#endif //_LTT_FACILITY_ID_%s_H_\n",fac
->capname
);
200 fprintf(hFp
, "#ifndef _LTT_FACILITY_%s_H_\n",fac
->capname
);
201 fprintf(hFp
, "#define _LTT_FACILITY_%s_H_\n\n",fac
->capname
);
202 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
203 generateTypeDefs(hFp
, fac
->name
);
204 generateStructFunc(hFp
, fac
->name
,checksum
);
205 //fprintf(hFp, "#endif //CONFIG_LTT\n");
206 fprintf(hFp
, "#endif //_LTT_FACILITY_%s_H_\n",fac
->capname
);
208 /* generate .h file, calls to register the facility at init time */
209 generateLoaderfile(lFp
,fac
->name
,nbEvent
,checksum
,fac
->capname
);
211 // create ltt-facility-loader-facname.c
212 generateCfile(cFp
, tmp
);
222 /*****************************************************************************
224 * generateEnumEvent : output event enum to .h file
226 * fp : file to be written to
227 * facName : name of facility
229 * nbEvent : number of events in the facility
230 ****************************************************************************/
231 void generateEnumEvent(FILE *fp
, char *facName
, int * nbEvent
, unsigned long checksum
) {
234 fprintf(fp
,"#include <linux/ltt-facilities.h>\n\n");
236 fprintf(fp
,"/**** facility handle ****/\n\n");
237 fprintf(fp
,"extern ltt_facility_t ltt_facility_%s_%X;\n",facName
, checksum
);
238 fprintf(fp
,"extern ltt_facility_t ltt_facility_%s;\n\n\n",facName
, checksum
);
240 fprintf(fp
,"/**** event type ****/\n\n");
241 fprintf(fp
,"enum %s_event {\n",facName
);
243 for(pos
= 0; pos
< fac
->events
.position
;pos
++) {
244 fprintf(fp
,"\tevent_%s", ((event
*)(fac
->events
.array
[pos
]))->name
);
245 if(pos
!= fac
->events
.position
-1) fprintf(fp
,",\n");
247 fprintf(fp
,"\n};\n\n\n");
249 // fprintf(fp,"/**** number of events in the facility ****/\n\n");
250 // fprintf(fp,"int nbEvents_%s = %d;\n\n\n",facName, fac->events.position);
251 *nbEvent
= fac
->events
.position
;
255 /*****************************************************************************
257 * printStruct : Generic struct printing function
259 * fp : file to be written to
260 * len : number of fields
261 * array : array of field info
262 * name : basic struct name
263 * facName : name of facility
264 * whichTypeFirst : struct or array/sequence first
265 * hasStrSeq : string or sequence present?
266 * structCount : struct postfix
267 ****************************************************************************/
270 printStruct(FILE * fp
, int len
, void ** array
, char * name
, char * facName
,
271 int * whichTypeFirst
, int * hasStrSeq
, int * structCount
,
272 type_descriptor
*type
)
277 type_descriptor
* td
;
279 for (pos
= 0; pos
< len
; pos
++) {
280 fld
= (field
*)array
[pos
];
282 if( td
->type
== STRING
|| td
->type
== SEQUENCE
||
286 // if (*whichTypeFirst == 0) {
287 // *whichTypeFirst = 1; //struct first
292 fprintf(fp
,"struct %s_%s",name
, facName
);
294 fprintf(fp
, "_%d {\n",++*structCount
);
299 fprintf(fp
, "\t%s %s; /* %s */\n",
300 getTypeStr(td
),fld
->name
,fld
->description
);
303 if (*whichTypeFirst
== 0) {
304 //string or sequence or array first
309 fprintf(fp
,"} __attribute__ ((packed));\n\n");
317 if(type
->alignment
== 0)
318 fprintf(fp
,"} __attribute__ ((packed));\n\n");
320 if(type
->alignment
!= 1 && type
->alignment
!= 2
321 && type
->alignment
!= 4 && type
->alignment
!= 8) {
322 printf("Wrong alignment %i, using packed.\n", type
->alignment
);
323 fprintf(fp
,"} __attribute__ ((packed));\n\n");
325 fprintf(fp
,"} __attribute__ ((aligned(%i)));\n\n", type
->alignment
);
331 /*****************************************************************************
333 * generateHfile : Create the typedefs
335 * fp : file to be written to
336 ****************************************************************************/
338 generateTypeDefs(FILE * fp
, char *facName
)
342 fprintf(fp
,"#include <linux/types.h>\n");
343 fprintf(fp
,"#include <linux/spinlock.h>\n");
344 fprintf(fp
,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName
);
345 fprintf(fp
,"#include <linux/ltt-core.h>\n");
348 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
350 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
351 type_descriptor
* type
=
352 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
353 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
354 "", type
->type_name
, &tmp
, &tmp
, NULL
);
355 fprintf(fp
, "typedef struct _%s %s;\n\n",
356 type
->type_name
, type
->type_name
);
362 /*****************************************************************************
364 * generateEnumDefinition: generate enum definition if it exists
366 * fp : file to be written to
368 ****************************************************************************/
369 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
372 if(type
->already_printed
) return;
374 fprintf(fp
,"enum {\n");
375 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
376 fprintf(fp
,"\tLTT_ENUM_%s", type
->labels
.array
[pos
]);
377 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",");
378 if(type
->labels_description
.array
[pos
] != NULL
)
379 fprintf(fp
,"\t/* %s */\n",type
->labels_description
.array
[pos
]);
383 fprintf(fp
,"};\n\n\n");
385 type
->already_printed
= 1;
388 /*****************************************************************************
390 * generateStrucTFunc: output structure and function to .h file
392 * fp : file to be written to
393 * facName : name of facility
394 ****************************************************************************/
395 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
398 type_descriptor
* td
;
400 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
402 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
403 ev
= (event
*) fac
->events
.array
[pos
];
404 //yxx if(ev->nested)continue;
405 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",
407 //if(ev->type == 0){ // event without type
408 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
409 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
410 // facName,checksum,ev->name);
411 // fprintf(fp,"};\n\n\n");
415 //if fields contain enum, print out enum definition
416 //MD : fixed in generateEnumDefinition to do not print the same enum
419 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
420 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
421 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
424 //default: no string, array or sequence in the event
429 //structure for kernel
431 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
432 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
,
436 //trace function : function name and parameters : stub function.
439 fprintf(fp
, "#ifndef CONFIG_LTT\n");
440 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
444 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
445 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
447 if(td
->type
== ARRAY
){
448 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
449 }else if(td
->type
== STRING
){
450 fprintf(fp
,"short int strlength_%d, %s * %s",
451 ++strCount
, getTypeStr(td
), fld
->name
);
452 }else if(td
->type
== SEQUENCE
){
453 fprintf(fp
,"%s seqlength_%d, %s * %s",
454 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
455 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
456 if(pos1
!= ev
->type
->fields
.position
- 1) fprintf(fp
,", ");
458 fprintf(fp
,")\n{\n");
460 fprintf(fp
,"#else\n");
462 //trace function : function name and parameters
465 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
469 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
470 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
472 if(td
->type
== ARRAY
){
473 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
474 }else if(td
->type
== STRING
){
475 fprintf(fp
,"short int strlength_%d, %s * %s",
476 ++strCount
, getTypeStr(td
), fld
->name
);
477 }else if(td
->type
== SEQUENCE
){
478 fprintf(fp
,"%s seqlength_%d, %s * %s",
479 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
480 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
481 if(pos1
!= ev
->type
->fields
.position
- 1) fprintf(fp
,", ");
483 fprintf(fp
,")\n{\n");
488 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
489 // write directly to the channel
490 fprintf(fp
, "\tunsigned int index;\n");
491 fprintf(fp
, "\tstruct ltt_channel_struct *channel;\n");
492 fprintf(fp
, "\tstruct ltt_trace_struct *trace;\n");
493 fprintf(fp
, "\tunsigned long _flags;\n");
494 fprintf(fp
, "\tvoid *buff;\n");
495 fprintf(fp
, "\tvoid *old_address;\n");
496 fprintf(fp
, "\tunsigned int header_length;\n");
497 fprintf(fp
, "\tunsigned int event_length;\n"); // total size (incl hdr)
498 fprintf(fp
, "\tunsigned int length;\n"); // Size of the event var data.
499 fprintf(fp
, "\tunsigned char _offset;\n");
500 fprintf(fp
, "\tstruct rchan_buf *buf;\n");
501 fprintf(fp
, "\tstruct timeval delta;\n");
502 fprintf(fp
, "\tu64 tsc;\n");
505 fprintf(fp
, "\tstruct %s_%s_1* __1;\n\n", ev
->name
, facName
);
507 /* Warning : this is done prior to taking locks :
508 * setting this value must be done at the end of the trace activation.
509 * (we don't care for trace removal, as the list of traces is protected : it
510 * just won't iterate on any trace). */
512 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
514 fprintf(fp
, "\t/* Disable interrupts. */\n");
515 fprintf(fp
, "\tlocal_irq_save(_flags);\n");
516 fprintf(fp
, "\tpreempt_disable();\n\n");
518 fprintf(fp
, "\tltt_nesting[smp_processor_id()]++;\n");
519 fprintf(fp
, "\tbarrier();\n");
520 fprintf(fp
, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
521 fprintf(fp
, "\tspin_lock(<t_traces.locks[smp_processor_id()]);\n\n");
524 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
525 "\t\t\t\tevent_%s);\n",
526 facName
, checksum
, ev
->name
);
530 fprintf(fp
, "\tlist_for_each_entry(trace, <t_traces.head, list) {\n");
531 fprintf(fp
, "\t\tif(!trace->active) continue;\n\n");
533 //length of buffer : length of all structures
534 // if(ev->type == 0) fprintf(fp, "0");
536 fprintf(fp
, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
537 fprintf(fp
, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
539 /* Warning : not atomic reservation : event size depends on the current
540 * address for alignment */
541 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
543 /* NOTE2 : as the read old address from memory must come before any
544 * protected event, let's add a memory barrier() to make sure the compiler
545 * will not reorder this read. */
546 fprintf(fp
, "\t\tdo {\n");
547 fprintf(fp
, "\t\t\told_address = buf->data + buf->offset;\n");
548 fprintf(fp
, "\t\t\tbarrier();\n");
549 fprintf(fp
, "\t\t\tchar *ptr = (char*)old_address;\n");
552 fprintf(fp
, "\t\t\theader_length = ltt_get_event_header_data(trace, "
554 "\t\t\t\t\t\t\t\t\t\told_address, &_offset, &delta, &tsc);\n");
556 fprintf(fp
, "\t\t\tptr += _offset + header_length;\n");
558 for(pos1
=0;pos1
<structCount
;pos1
++){
560 if(ev
->type
->alignment
> 1) {
561 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
562 ev
->type
->alignment
, ev
->type
->alignment
, ev
->type
->alignment
);
564 fprintf(fp
,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev
->name
,
566 // if(pos1 != structCount-1) fprintf(fp," + ");
569 //length of buffer : length of all arrays, sequences and strings
574 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
575 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
577 if(td
->type
== SEQUENCE
|| td
->type
==STRING
|| td
->type
==ARRAY
){
578 if(td
->type
== SEQUENCE
) {
579 if(td
->alignment
> 1) {
580 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
581 td
->alignment
, td
->alignment
, td
->alignment
);
584 "\t\t\tptr += sizeof(%s) + (sizeof(%s) * seqlength_%d);\n",
585 uintOutputTypes
[td
->size
], getTypeStr(td
), ++seqCount
);
586 } else if(td
->type
==STRING
) {
587 if(td
->alignment
> 1) {
588 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
589 td
->alignment
, td
->alignment
, td
->alignment
);
591 fprintf(fp
,"ptr += strlength_%d + 1;\n",
594 else if(td
->type
==ARRAY
) {
595 if(td
->alignment
> 1) {
596 fprintf(fp
,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
597 td
->alignment
, td
->alignment
, td
->alignment
);
599 fprintf(fp
,"\t\t\tptr += sizeof(%s) * %d;\n",
600 getTypeStr(td
),td
->size
);
601 if(structCount
== 0) flag
= 1;
607 fprintf(fp
, "\t\t\tevent_length = (unsigned long)ptr -"
608 "(unsigned long)old_address;\n");
610 /* let's put some protection before the cmpxchg : the space reservation and
611 * the get TSC are not dependant from each other. I don't want the compiler
612 * to reorder those in the wrong order. And relay_reserve is inline, so
613 * _yes_, the compiler could mess it up. */
614 fprintf(fp
, "\t\t\tbarrier();\n");
615 fprintf(fp
, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
618 fprintf(fp
, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
622 /* Reserve the channel */
623 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
624 fprintf(fp
, "\t\tif(buff == NULL) {\n");
625 fprintf(fp
, "\t\t\t/* Buffer is full*/\n");
626 fprintf(fp
, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
627 fprintf(fp
, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
628 fprintf(fp
, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
629 fprintf(fp
, "\t\t}\n");
632 //fprintf(fp, "\t\tif(resret == 1) {\n");
633 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
634 // facName, checksum, ev->name);
635 //fprintf(fp, "\t\t}\n");
637 /* Write the header */
639 fprintf(fp
,"\t\tlength = event_length - header_length;\n");
641 fprintf(fp
, "\t\tltt_write_event_header(trace, channel, buff, \n"
642 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
643 "\t\t\t\t&delta, &tsc);\n",
644 facName
, checksum
, ev
->name
);
648 fprintf(fp
, "\t\tchar *ptr = (char*)buff + _offset + header_length;\n");
651 //declare a char pointer if needed : starts at the end of the structs.
652 //if(structCount + hasStrSeq > 1) {
653 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
654 // for(pos1=0;pos1<structCount;pos1++){
655 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
657 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
660 // Declare an alias pointer of the struct type to the beginning
661 // of the reserved area, just after the event header.
663 if(ev
->type
->alignment
> 1) {
664 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
665 ev
->type
->alignment
, ev
->type
->alignment
, ev
->type
->alignment
);
668 fprintf(fp
, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
671 //allocate memory for new struct and initialize it
672 //if(whichTypeFirst == 1){ //struct first
673 //for(pos1=0;pos1<structCount;pos1++){
674 // if(pos1==0) fprintf(fp,
675 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
676 // ev->name, facName,ev->name, facName);
677 //MD disabled else fprintf(fp,
678 // "\tstruct %s_%s_%d __%d;\n",
679 // ev->name, facName,pos1+1,pos1+1);
681 //}else if(whichTypeFirst == 2){
682 // for(pos1=0;pos1<structCount;pos1++)
683 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
684 // ev->name, facName,pos1+1,pos1+1);
688 if(structCount
) fprintf(fp
,"\t\t//initialize structs\n");
692 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
693 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
695 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
699 // if(structCount > 1) fprintf(fp,"\n");
701 fprintf(fp
, "\t\t__1->%s = %s;\n", fld
->name
, fld
->name
);
703 //if(structCount == 1 && whichTypeFirst == 1)
704 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
706 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
710 if(structCount
) fprintf(fp
,"\n");
711 //set ptr to the end of first struct if needed;
712 //if(structCount + hasStrSeq > 1){
713 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
714 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
717 //copy struct, sequence and string to buffer
723 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
724 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
726 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
727 // if(flag == 0) structCount++;
729 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
730 // assert(0); // MD : disabled !
731 // fprintf(fp,"\t//copy struct to buffer\n");
732 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
733 // structCount, ev->name, facName,structCount);
734 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
735 // ev->name, facName,structCount);
738 //else if(td->type == SEQUENCE){
739 if(td
->type
== SEQUENCE
){
741 fprintf(fp
,"\t\t//copy sequence length and sequence to buffer\n");
743 if(td
->alignment
> 1) {
744 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
745 td
->alignment
, td
->alignment
, td
->alignment
);
747 fprintf(fp
,"\t\t*ptr = seqlength_%d;\n",++seqCount
);
748 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
749 if(td
->alignment
> 1) {
750 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
751 td
->alignment
, td
->alignment
, td
->alignment
);
753 fprintf(fp
,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
754 fld
->name
, getTypeStr(td
), seqCount
);
755 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
756 getTypeStr(td
), seqCount
);
758 else if(td
->type
==STRING
){
760 fprintf(fp
,"\t\t//copy string to buffer\n");
761 fprintf(fp
,"\t\tif(strlength_%d > 0){\n",++strCount
);
762 if(td
->alignment
> 1) {
763 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
764 td
->alignment
, td
->alignment
, td
->alignment
);
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 if(td
->alignment
> 1) {
777 fprintf(fp
,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
778 td
->alignment
, td
->alignment
, td
->alignment
);
780 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
781 fld
->name
, getTypeStr(td
), td
->size
);
782 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td
), td
->size
);
785 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
788 fprintf(fp
, "\t\t/* Commit the work */\n");
789 fprintf(fp
, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
790 "\t\t\t\tbuff, event_length);\n");
791 fprintf(fp
, "\t\tltt_write_commit_counter("
792 "channel->rchan->buf[smp_processor_id()],\n"
795 /* End of traces iteration */
796 fprintf(fp
, "\t}\n\n");
799 // The generated preempt_check_resched is not dangerous because
800 // interrupts are disabled.
801 fprintf(fp
, "\tspin_unlock(<t_traces.locks[smp_processor_id()]);\n");
803 fprintf(fp
, "unlock:\n");
804 fprintf(fp
, "\tbarrier();\n");
805 fprintf(fp
, "\tltt_nesting[smp_processor_id()]--;\n");
806 fprintf(fp
, "\t/* Re-enable interrupts */\n");
807 fprintf(fp
, "\tlocal_irq_restore(_flags);\n");
808 fprintf(fp
, "\tpreempt_enable_no_resched();\n");
809 //fprintf(fp, "\tpreempt_check_resched();\n");
811 //call trace function
812 //fprintf(fp,"\n\t//call trace function\n");
813 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
815 fprintf(fp
, "#endif //CONFIG_LTT\n\n");
820 /*****************************************************************************
822 * getTypeStr : generate type string
824 * td : a type descriptor
826 * char * : type string
827 ****************************************************************************/
828 char * getTypeStr(type_descriptor
* td
){
829 type_descriptor
* t
;
833 return intOutputTypes
[td
->size
];
835 return uintOutputTypes
[td
->size
];
841 return "unsigned long";
849 return floatOutputTypes
[td
->size
];
853 return uintOutputTypes
[td
->size
];
859 return intOutputTypes
[t
->size
];
861 return uintOutputTypes
[t
->size
];
867 return "unsigned long";
875 return floatOutputTypes
[t
->size
];
879 return uintOutputTypes
[t
->size
];
881 error_callback(NULL
,"Nested struct is not supportted");
885 case STRUCT
: //for now we do not support nested struct
886 error_callback(NULL
,"Nested struct is not supportted");
889 error_callback(NULL
,"No type information");
895 /*****************************************************************************
897 * generateLoaderfile: generate a facility loaded .h file
899 * fp : file to be written to
900 * facName : name of facility
901 * nbEvent : number of events in the facility
902 * checksum : checksum for the facility
903 ****************************************************************************/
904 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
, char *capname
){
905 fprintf(fp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname
);
906 fprintf(fp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname
);
907 fprintf(fp
,"#include <linux/ltt-facilities.h>\n", facName
, checksum
);
908 fprintf(fp
,"ltt_facility_t\tltt_facility_%s;\n", facName
, checksum
);
909 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
911 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
913 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
915 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum
);
916 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName
);
917 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent
);
918 fprintf(fp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname
);
921 void generateCfile(FILE * fp
, char * filefacname
){
924 fprintf(fp
, " * ltt-facility-loader-%s.c\n", filefacname
);
926 fprintf(fp
, " * (C) Copyright 2005 - \n");
927 fprintf(fp
, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
929 fprintf(fp
, " * Contains the LTT facility loader.\n");
931 fprintf(fp
, " */\n");
934 fprintf(fp
, "#include <linux/ltt-facilities.h>\n");
935 fprintf(fp
, "#include <linux/module.h>\n");
936 fprintf(fp
, "#include <linux/init.h>\n");
937 fprintf(fp
, "#include <linux/config.h>\n");
938 fprintf(fp
, "#include \"ltt-facility-loader-%s.h\"\n", filefacname
);
941 fprintf(fp
, "#ifdef CONFIG_LTT\n");
943 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
944 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
946 fprintf(fp
, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
948 fprintf(fp
, "#define SYMBOL_STRING(sym) #sym\n");
950 fprintf(fp
, "static struct ltt_facility facility = {\n");
951 fprintf(fp
, "\t.name = ltt_facility_name,\n");
952 fprintf(fp
, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
953 fprintf(fp
, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
954 fprintf(fp
, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL)\n");
957 fprintf(fp
, "#ifndef MODULE\n");
959 fprintf(fp
, "/* Built-in facility. */\n");
961 fprintf(fp
, "static int __init facility_init(void)\n");
963 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname
);
965 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
966 fprintf(fp
, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
968 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
970 fprintf(fp
, "__initcall(facility_init);\n");
974 fprintf(fp
, "#else \n");
976 fprintf(fp
, "/* Dynamic facility. */\n");
978 fprintf(fp
, "static int __init facility_init(void)\n");
980 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname
);
982 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
983 fprintf(fp
, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
985 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
988 fprintf(fp
, "static void __exit facility_exit(void)\n");
990 fprintf(fp
, "\tint err;\n");
992 fprintf(fp
, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
993 fprintf(fp
, "\tif(err != 0)\n");
994 fprintf(fp
, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
998 fprintf(fp
, "module_init(facility_init)\n");
999 fprintf(fp
, "module_exit(facility_exit)\n");
1002 fprintf(fp
, "MODULE_LICENSE(\"GPL\");\n");
1003 fprintf(fp
, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1004 fprintf(fp
, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1006 fprintf(fp
, "#endif //MODULE\n");
1008 fprintf(fp
, "#endif //CONFIG_LTT\n");
This page took 0.058032 seconds and 3 git commands to generate.