739eee2b6ea2ba6024c1bebd28ee4017efec81d3
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
)
276 type_descriptor
* td
;
278 for (pos
= 0; pos
< len
; pos
++) {
279 fld
= (field
*)array
[pos
];
281 if( td
->type
== STRING
|| td
->type
== SEQUENCE
||
285 // if (*whichTypeFirst == 0) {
286 // *whichTypeFirst = 1; //struct first
291 fprintf(fp
,"struct %s_%s",name
, facName
);
293 fprintf(fp
, "_%d {\n",++*structCount
);
298 fprintf(fp
, "\t%s %s; /* %s */\n",
299 getTypeStr(td
),fld
->name
,fld
->description
);
302 if (*whichTypeFirst
== 0) {
303 //string or sequence or array first
308 fprintf(fp
,"} __attribute__ ((packed));\n\n");
316 fprintf(fp
,"} __attribute__ ((packed));\n\n");
321 /*****************************************************************************
323 * generateHfile : Create the typedefs
325 * fp : file to be written to
326 ****************************************************************************/
328 generateTypeDefs(FILE * fp
, char *facName
)
332 fprintf(fp
,"#include <linux/types.h>\n");
333 fprintf(fp
,"#include <linux/spinlock.h>\n");
334 fprintf(fp
,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName
);
335 fprintf(fp
,"#include <linux/ltt-core.h>\n");
337 fprintf(fp
, "/**** Basic Type Definitions ****/\n\n");
339 for (pos
= 0; pos
< fac
->named_types
.values
.position
; pos
++) {
340 type_descriptor
* type
=
341 (type_descriptor
*)fac
->named_types
.values
.array
[pos
];
342 printStruct(fp
, type
->fields
.position
, type
->fields
.array
,
343 "", type
->type_name
, &tmp
, &tmp
, NULL
);
344 fprintf(fp
, "typedef struct _%s %s;\n\n",
345 type
->type_name
, type
->type_name
);
350 /*****************************************************************************
352 * generateEnumDefinition: generate enum definition if it exists
354 * fp : file to be written to
356 ****************************************************************************/
357 void generateEnumDefinition(FILE * fp
, type_descriptor
* type
){
360 if(type
->already_printed
) return;
362 fprintf(fp
,"enum {\n");
363 for(pos
= 0; pos
< type
->labels
.position
; pos
++){
364 fprintf(fp
,"\tLTT_ENUM_%s", type
->labels
.array
[pos
]);
365 if (pos
!= type
->labels
.position
- 1) fprintf(fp
,",");
366 if(type
->labels_description
.array
[pos
] != NULL
)
367 fprintf(fp
,"\t/* %s */\n",type
->labels_description
.array
[pos
]);
371 fprintf(fp
,"};\n\n\n");
373 type
->already_printed
= 1;
376 /*****************************************************************************
378 * generateStrucTFunc: output structure and function to .h file
380 * fp : file to be written to
381 * facName : name of facility
382 ****************************************************************************/
383 void generateStructFunc(FILE * fp
, char * facName
, unsigned long checksum
){
386 type_descriptor
* td
;
388 int hasStrSeq
, flag
, structCount
, seqCount
,strCount
, whichTypeFirst
=0;
390 for(pos
= 0; pos
< fac
->events
.position
; pos
++){
391 ev
= (event
*) fac
->events
.array
[pos
];
392 //yxx if(ev->nested)continue;
393 fprintf(fp
,"/**** structure and trace function for event: %s ****/\n\n",
395 //if(ev->type == 0){ // event without type
396 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
397 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
398 // facName,checksum,ev->name);
399 // fprintf(fp,"};\n\n\n");
403 //if fields contain enum, print out enum definition
404 //MD : fixed in generateEnumDefinition to do not print the same enum
407 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
408 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
409 if(fld
->type
->type
== ENUM
) generateEnumDefinition(fp
, fld
->type
);
412 //default: no string, array or sequence in the event
417 //structure for kernel
419 printStruct(fp
, ev
->type
->fields
.position
, ev
->type
->fields
.array
,
420 ev
->name
, facName
, &whichTypeFirst
, &hasStrSeq
, &structCount
);
423 //trace function : function name and parameters : stub function.
426 fprintf(fp
, "#ifndef CONFIG_LTT\n");
427 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
431 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
432 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
434 if(td
->type
== ARRAY
){
435 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
436 }else if(td
->type
== STRING
){
437 fprintf(fp
,"short int strlength_%d, %s * %s",
438 ++strCount
, getTypeStr(td
), fld
->name
);
439 }else if(td
->type
== SEQUENCE
){
440 fprintf(fp
,"%s seqlength_%d, %s * %s",
441 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
442 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
443 if(pos1
!= ev
->type
->fields
.position
- 1) fprintf(fp
,", ");
445 fprintf(fp
,")\n{\n");
447 fprintf(fp
,"#else\n");
449 //trace function : function name and parameters
452 fprintf(fp
,"static inline void trace_%s_%s(",facName
,ev
->name
);
456 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
457 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
459 if(td
->type
== ARRAY
){
460 fprintf(fp
,"%s * %s",getTypeStr(td
), fld
->name
);
461 }else if(td
->type
== STRING
){
462 fprintf(fp
,"short int strlength_%d, %s * %s",
463 ++strCount
, getTypeStr(td
), fld
->name
);
464 }else if(td
->type
== SEQUENCE
){
465 fprintf(fp
,"%s seqlength_%d, %s * %s",
466 uintOutputTypes
[td
->size
], ++seqCount
,getTypeStr(td
), fld
->name
);
467 }else fprintf(fp
,"%s %s",getTypeStr(td
), fld
->name
);
468 if(pos1
!= ev
->type
->fields
.position
- 1) fprintf(fp
,", ");
470 fprintf(fp
,")\n{\n");
474 //length of buffer : length of all structures
475 fprintf(fp
,"\tint length = ");
476 if(ev
->type
== 0) fprintf(fp
, "0");
478 for(pos1
=0;pos1
<structCount
;pos1
++){
479 fprintf(fp
,"sizeof(struct %s_%s_%d)",ev
->name
, facName
,pos1
+1);
480 if(pos1
!= structCount
-1) fprintf(fp
," + ");
483 //length of buffer : length of all arrays, sequences and strings
488 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
489 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
491 if(td
->type
== SEQUENCE
|| td
->type
==STRING
|| td
->type
==ARRAY
){
492 if(structCount
|| flag
> 0) fprintf(fp
," + ");
493 if(td
->type
== SEQUENCE
)
494 fprintf(fp
,"sizeof(%s) + sizeof(%s) * seqlength_%d",
495 uintOutputTypes
[td
->size
], getTypeStr(td
), ++seqCount
);
496 else if(td
->type
==STRING
) fprintf(fp
,"strlength_%d + 1", ++strCount
);
497 else if(td
->type
==ARRAY
)
498 fprintf(fp
,"sizeof(%s) * %d", getTypeStr(td
),td
->size
);
499 if(structCount
== 0) flag
= 1;
505 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
506 // write directly to the channel
507 fprintf(fp
, "\tunsigned int index;\n");
508 fprintf(fp
, "\tstruct ltt_channel_struct *channel;\n");
509 fprintf(fp
, "\tstruct ltt_trace_struct *trace;\n");
510 fprintf(fp
, "\tunsigned long _flags;\n");
511 fprintf(fp
, "\tvoid *buff;\n");
512 fprintf(fp
, "\tunsigned int header_length;\n");
513 fprintf(fp
, "\tunsigned int event_length;\n");
514 fprintf(fp
, "\tint resret;\n");
515 fprintf(fp
, "\tunsigned char _offset;\n");
516 fprintf(fp
, "\tstruct rchan_buf *buf;\n");
519 fprintf(fp
, "\tstruct %s_%s_1* __1;\n\n", ev
->name
, facName
);
521 /* Warning : this is done prior to taking locks :
522 * setting this value must be done at the end of the trace activation.
523 * (we don't care for trace removal, as the list of traces is protected : it
524 * just won't iterate on any trace). */
526 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
528 fprintf(fp
, "\t/* Disable interrupts. */\n");
529 fprintf(fp
, "\tlocal_irq_save(_flags);\n");
530 fprintf(fp
, "\tpreempt_disable();\n\n");
532 fprintf(fp
, "\tltt_nesting[smp_processor_id()]++;\n");
533 fprintf(fp
, "\tbarrier();\n");
534 fprintf(fp
, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
535 fprintf(fp
, "\tspin_lock(<t_traces.locks[smp_processor_id()]);\n\n");
538 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
539 "\t\t\t\tevent_%s);\n",
540 facName
, checksum
, ev
->name
);
544 fprintf(fp
, "\tlist_for_each_entry(trace, <t_traces.head, list) {\n");
545 fprintf(fp
, "\t\tif(!trace->active) continue;\n\n");
547 fprintf(fp
, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
548 fprintf(fp
, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
549 /* Warning : not atomic reservation : event size depends on the current
550 * address for alignment */
551 fprintf(fp
, "\t\theader_length = "
552 "ltt_get_event_header_size(trace, channel,"
553 "buf->data + buf->offset, &_offset);\n");
554 fprintf(fp
, "\t\tevent_length = header_length + length;\n");
556 /* Reserve the channel */
557 fprintf(fp
, "\t\tbuff = relay_reserve(channel->rchan, event_length, &resret);\n");
558 fprintf(fp
, "\t\tif(buff == NULL) {\n");
559 fprintf(fp
, "\t\t\t/* Buffer is full*/\n");
560 fprintf(fp
, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
561 fprintf(fp
, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
562 fprintf(fp
, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
563 fprintf(fp
, "\t\t}\n");
566 fprintf(fp
, "\t\tif(resret == 1) {\n");
567 fprintf(fp
, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
568 facName
, checksum
, ev
->name
);
569 fprintf(fp
, "\t\t}\n");
571 /* Write the header */
573 fprintf(fp
, "\t\tltt_write_event_header(trace, channel, buff, \n"
574 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset);\n",
575 facName
, checksum
, ev
->name
);
578 //declare a char pointer if needed : starts at the end of the structs.
579 if(structCount
+ hasStrSeq
> 1) {
580 fprintf(fp
,"\t\tchar * ptr = (char*)buff + header_length");
581 for(pos1
=0;pos1
<structCount
;pos1
++){
582 fprintf(fp
," + sizeof(struct %s_%s_%d)",ev
->name
, facName
,pos1
+1);
584 if(structCount
+ hasStrSeq
> 1) fprintf(fp
,";\n");
587 // Declare an alias pointer of the struct type to the beginning
588 // of the reserved area, just after the event header.
590 fprintf(fp
, "\t\t__1 = (struct %s_%s_1 *)(buff + header_length);\n",
592 //allocate memory for new struct and initialize it
593 //if(whichTypeFirst == 1){ //struct first
594 //for(pos1=0;pos1<structCount;pos1++){
595 // if(pos1==0) fprintf(fp,
596 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
597 // ev->name, facName,ev->name, facName);
598 //MD disabled else fprintf(fp,
599 // "\tstruct %s_%s_%d __%d;\n",
600 // ev->name, facName,pos1+1,pos1+1);
602 //}else if(whichTypeFirst == 2){
603 // for(pos1=0;pos1<structCount;pos1++)
604 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
605 // ev->name, facName,pos1+1,pos1+1);
609 if(structCount
) fprintf(fp
,"\t\t//initialize structs\n");
613 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
614 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
616 if(td
->type
!= ARRAY
&& td
->type
!= SEQUENCE
&& td
->type
!= STRING
){
620 // if(structCount > 1) fprintf(fp,"\n");
622 fprintf(fp
, "\t\t__1->%s = %s;\n", fld
->name
, fld
->name
);
624 //if(structCount == 1 && whichTypeFirst == 1)
625 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
627 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
631 if(structCount
) fprintf(fp
,"\n");
632 //set ptr to the end of first struct if needed;
633 //if(structCount + hasStrSeq > 1){
634 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
635 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
638 //copy struct, sequence and string to buffer
644 for(pos1
= 0; pos1
< ev
->type
->fields
.position
; pos1
++){
645 fld
= (field
*)ev
->type
->fields
.array
[pos1
];
647 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
648 // if(flag == 0) structCount++;
650 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
651 // assert(0); // MD : disabled !
652 // fprintf(fp,"\t//copy struct to buffer\n");
653 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
654 // structCount, ev->name, facName,structCount);
655 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
656 // ev->name, facName,structCount);
659 //else if(td->type == SEQUENCE){
660 if(td
->type
== SEQUENCE
){
662 fprintf(fp
,"\t\t//copy sequence length and sequence to buffer\n");
663 fprintf(fp
,"\t\t*ptr = seqlength_%d;\n",++seqCount
);
664 fprintf(fp
,"\t\tptr += sizeof(%s);\n",uintOutputTypes
[td
->size
]);
665 fprintf(fp
,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
666 fld
->name
, getTypeStr(td
), seqCount
);
667 fprintf(fp
,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
668 getTypeStr(td
), seqCount
);
670 else if(td
->type
==STRING
){
672 fprintf(fp
,"\t\t//copy string to buffer\n");
673 fprintf(fp
,"\t\tif(strlength_%d > 0){\n",++strCount
);
674 fprintf(fp
,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
675 fld
->name
, strCount
);
676 fprintf(fp
,"\t\t\tptr += strlength_%d + 1;\n",strCount
);
677 fprintf(fp
,"\t\t}else{\n");
678 fprintf(fp
,"\t\t\t*ptr = '\\0';\n");
679 fprintf(fp
,"\t\t\tptr += 1;\n");
680 fprintf(fp
,"\t\t}\n\n");
681 }else if(td
->type
==ARRAY
){
683 fprintf(fp
,"\t//copy array to buffer\n");
684 fprintf(fp
,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
685 fld
->name
, getTypeStr(td
), td
->size
);
686 fprintf(fp
,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td
), td
->size
);
689 if(structCount
+ seqCount
> 1) fprintf(fp
,"\n");
692 fprintf(fp
, "\t\t/* Commit the work */\n");
693 fprintf(fp
, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
694 "\t\t\t\tbuff, event_length);\n");
695 fprintf(fp
, "\t\tltt_write_commit_counter("
696 "channel->rchan->buf[smp_processor_id()],\n"
699 /* End of traces iteration */
700 fprintf(fp
, "\t}\n\n");
703 // The generated preempt_check_resched is not dangerous because
704 // interrupts are disabled.
705 fprintf(fp
, "\tspin_unlock(<t_traces.locks[smp_processor_id()]);\n");
707 fprintf(fp
, "unlock:\n");
708 fprintf(fp
, "\tbarrier();\n");
709 fprintf(fp
, "\tltt_nesting[smp_processor_id()]--;\n");
710 fprintf(fp
, "\t/* Re-enable interrupts */\n");
711 fprintf(fp
, "\tlocal_irq_restore(_flags);\n");
712 fprintf(fp
, "\tpreempt_enable_no_resched();\n");
713 //fprintf(fp, "\tpreempt_check_resched();\n");
715 //call trace function
716 //fprintf(fp,"\n\t//call trace function\n");
717 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
719 fprintf(fp
, "#endif //CONFIG_LTT\n\n");
724 /*****************************************************************************
726 * getTypeStr : generate type string
728 * td : a type descriptor
730 * char * : type string
731 ****************************************************************************/
732 char * getTypeStr(type_descriptor
* td
){
733 type_descriptor
* t
;
737 return intOutputTypes
[td
->size
];
739 return uintOutputTypes
[td
->size
];
745 return "unsigned long";
753 return floatOutputTypes
[td
->size
];
757 return uintOutputTypes
[td
->size
];
763 return intOutputTypes
[t
->size
];
765 return uintOutputTypes
[t
->size
];
771 return "unsigned long";
779 return floatOutputTypes
[t
->size
];
783 return uintOutputTypes
[t
->size
];
785 error_callback(NULL
,"Nested struct is not supportted");
789 case STRUCT
: //for now we do not support nested struct
790 error_callback(NULL
,"Nested struct is not supportted");
793 error_callback(NULL
,"No type information");
799 /*****************************************************************************
801 * generateLoaderfile: generate a facility loaded .h file
803 * fp : file to be written to
804 * facName : name of facility
805 * nbEvent : number of events in the facility
806 * checksum : checksum for the facility
807 ****************************************************************************/
808 void generateLoaderfile(FILE * fp
, char * facName
, int nbEvent
, unsigned long checksum
, char *capname
){
809 fprintf(fp
, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname
);
810 fprintf(fp
, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname
);
811 fprintf(fp
,"#include <linux/ltt-facilities.h>\n", facName
, checksum
);
812 fprintf(fp
,"ltt_facility_t\tltt_facility_%s;\n", facName
, checksum
);
813 fprintf(fp
,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName
, checksum
);
815 fprintf(fp
,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
817 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
819 fprintf(fp
,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum
);
820 fprintf(fp
,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName
);
821 fprintf(fp
,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent
);
822 fprintf(fp
, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname
);
825 void generateCfile(FILE * fp
, char * filefacname
){
828 fprintf(fp
, " * ltt-facility-loader-%s.c\n", filefacname
);
830 fprintf(fp
, " * (C) Copyright 2005 - \n");
831 fprintf(fp
, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
833 fprintf(fp
, " * Contains the LTT facility loader.\n");
835 fprintf(fp
, " */\n");
838 fprintf(fp
, "#include <linux/ltt-facilities.h>\n");
839 fprintf(fp
, "#include <linux/module.h>\n");
840 fprintf(fp
, "#include <linux/init.h>\n");
841 fprintf(fp
, "#include <linux/config.h>\n");
842 fprintf(fp
, "#include \"ltt-facility-loader-%s.h\"\n", filefacname
);
845 fprintf(fp
, "#ifdef CONFIG_LTT\n");
847 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
848 fprintf(fp
, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
850 fprintf(fp
, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
852 fprintf(fp
, "#define SYMBOL_STRING(sym) #sym\n");
854 fprintf(fp
, "static struct ltt_facility facility = {\n");
855 fprintf(fp
, "\t.name = ltt_facility_name,\n");
856 fprintf(fp
, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
857 fprintf(fp
, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
858 fprintf(fp
, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL)\n");
861 fprintf(fp
, "#ifndef MODULE\n");
863 fprintf(fp
, "/* Built-in facility. */\n");
865 fprintf(fp
, "static int __init facility_init(void)\n");
867 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname
);
869 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
870 fprintf(fp
, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
872 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
874 fprintf(fp
, "__initcall(facility_init);\n");
878 fprintf(fp
, "#else \n");
880 fprintf(fp
, "/* Dynamic facility. */\n");
882 fprintf(fp
, "static int __init facility_init(void)\n");
884 fprintf(fp
, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname
);
886 fprintf(fp
, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
887 fprintf(fp
, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
889 fprintf(fp
, "\treturn LTT_FACILITY_SYMBOL;\n");
892 fprintf(fp
, "static void __exit facility_exit(void)\n");
894 fprintf(fp
, "\tint err;\n");
896 fprintf(fp
, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
897 fprintf(fp
, "\tif(err != 0)\n");
898 fprintf(fp
, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
902 fprintf(fp
, "module_init(facility_init)\n");
903 fprintf(fp
, "module_exit(facility_exit)\n");
906 fprintf(fp
, "MODULE_LICENSE(\"GPL\");\n");
907 fprintf(fp
, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
908 fprintf(fp
, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
910 fprintf(fp
, "#endif //MODULE\n");
912 fprintf(fp
, "#endif //CONFIG_LTT\n");
This page took 0.05425 seconds and 4 git commands to generate.