genevent : -a bugfix
[lttv.git] / genevent / genevent.c
1 /*
2
3 genevent.c: Generate helper declarations and functions to trace events
4 from an event description file.
5
6 Copyright (C) 2002, Xianxiu Yang
7 Copyright (C) 2002, Michel Dagenais
8
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.
12
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.
17
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
21 */
22
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.
26
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
30 definitions.
31
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. */
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <stdio.h>
41 #include <stdarg.h>
42 #include <linux/errno.h>
43 #include <assert.h>
44
45 #include "parser.h"
46 #include "genevent.h"
47
48 #define max(a,b) ((a)<(b))?(b):(a)
49
50 /* Named types may be referenced from anywhere */
51
52 facility * fac;
53
54 unsigned alignment = 0;
55
56 int main(int argc, char** argv)
57 {
58 char *token;
59 parse_file in;
60 char buffer[BUFFER_SIZE];
61 int i;
62
63 if(argc < 2){
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");
69 exit(1);
70 }
71
72 in.buffer = buffer;
73 in.error = error_callback;
74
75 for(i = 1 ; i < argc ; i++) {
76
77 if(strcmp("-a", argv[i])==0) {
78 if(i >= argc-1) {
79 printf("Error : missing argument to -a\n");
80 exit(1);
81 } else i++;
82 alignment = atoi(argv[i]);
83 } else {
84
85 in.lineno = 0;
86 in.name = allocAndCopy(argv[i]);
87
88 in.fp = fopen(in.name, "r");
89 if(!in.fp ){
90 in.error(&in,"cannot open facility input file");
91 }
92
93 while(1){
94 token = getToken(&in);
95 if(in.type == ENDFILE) break;
96
97 if(strcmp(token, "<")) in.error(&in,"not a facility file");
98 token = getName(&in);
99
100 if(strcmp("facility",token) == 0) {
101 fac = memAlloc(sizeof(facility));
102 fac->name = NULL;
103 fac->description = NULL;
104 sequence_init(&(fac->events));
105 table_init(&(fac->named_types));
106 sequence_init(&(fac->unnamed_types));
107
108 parseFacility(&in, fac);
109
110 //check if any namedType is not defined
111 checkNamedTypesImplemented(&fac->named_types);
112 }
113 else in.error(&in,"facility token was expected");
114
115 generateFile(argv[i]);
116
117 free(fac->name);
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);
125 free(fac);
126 }
127
128 free(in.name);
129 fclose(in.fp);
130 }
131 }
132 return 0;
133 }
134
135
136 /*****************************************************************************
137 *Function name
138 * generateFile : generate .c and .h file
139 *Input Params
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;
145 int nbEvent;
146 unsigned long checksum=0;
147
148 //remove .xml if it exists
149 tmp = &name[strlen(name)-4];
150 if(strcmp(tmp, ".xml") == 0){
151 *tmp = '\0';
152 }
153
154 tmp = strrchr(name,'/');
155 if(tmp){
156 tmp++;
157 }else{
158 tmp = name;
159 }
160
161 loadName = appendString("ltt-facility-loader-", tmp);
162 tmp2 = appendString(loadName,".h");
163 free(loadName);
164 loadName = tmp2;
165 hName = appendString("ltt-facility-", tmp);
166 tmp2 = appendString(hName,".h");
167 free(hName);
168 hName = tmp2;
169 hIdName = appendString("ltt-facility-id-", tmp);
170 tmp2 = appendString(hIdName,".h");
171 free(hIdName);
172 hIdName = tmp2;
173 cName = appendString("ltt-facility-loader-", tmp);
174 tmp2 = appendString(cName,".c");
175 free(cName);
176 cName = tmp2;
177 lFp = fopen(loadName,"w");
178 if(!lFp){
179 printf("Cannot open the file : %s\n",loadName);
180 exit(1);
181 }
182
183 hFp = fopen(hName,"w");
184 if(!hFp){
185 printf("Cannot open the file : %s\n",hName);
186 exit(1);
187 }
188
189 iFp = fopen(hIdName,"w");
190 if(!iFp){
191 printf("Cannot open the file : %s\n",hIdName);
192 exit(1);
193 }
194
195 cFp = fopen(cName,"w");
196 if(!cFp){
197 printf("Cannot open the file : %s\n",cName);
198 exit(1);
199 }
200
201 free(loadName);
202 free(hName);
203 free(hIdName);
204 free(cName);
205
206 generateChecksum(fac->name, &checksum, &(fac->events));
207
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);
215
216
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);
224
225 /* generate .h file, calls to register the facility at init time */
226 generateLoaderfile(lFp,fac->name,nbEvent,checksum,fac->capname);
227
228 // create ltt-facility-loader-facname.c
229 generateCfile(cFp, tmp);
230
231 fclose(hFp);
232 fclose(iFp);
233 fclose(lFp);
234 fclose(cFp);
235
236 }
237
238
239 /*****************************************************************************
240 *Function name
241 * generateEnumEvent : output event enum to .h file
242 *Input Params
243 * fp : file to be written to
244 * facName : name of facility
245 *Output Params
246 * nbEvent : number of events in the facility
247 ****************************************************************************/
248 void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long checksum) {
249 int pos = 0;
250
251 fprintf(fp,"#include <linux/ltt-facilities.h>\n\n");
252
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);
256
257 fprintf(fp,"/**** event type ****/\n\n");
258 fprintf(fp,"enum %s_event {\n",facName);
259
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");
263 }
264 fprintf(fp,"\n};\n\n\n");
265
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;
269 }
270
271
272 /*****************************************************************************
273 *Function name
274 * printStruct : Generic struct printing function
275 *Input Params
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 ****************************************************************************/
285
286 static void
287 printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
288 int * whichTypeFirst, int * hasStrSeq, int * structCount,
289 type_descriptor *type)
290 {
291 int flag = 0;
292 int pos;
293 field * fld;
294 type_descriptor * td;
295
296 for (pos = 0; pos < len; pos++) {
297 fld = (field *)array[pos];
298 td = fld->type;
299 if( td->type == STRING || td->type == SEQUENCE ||
300 td->type == ARRAY) {
301 (*hasStrSeq)++;
302 }
303 // if (*whichTypeFirst == 0) {
304 // *whichTypeFirst = 1; //struct first
305 // }
306 if (flag == 0) {
307 flag = 1;
308
309 fprintf(fp,"struct %s_%s",name, facName);
310 if (structCount) {
311 fprintf(fp, "_%d {\n",++*structCount);
312 } else {
313 fprintf(fp, " {\n");
314 }
315 }
316 fprintf(fp, "\t%s %s; /* %s */\n",
317 getTypeStr(td),fld->name,fld->description );
318 #if 0
319 } else {
320 if (*whichTypeFirst == 0) {
321 //string or sequence or array first
322 *whichTypeFirst = 2;
323 }
324 (*hasStrSeq)++;
325 if(flag) {
326 fprintf(fp,"} __attribute__ ((packed));\n\n");
327 }
328 flag = 0;
329 }
330 #endif //0
331 }
332
333 if(flag) {
334 unsigned align = max(alignment, type->alignment);
335
336 if(align == 0)
337 fprintf(fp,"} __attribute__ ((packed));\n\n");
338 else {
339 if(align != 1 && align != 2
340 && align != 4 && align != 8) {
341 printf("Wrong alignment %i, using packed.\n", align);
342 fprintf(fp,"} __attribute__ ((packed));\n\n");
343 } else
344 fprintf(fp,"} __attribute__ ((aligned(%i)));\n\n", align);
345 }
346 }
347 }
348
349
350 /*****************************************************************************
351 *Function name
352 * generateHfile : Create the typedefs
353 *Input Params
354 * fp : file to be written to
355 ****************************************************************************/
356 void
357 generateTypeDefs(FILE * fp, char *facName)
358 {
359 int pos, tmp = 1;
360
361 fprintf(fp,"#include <linux/types.h>\n");
362 fprintf(fp,"#include <linux/spinlock.h>\n");
363 fprintf(fp,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName);
364 fprintf(fp,"#include <linux/ltt-core.h>\n");
365
366 #if 0 //broken
367 fprintf(fp, "/**** Basic Type Definitions ****/\n\n");
368
369 for (pos = 0; pos < fac->named_types.values.position; pos++) {
370 type_descriptor * type =
371 (type_descriptor*)fac->named_types.values.array[pos];
372 printStruct(fp, type->fields.position, type->fields.array,
373 "", type->type_name, &tmp, &tmp, NULL);
374 fprintf(fp, "typedef struct _%s %s;\n\n",
375 type->type_name, type->type_name);
376 }
377 #endif //0
378 }
379
380
381 /*****************************************************************************
382 *Function name
383 * generateEnumDefinition: generate enum definition if it exists
384 *Input Params
385 * fp : file to be written to
386 * fHead : enum type
387 ****************************************************************************/
388 void generateEnumDefinition(FILE * fp, type_descriptor * type){
389 int pos;
390
391 if(type->already_printed) return;
392
393 fprintf(fp,"enum {\n");
394 for(pos = 0; pos < type->labels.position; pos++){
395 fprintf(fp,"\tLTT_ENUM_%s", type->labels.array[pos]);
396 if (pos != type->labels.position - 1) fprintf(fp,",");
397 if(type->labels_description.array[pos] != NULL)
398 fprintf(fp,"\t/* %s */\n",type->labels_description.array[pos]);
399 else
400 fprintf(fp,"\n");
401 }
402 fprintf(fp,"};\n\n\n");
403
404 type->already_printed = 1;
405 }
406
407 /*****************************************************************************
408 *Function name
409 * generateStrucTFunc: output structure and function to .h file
410 *Input Params
411 * fp : file to be written to
412 * facName : name of facility
413 ****************************************************************************/
414 void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
415 event * ev;
416 field * fld;
417 type_descriptor * td;
418 int pos, pos1;
419 int hasStrSeq, flag, structCount, seqCount,strCount, whichTypeFirst=0;
420
421 for(pos = 0; pos < fac->events.position; pos++){
422 ev = (event *) fac->events.array[pos];
423 //yxx if(ev->nested)continue;
424 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",
425 ev->name);
426 //if(ev->type == 0){ // event without type
427 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
428 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
429 // facName,checksum,ev->name);
430 // fprintf(fp,"};\n\n\n");
431 // continue;
432 //}
433
434 //if fields contain enum, print out enum definition
435 //MD : fixed in generateEnumDefinition to do not print the same enum
436 //twice.
437 if(ev->type != 0)
438 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
439 fld = (field *)ev->type->fields.array[pos1];
440 if(fld->type->type == ENUM) generateEnumDefinition(fp, fld->type);
441 }
442
443 //default: no string, array or sequence in the event
444 hasStrSeq = 0;
445 whichTypeFirst = 0;
446 structCount = 0;
447
448 //structure for kernel
449 if(ev->type != 0)
450 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
451 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount,
452 ev->type);
453
454
455 //trace function : function name and parameters : stub function.
456 seqCount = 0;
457 strCount = 0;
458 fprintf(fp, "#ifndef CONFIG_LTT\n");
459 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
460 if(ev->type == 0)
461 fprintf(fp, "void");
462 else
463 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
464 fld = (field *)ev->type->fields.array[pos1];
465 td = fld->type;
466 if(td->type == ARRAY ){
467 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
468 }else if(td->type == STRING){
469 fprintf(fp,"short int strlength_%d, %s * %s",
470 ++strCount, getTypeStr(td), fld->name);
471 }else if(td->type == SEQUENCE){
472 fprintf(fp,"%s seqlength_%d, %s * %s",
473 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
474 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
475 if(pos1 != ev->type->fields.position - 1) fprintf(fp,", ");
476 }
477 fprintf(fp,")\n{\n");
478 fprintf(fp,"}\n");
479 fprintf(fp,"#else\n");
480
481 //trace function : function name and parameters
482 seqCount = 0;
483 strCount = 0;
484 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
485 if(ev->type == 0)
486 fprintf(fp, "void");
487 else
488 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
489 fld = (field *)ev->type->fields.array[pos1];
490 td = fld->type;
491 if(td->type == ARRAY ){
492 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
493 }else if(td->type == STRING){
494 fprintf(fp,"short int strlength_%d, %s * %s",
495 ++strCount, getTypeStr(td), fld->name);
496 }else if(td->type == SEQUENCE){
497 fprintf(fp,"%s seqlength_%d, %s * %s",
498 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
499 }else fprintf(fp,"%s %s",getTypeStr(td), fld->name);
500 if(pos1 != ev->type->fields.position - 1) fprintf(fp,", ");
501 }
502 fprintf(fp,")\n{\n");
503
504
505
506 //allocate buffer
507 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
508 // write directly to the channel
509 fprintf(fp, "\tunsigned int index;\n");
510 fprintf(fp, "\tstruct ltt_channel_struct *channel;\n");
511 fprintf(fp, "\tstruct ltt_trace_struct *trace;\n");
512 fprintf(fp, "\tunsigned long _flags;\n");
513 fprintf(fp, "\tvoid *buff;\n");
514 fprintf(fp, "\tvoid *old_address;\n");
515 fprintf(fp, "\tunsigned int header_length;\n");
516 fprintf(fp, "\tunsigned int event_length;\n"); // total size (incl hdr)
517 fprintf(fp, "\tunsigned int length;\n"); // Size of the event var data.
518 fprintf(fp, "\tunsigned char _offset;\n");
519 fprintf(fp, "\tstruct rchan_buf *buf;\n");
520 fprintf(fp, "\tstruct timeval delta;\n");
521 fprintf(fp, "\tu64 tsc;\n");
522
523 if(ev->type != 0)
524 fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
525
526 /* Warning : this is done prior to taking locks :
527 * setting this value must be done at the end of the trace activation.
528 * (we don't care for trace removal, as the list of traces is protected : it
529 * just won't iterate on any trace). */
530 fprintf(fp,
531 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
532
533 fprintf(fp, "\t/* Disable interrupts. */\n");
534 fprintf(fp, "\tlocal_irq_save(_flags);\n");
535 fprintf(fp, "\tpreempt_disable();\n\n");
536
537 fprintf(fp, "\tltt_nesting[smp_processor_id()]++;\n");
538 fprintf(fp, "\tbarrier();\n");
539 fprintf(fp, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
540 fprintf(fp, "\tspin_lock(&ltt_traces.locks[smp_processor_id()]);\n\n");
541
542 fprintf(fp,
543 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
544 "\t\t\t\tevent_%s);\n",
545 facName, checksum, ev->name);
546 fprintf(fp,"\n");
547
548 /* For each trace */
549 fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
550 fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
551
552 //length of buffer : length of all structures
553 // if(ev->type == 0) fprintf(fp, "0");
554
555 fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
556 fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
557 fprintf(fp, "\n");
558 /* Warning : not atomic reservation : event size depends on the current
559 * address for alignment */
560 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
561 // Replaces _offset
562 /* NOTE2 : as the read old address from memory must come before any
563 * protected event, let's add a memory barrier() to make sure the compiler
564 * will not reorder this read. */
565 fprintf(fp, "\t\tdo {\n");
566 fprintf(fp, "\t\t\told_address = buf->data + buf->offset;\n");
567 fprintf(fp, "\t\t\tbarrier();\n");
568 fprintf(fp, "\t\t\tchar *ptr = (char*)old_address;\n");
569
570
571 fprintf(fp, "\t\t\theader_length = ltt_get_event_header_data(trace, "
572 "channel,\n"
573 "\t\t\t\t\t\t\t\t\t\told_address, &_offset, &delta, &tsc);\n");
574
575 fprintf(fp, "\t\t\tptr += _offset + header_length;\n");
576
577 for(pos1=0;pos1<structCount;pos1++){
578
579 unsigned align = max(alignment, ev->type->alignment);
580 if(align > 1) {
581 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
582 align, align, align);
583 }
584 fprintf(fp,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev->name,
585 facName,pos1+1);
586 // if(pos1 != structCount-1) fprintf(fp," + ");
587 }
588
589 //length of buffer : length of all arrays, sequences and strings
590 seqCount = 0;
591 strCount = 0;
592 flag = 0;
593 if(ev->type != 0)
594 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
595 fld = (field *)ev->type->fields.array[pos1];
596 td = fld->type;
597 if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
598 if(td->type == SEQUENCE) {
599
600 unsigned align = max(alignment, td->alignment);
601 if(align > 1) {
602 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
603 align, align, align);
604 }
605 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
606 if(align > 1) {
607 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
608 align, align, align);
609 }
610 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
611 getTypeStr(td), seqCount);
612
613 } else if(td->type==STRING) {
614 unsigned align = max(alignment, td->alignment);
615 if(align > 1) {
616 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
617 align, align, align);
618 }
619 fprintf(fp,"ptr += strlength_%d + 1;\n",
620 ++strCount);
621 }
622 else if(td->type==ARRAY) {
623 unsigned align = max(alignment, td->alignment);
624 if(align > 1) {
625 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
626 align, align, align);
627 }
628 fprintf(fp,"\t\t\tptr += sizeof(%s) * %d;\n",
629 getTypeStr(td),td->size);
630 if(structCount == 0) flag = 1;
631 }
632 }
633 }
634 fprintf(fp,";\n");
635
636 fprintf(fp, "\t\t\tevent_length = (unsigned long)ptr -"
637 "(unsigned long)old_address;\n");
638
639 /* let's put some protection before the cmpxchg : the space reservation and
640 * the get TSC are not dependant from each other. I don't want the compiler
641 * to reorder those in the wrong order. And relay_reserve is inline, so
642 * _yes_, the compiler could mess it up. */
643 fprintf(fp, "\t\t\tbarrier();\n");
644 fprintf(fp, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
645 "old_address);\n");
646 fprintf(fp, "\n");
647 fprintf(fp, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
648 fprintf(fp, "\n");
649
650
651 /* Reserve the channel */
652 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
653 fprintf(fp, "\t\tif(buff == NULL) {\n");
654 fprintf(fp, "\t\t\t/* Buffer is full*/\n");
655 fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
656 fprintf(fp, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
657 fprintf(fp, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
658 fprintf(fp, "\t\t}\n");
659
660 /* DEBUG */
661 //fprintf(fp, "\t\tif(resret == 1) {\n");
662 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
663 // facName, checksum, ev->name);
664 //fprintf(fp, "\t\t}\n");
665
666 /* Write the header */
667 fprintf(fp, "\n");
668 fprintf(fp,"\t\tlength = event_length - header_length;\n");
669 fprintf(fp, "\n");
670 fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
671 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
672 "\t\t\t\t&delta, &tsc);\n",
673 facName, checksum, ev->name);
674 fprintf(fp, "\n");
675
676 if(ev->type != 0)
677 fprintf(fp, "\t\tchar *ptr = (char*)buff + _offset + header_length;\n");
678
679
680 //declare a char pointer if needed : starts at the end of the structs.
681 //if(structCount + hasStrSeq > 1) {
682 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
683 // for(pos1=0;pos1<structCount;pos1++){
684 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
685 // }
686 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
687 //}
688
689 // Declare an alias pointer of the struct type to the beginning
690 // of the reserved area, just after the event header.
691 if(ev->type != 0) {
692 unsigned align = max(alignment, td->alignment);
693 if(align > 1) {
694 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
695 align, align, align);
696 }
697
698 fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
699 ev->name, facName);
700 }
701 //allocate memory for new struct and initialize it
702 //if(whichTypeFirst == 1){ //struct first
703 //for(pos1=0;pos1<structCount;pos1++){
704 // if(pos1==0) fprintf(fp,
705 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
706 // ev->name, facName,ev->name, facName);
707 //MD disabled else fprintf(fp,
708 // "\tstruct %s_%s_%d __%d;\n",
709 // ev->name, facName,pos1+1,pos1+1);
710 //}
711 //}else if(whichTypeFirst == 2){
712 // for(pos1=0;pos1<structCount;pos1++)
713 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
714 // ev->name, facName,pos1+1,pos1+1);
715 //}
716 fprintf(fp,"\n");
717
718 if(structCount) fprintf(fp,"\t\t//initialize structs\n");
719 //flag = 0;
720 //structCount = 0;
721 if(ev->type != 0)
722 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
723 fld = (field *)ev->type->fields.array[pos1];
724 td = fld->type;
725 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
726 //if(flag == 0){
727 // flag = 1;
728 // structCount++;
729 // if(structCount > 1) fprintf(fp,"\n");
730 //}
731 fprintf(fp, "\t\t__1->%s = %s;\n", fld->name, fld->name );
732
733 //if(structCount == 1 && whichTypeFirst == 1)
734 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
735 //else
736 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
737 }
738 //else flag = 0;
739 }
740 if(structCount) fprintf(fp,"\n");
741 //set ptr to the end of first struct if needed;
742 //if(structCount + hasStrSeq > 1){
743 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
744 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
745 //}
746
747 //copy struct, sequence and string to buffer
748 seqCount = 0;
749 strCount = 0;
750 flag = 0;
751 structCount = 0;
752 if(ev->type != 0)
753 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
754 fld = (field *)ev->type->fields.array[pos1];
755 td = fld->type;
756 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
757 // if(flag == 0) structCount++;
758 // flag++;
759 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
760 // assert(0); // MD : disabled !
761 // fprintf(fp,"\t//copy struct to buffer\n");
762 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
763 // structCount, ev->name, facName,structCount);
764 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
765 // ev->name, facName,structCount);
766 // }
767 // }
768 //else if(td->type == SEQUENCE){
769 if(td->type == SEQUENCE){
770 flag = 0;
771 fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
772
773 unsigned align = max(alignment, td->alignment);
774 if(align > 1) {
775 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
776 align, align, align);
777 }
778 fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
779 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
780 if(align > 1) {
781 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
782 align, align, align);
783 }
784 fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
785 fld->name, getTypeStr(td), seqCount);
786 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
787 getTypeStr(td), seqCount);
788 }
789 else if(td->type==STRING){
790 flag = 0;
791 fprintf(fp,"\t\t//copy string to buffer\n");
792 fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
793 unsigned align = max(alignment, td->alignment);
794 if(align > 1) {
795 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
796 align, align, align);
797 }
798 fprintf(fp,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
799 fld->name, strCount);
800 fprintf(fp,"\t\t\tptr += strlength_%d + 1;\n",strCount);
801 fprintf(fp,"\t\t}else{\n");
802 fprintf(fp,"\t\t\t*ptr = '\\0';\n");
803 fprintf(fp,"\t\t\tptr += 1;\n");
804 fprintf(fp,"\t\t}\n\n");
805 }else if(td->type==ARRAY){
806 flag = 0;
807 fprintf(fp,"\t//copy array to buffer\n");
808 unsigned align = max(alignment, td->alignment);
809 if(align > 1) {
810 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
811 align, align, align);
812 }
813 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
814 fld->name, getTypeStr(td), td->size);
815 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
816 }
817 }
818 if(structCount + seqCount > 1) fprintf(fp,"\n");
819
820 fprintf(fp,"\n");
821 fprintf(fp, "\t\t/* Commit the work */\n");
822 fprintf(fp, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
823 "\t\t\t\tbuff, event_length);\n");
824 fprintf(fp, "\t\tltt_write_commit_counter("
825 "channel->rchan->buf[smp_processor_id()],\n"
826 "\t\t\t\tbuff);\n");
827
828 /* End of traces iteration */
829 fprintf(fp, "\t}\n\n");
830
831 fprintf(fp, "\n");
832 // The generated preempt_check_resched is not dangerous because
833 // interrupts are disabled.
834 fprintf(fp, "\tspin_unlock(&ltt_traces.locks[smp_processor_id()]);\n");
835
836 fprintf(fp, "unlock:\n");
837 fprintf(fp, "\tbarrier();\n");
838 fprintf(fp, "\tltt_nesting[smp_processor_id()]--;\n");
839 fprintf(fp, "\t/* Re-enable interrupts */\n");
840 fprintf(fp, "\tlocal_irq_restore(_flags);\n");
841 fprintf(fp, "\tpreempt_enable_no_resched();\n");
842 //fprintf(fp, "\tpreempt_check_resched();\n");
843
844 //call trace function
845 //fprintf(fp,"\n\t//call trace function\n");
846 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
847 fprintf(fp,"}\n");
848 fprintf(fp, "#endif //CONFIG_LTT\n\n");
849 }
850
851 }
852
853 /*****************************************************************************
854 *Function name
855 * getTypeStr : generate type string
856 *Input Params
857 * td : a type descriptor
858 *Return Values
859 * char * : type string
860 ****************************************************************************/
861 char * getTypeStr(type_descriptor * td){
862 type_descriptor * t ;
863
864 switch(td->type){
865 case INT:
866 return intOutputTypes[td->size];
867 case UINT:
868 return uintOutputTypes[td->size];
869 case POINTER:
870 return "void *";
871 case LONG:
872 return "long";
873 case ULONG:
874 return "unsigned long";
875 case SIZE_T:
876 return "size_t";
877 case SSIZE_T:
878 return "ssize_t";
879 case OFF_T:
880 return "off_t";
881 case FLOAT:
882 return floatOutputTypes[td->size];
883 case STRING:
884 return "const char";
885 case ENUM:
886 return uintOutputTypes[td->size];
887 case ARRAY:
888 case SEQUENCE:
889 t = td->nested_type;
890 switch(t->type){
891 case INT:
892 return intOutputTypes[t->size];
893 case UINT:
894 return uintOutputTypes[t->size];
895 case POINTER:
896 return "void *";
897 case LONG:
898 return "long";
899 case ULONG:
900 return "unsigned long";
901 case SIZE_T:
902 return "size_t";
903 case SSIZE_T:
904 return "ssize_t";
905 case OFF_T:
906 return "off_t";
907 case FLOAT:
908 return floatOutputTypes[t->size];
909 case STRING:
910 return "const char";
911 case ENUM:
912 return uintOutputTypes[t->size];
913 default :
914 error_callback(NULL,"Nested struct is not supportted");
915 break;
916 }
917 break;
918 case STRUCT: //for now we do not support nested struct
919 error_callback(NULL,"Nested struct is not supportted");
920 break;
921 default:
922 error_callback(NULL,"No type information");
923 break;
924 }
925 return NULL;
926 }
927
928 /*****************************************************************************
929 *Function name
930 * generateLoaderfile: generate a facility loaded .h file
931 *Input Params
932 * fp : file to be written to
933 * facName : name of facility
934 * nbEvent : number of events in the facility
935 * checksum : checksum for the facility
936 ****************************************************************************/
937 void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
938 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
939 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
940 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
941 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
942 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
943
944 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
945 facName);
946 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
947 facName, checksum);
948 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum);
949 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName);
950 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent);
951 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
952 }
953
954 void generateCfile(FILE * fp, char * filefacname){
955
956 fprintf(fp, "/*\n");
957 fprintf(fp, " * ltt-facility-loader-%s.c\n", filefacname);
958 fprintf(fp, " *\n");
959 fprintf(fp, " * (C) Copyright 2005 - \n");
960 fprintf(fp, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
961 fprintf(fp, " *\n");
962 fprintf(fp, " * Contains the LTT facility loader.\n");
963 fprintf(fp, " *\n");
964 fprintf(fp, " */\n");
965 fprintf(fp, "\n");
966 fprintf(fp, "\n");
967 fprintf(fp, "#include <linux/ltt-facilities.h>\n");
968 fprintf(fp, "#include <linux/module.h>\n");
969 fprintf(fp, "#include <linux/init.h>\n");
970 fprintf(fp, "#include <linux/config.h>\n");
971 fprintf(fp, "#include \"ltt-facility-loader-%s.h\"\n", filefacname);
972 fprintf(fp, "\n");
973 fprintf(fp, "\n");
974 fprintf(fp, "#ifdef CONFIG_LTT\n");
975 fprintf(fp, "\n");
976 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
977 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
978 fprintf(fp, "\n");
979 fprintf(fp, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
980 fprintf(fp, "\n");
981 fprintf(fp, "#define SYMBOL_STRING(sym) #sym\n");
982 fprintf(fp, "\n");
983 fprintf(fp, "static struct ltt_facility facility = {\n");
984 fprintf(fp, "\t.name = ltt_facility_name,\n");
985 fprintf(fp, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
986 fprintf(fp, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
987 fprintf(fp, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL)\n");
988 fprintf(fp, "};\n");
989 fprintf(fp, "\n");
990 fprintf(fp, "#ifndef MODULE\n");
991 fprintf(fp, "\n");
992 fprintf(fp, "/* Built-in facility. */\n");
993 fprintf(fp, "\n");
994 fprintf(fp, "static int __init facility_init(void)\n");
995 fprintf(fp, "{\n");
996 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname);
997 fprintf(fp, "\n");
998 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
999 fprintf(fp, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1000 fprintf(fp, "\t\n");
1001 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
1002 fprintf(fp, "}\n");
1003 fprintf(fp, "__initcall(facility_init);\n");
1004 fprintf(fp, "\n");
1005 fprintf(fp, "\n");
1006 fprintf(fp, "\n");
1007 fprintf(fp, "#else \n");
1008 fprintf(fp, "\n");
1009 fprintf(fp, "/* Dynamic facility. */\n");
1010 fprintf(fp, "\n");
1011 fprintf(fp, "static int __init facility_init(void)\n");
1012 fprintf(fp, "{\n");
1013 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname);
1014 fprintf(fp, "\n");
1015 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
1016 fprintf(fp, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
1017 fprintf(fp, "\n");
1018 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
1019 fprintf(fp, "}\n");
1020 fprintf(fp, "\n");
1021 fprintf(fp, "static void __exit facility_exit(void)\n");
1022 fprintf(fp, "{\n");
1023 fprintf(fp, "\tint err;\n");
1024 fprintf(fp, "\n");
1025 fprintf(fp, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
1026 fprintf(fp, "\tif(err != 0)\n");
1027 fprintf(fp, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
1028 fprintf(fp, "\n");
1029 fprintf(fp, "}\n");
1030 fprintf(fp, "\n");
1031 fprintf(fp, "module_init(facility_init)\n");
1032 fprintf(fp, "module_exit(facility_exit)\n");
1033 fprintf(fp, "\n");
1034 fprintf(fp, "\n");
1035 fprintf(fp, "MODULE_LICENSE(\"GPL\");\n");
1036 fprintf(fp, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1037 fprintf(fp, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1038 fprintf(fp, "\n");
1039 fprintf(fp, "#endif //MODULE\n");
1040 fprintf(fp, "\n");
1041 fprintf(fp, "#endif //CONFIG_LTT\n");
1042 }
1043
1044
This page took 0.058481 seconds and 5 git commands to generate.