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