fix header sizes and read trace header
[lttv.git] / genevent / genevent.c
CommitLineData
3888436c 1/*
2
3genevent.c: Generate helper declarations and functions to trace events
4 from an event description file.
5
6Copyright (C) 2002, Xianxiu Yang
7Copyright (C) 2002, Michel Dagenais
8
9This 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
11the Free Software Foundation; version 2 of the License.
12
13This 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>
31cbc5d3 39#include <ctype.h>
3888436c 40#include <stdio.h>
41#include <stdarg.h>
42#include <linux/errno.h>
d7ed29cd 43#include <assert.h>
3888436c 44
45#include "parser.h"
46#include "genevent.h"
47
4a65a3b9 48#define max(a,b) ((a)<(b))?(b):(a)
49
3888436c 50/* Named types may be referenced from anywhere */
51
52facility * fac;
53
4a65a3b9 54unsigned alignment = 0;
55
3888436c 56int 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");
4a65a3b9 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");
3888436c 69 exit(1);
70 }
71
72 in.buffer = buffer;
73 in.error = error_callback;
74
75 for(i = 1 ; i < argc ; i++) {
4a65a3b9 76
77 if(strcmp("-a", argv[i])==0) {
cc226d37 78 if(i >= argc-1) {
4a65a3b9 79 printf("Error : missing argument to -a\n");
80 exit(1);
81 } else i++;
82 alignment = atoi(argv[i]);
cc226d37 83 } else {
4a65a3b9 84
cc226d37 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 }
3888436c 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 ****************************************************************************/
142void generateFile(char *name){
a8f6f123 143 char *loadName, *hName, *hIdName, *cName, *tmp, *tmp2;
144 FILE * lFp, *hFp, *iFp, *cFp;
3888436c 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 }
6d387597 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;
a8f6f123 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;
6d387597 177 lFp = fopen(loadName,"w");
178 if(!lFp){
179 printf("Cannot open the file : %s\n",loadName);
3888436c 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 }
a8f6f123 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 }
3888436c 200
6d387597 201 free(loadName);
3888436c 202 free(hName);
a8f6f123 203 free(hIdName);
204 free(cName);
3888436c 205
206 generateChecksum(fac->name, &checksum, &(fac->events));
207
208 /* generate .h file, event enumeration then structures and functions */
a8f6f123 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);
1bedc199 211 fprintf(iFp, "#ifdef CONFIG_LTT\n");
a8f6f123 212 generateEnumEvent(iFp, fac->name, &nbEvent, checksum);
1bedc199 213 fprintf(iFp, "#endif //CONFIG_LTT\n");
a8f6f123 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);
1bedc199 219 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
a8f6f123 220 generateTypeDefs(hFp, fac->name);
31cbc5d3 221 generateStructFunc(hFp, fac->name,checksum);
1bedc199 222 //fprintf(hFp, "#endif //CONFIG_LTT\n");
a8f6f123 223 fprintf(hFp, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
3888436c 224
6d387597 225 /* generate .h file, calls to register the facility at init time */
8c6ca411 226 generateLoaderfile(lFp,fac->name,nbEvent,checksum,fac->capname);
3888436c 227
a8f6f123 228 // create ltt-facility-loader-facname.c
229 generateCfile(cFp, tmp);
230
3888436c 231 fclose(hFp);
a8f6f123 232 fclose(iFp);
6d387597 233 fclose(lFp);
a8f6f123 234 fclose(cFp);
235
3888436c 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 ****************************************************************************/
31cbc5d3 248void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long checksum) {
3888436c 249 int pos = 0;
250
a8f6f123 251 fprintf(fp,"#include <linux/ltt-facilities.h>\n\n");
3888436c 252
253 fprintf(fp,"/**** facility handle ****/\n\n");
a8f6f123 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);
3888436c 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++) {
a8f6f123 261 fprintf(fp,"\tevent_%s", ((event *)(fac->events.array[pos]))->name);
3888436c 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
31cbc5d3 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 ****************************************************************************/
cb1eb7ce 285
31cbc5d3 286static void
287printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
9774b764 288 int * whichTypeFirst, int * hasStrSeq, int * structCount,
289 type_descriptor *type)
31cbc5d3 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;
a8f6f123 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// }
31cbc5d3 306 if (flag == 0) {
307 flag = 1;
308
cb1eb7ce 309 fprintf(fp,"struct %s_%s",name, facName);
310 if (structCount) {
a8f6f123 311 fprintf(fp, "_%d {\n",++*structCount);
cb1eb7ce 312 } else {
313 fprintf(fp, " {\n");
314 }
31cbc5d3 315 }
cb1eb7ce 316 fprintf(fp, "\t%s %s; /* %s */\n",
317 getTypeStr(td),fld->name,fld->description );
a8f6f123 318#if 0
31cbc5d3 319 } else {
cb1eb7ce 320 if (*whichTypeFirst == 0) {
31cbc5d3 321 //string or sequence or array first
cb1eb7ce 322 *whichTypeFirst = 2;
323 }
324 (*hasStrSeq)++;
325 if(flag) {
326 fprintf(fp,"} __attribute__ ((packed));\n\n");
327 }
328 flag = 0;
31cbc5d3 329 }
a8f6f123 330#endif //0
31cbc5d3 331 }
332
333 if(flag) {
4a65a3b9 334 unsigned align = max(alignment, type->alignment);
335
336 if(align == 0)
9774b764 337 fprintf(fp,"} __attribute__ ((packed));\n\n");
338 else {
4a65a3b9 339 if(align != 1 && align != 2
340 && align != 4 && align != 8) {
341 printf("Wrong alignment %i, using packed.\n", align);
9774b764 342 fprintf(fp,"} __attribute__ ((packed));\n\n");
343 } else
4a65a3b9 344 fprintf(fp,"} __attribute__ ((aligned(%i)));\n\n", align);
9774b764 345 }
31cbc5d3 346 }
347}
348
349
350/*****************************************************************************
351 *Function name
352 * generateHfile : Create the typedefs
353 *Input Params
354 * fp : file to be written to
355 ****************************************************************************/
356void
a8f6f123 357generateTypeDefs(FILE * fp, char *facName)
31cbc5d3 358{
359 int pos, tmp = 1;
360
a8f6f123 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
9774b764 366#if 0 //broken
31cbc5d3 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 }
9774b764 377#endif //0
31cbc5d3 378}
379
380
3888436c 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 ****************************************************************************/
388void generateEnumDefinition(FILE * fp, type_descriptor * type){
389 int pos;
390
a8f6f123 391 if(type->already_printed) return;
392
3888436c 393 fprintf(fp,"enum {\n");
394 for(pos = 0; pos < type->labels.position; pos++){
a8f6f123 395 fprintf(fp,"\tLTT_ENUM_%s", type->labels.array[pos]);
8c6ca411 396 if (pos != type->labels.position - 1) fprintf(fp,",");
a8f6f123 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");
3888436c 401 }
8c6ca411 402 fprintf(fp,"};\n\n\n");
44cac8a9 403
a8f6f123 404 type->already_printed = 1;
3888436c 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 ****************************************************************************/
31cbc5d3 414void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
3888436c 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;
d7ed29cd 424 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",
425 ev->name);
a8f6f123 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 //}
3888436c 433
434 //if fields contain enum, print out enum definition
d7ed29cd 435 //MD : fixed in generateEnumDefinition to do not print the same enum
436 //twice.
a8f6f123 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 }
3888436c 442
443 //default: no string, array or sequence in the event
444 hasStrSeq = 0;
445 whichTypeFirst = 0;
3888436c 446 structCount = 0;
31cbc5d3 447
448 //structure for kernel
a8f6f123 449 if(ev->type != 0)
450 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
9774b764 451 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount,
452 ev->type);
3888436c 453
1bedc199 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
3888436c 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);
a8f6f123 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 }
d7ed29cd 502 fprintf(fp,")\n{\n");
3888436c 503
1bedc199 504
505
3888436c 506 //allocate buffer
d7ed29cd 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");
a8f6f123 512 fprintf(fp, "\tunsigned long _flags;\n");
2f74104a 513 fprintf(fp, "\tvoid *buff;\n");
e8907e11 514 fprintf(fp, "\tunsigned old_offset;\n");
2f74104a 515 fprintf(fp, "\tunsigned int header_length;\n");
c0d2d4d4 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.
1bedc199 518 fprintf(fp, "\tunsigned char _offset;\n");
519 fprintf(fp, "\tstruct rchan_buf *buf;\n");
5e07c65f 520 fprintf(fp, "\tstruct timeval delta;\n");
521 fprintf(fp, "\tu64 tsc;\n");
e8907e11 522 fprintf(fp, "\tchar *ptr;\n");
2f74104a 523
a8f6f123 524 if(ev->type != 0)
525 fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
d7ed29cd 526
1bedc199 527 /* Warning : this is done prior to taking locks :
528 * setting this value must be done at the end of the trace activation.
529 * (we don't care for trace removal, as the list of traces is protected : it
530 * just won't iterate on any trace). */
531 fprintf(fp,
532 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
533
2f74104a 534 fprintf(fp, "\t/* Disable interrupts. */\n");
535 fprintf(fp, "\tlocal_irq_save(_flags);\n");
536 fprintf(fp, "\tpreempt_disable();\n\n");
537
538 fprintf(fp, "\tltt_nesting[smp_processor_id()]++;\n");
1bedc199 539 fprintf(fp, "\tbarrier();\n");
540 fprintf(fp, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
2f74104a 541 fprintf(fp, "\tspin_lock(&ltt_traces.locks[smp_processor_id()]);\n\n");
542
d7ed29cd 543 fprintf(fp,
544 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
a8f6f123 545 "\t\t\t\tevent_%s);\n",
d7ed29cd 546 facName, checksum, ev->name);
547 fprintf(fp,"\n");
548
a8f6f123 549 /* For each trace */
d7ed29cd 550 fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
a8f6f123 551 fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
0f5d12e9 552
553 //length of buffer : length of all structures
0f5d12e9 554 // if(ev->type == 0) fprintf(fp, "0");
555
1bedc199 556 fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
557 fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
5e07c65f 558 fprintf(fp, "\n");
1bedc199 559 /* Warning : not atomic reservation : event size depends on the current
560 * address for alignment */
5e07c65f 561 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
0f5d12e9 562 // Replaces _offset
c3e1c4c4 563 /* NOTE2 : as the read old address from memory must come before any
564 * protected event, let's add a memory barrier() to make sure the compiler
565 * will not reorder this read. */
5e07c65f 566 fprintf(fp, "\t\tdo {\n");
e8907e11 567 fprintf(fp, "\t\t\told_offset = buf->offset;\n");
c3e1c4c4 568 fprintf(fp, "\t\t\tbarrier();\n");
e8907e11 569 fprintf(fp, "\t\t\tptr = (char*)buf->data + old_offset;\n");
c0d2d4d4 570
571
5e07c65f 572 fprintf(fp, "\t\t\theader_length = ltt_get_event_header_data(trace, "
573 "channel,\n"
e8907e11 574 "\t\t\t\t\t\t\t\t\t\tptr, &_offset, &delta, &tsc);\n");
5e07c65f 575
c0d2d4d4 576 fprintf(fp, "\t\t\tptr += _offset + header_length;\n");
0f5d12e9 577
578 for(pos1=0;pos1<structCount;pos1++){
579
4a65a3b9 580 unsigned align = max(alignment, ev->type->alignment);
581 if(align > 1) {
c0d2d4d4 582 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
4a65a3b9 583 align, align, align);
0f5d12e9 584 }
c0d2d4d4 585 fprintf(fp,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev->name,
0f5d12e9 586 facName,pos1+1);
587// if(pos1 != structCount-1) fprintf(fp," + ");
588 }
589
590 //length of buffer : length of all arrays, sequences and strings
591 seqCount = 0;
592 strCount = 0;
593 flag = 0;
594 if(ev->type != 0)
595 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
596 fld = (field *)ev->type->fields.array[pos1];
597 td = fld->type;
598 if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
599 if(td->type == SEQUENCE) {
4a65a3b9 600
601 unsigned align = max(alignment, td->alignment);
602 if(align > 1) {
603 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
604 align, align, align);
605 }
606 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
607 if(align > 1) {
608 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
609 align, align, align);
610 }
611 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
612 getTypeStr(td), seqCount);
613
0f5d12e9 614 } else if(td->type==STRING) {
4a65a3b9 615 unsigned align = max(alignment, td->alignment);
616 if(align > 1) {
c0d2d4d4 617 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
4a65a3b9 618 align, align, align);
0f5d12e9 619 }
c0d2d4d4 620 fprintf(fp,"ptr += strlength_%d + 1;\n",
0f5d12e9 621 ++strCount);
622 }
623 else if(td->type==ARRAY) {
4a65a3b9 624 unsigned align = max(alignment, td->alignment);
625 if(align > 1) {
c0d2d4d4 626 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 627 align, align, align);
0f5d12e9 628 }
c0d2d4d4 629 fprintf(fp,"\t\t\tptr += sizeof(%s) * %d;\n",
0f5d12e9 630 getTypeStr(td),td->size);
631 if(structCount == 0) flag = 1;
632 }
633 }
634 }
c0d2d4d4 635 fprintf(fp, "\t\t\tevent_length = (unsigned long)ptr -"
e8907e11 636 "(unsigned long)(buf->data + old_offset);\n");
c3e1c4c4 637
638 /* let's put some protection before the cmpxchg : the space reservation and
639 * the get TSC are not dependant from each other. I don't want the compiler
640 * to reorder those in the wrong order. And relay_reserve is inline, so
641 * _yes_, the compiler could mess it up. */
642 fprintf(fp, "\t\t\tbarrier();\n");
5e07c65f 643 fprintf(fp, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
e8907e11 644 "old_offset);\n");
5e07c65f 645 fprintf(fp, "\n");
646 fprintf(fp, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
647 fprintf(fp, "\n");
648
649
d7ed29cd 650 /* Reserve the channel */
5e07c65f 651 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
a8f6f123 652 fprintf(fp, "\t\tif(buff == NULL) {\n");
653 fprintf(fp, "\t\t\t/* Buffer is full*/\n");
654 fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
655 fprintf(fp, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
e3cc790d 656 fprintf(fp, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
a8f6f123 657 fprintf(fp, "\t\t}\n");
d7ed29cd 658
a8f6f123 659 /* DEBUG */
5e07c65f 660 //fprintf(fp, "\t\tif(resret == 1) {\n");
661 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
662 // facName, checksum, ev->name);
663 //fprintf(fp, "\t\t}\n");
a8f6f123 664
665 /* Write the header */
c0d2d4d4 666 fprintf(fp, "\n");
e8907e11 667 fprintf(fp,"\t\tlength = event_length - _offset - header_length;\n");
a8f6f123 668 fprintf(fp, "\n");
669 fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
c0d2d4d4 670 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
671 "\t\t\t\t&delta, &tsc);\n",
a8f6f123 672 facName, checksum, ev->name);
673 fprintf(fp, "\n");
5e07c65f 674
675 if(ev->type != 0)
676 fprintf(fp, "\t\tchar *ptr = (char*)buff + _offset + header_length;\n");
0f5d12e9 677
678
d7ed29cd 679 //declare a char pointer if needed : starts at the end of the structs.
0f5d12e9 680 //if(structCount + hasStrSeq > 1) {
681 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
682 // for(pos1=0;pos1<structCount;pos1++){
683 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
684 // }
685 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
686 //}
d7ed29cd 687
688 // Declare an alias pointer of the struct type to the beginning
689 // of the reserved area, just after the event header.
0f5d12e9 690 if(ev->type != 0) {
4a65a3b9 691 unsigned align = max(alignment, td->alignment);
692 if(align > 1) {
0f5d12e9 693 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 694 align, align, align);
0f5d12e9 695 }
696
697 fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
a8f6f123 698 ev->name, facName);
0f5d12e9 699 }
d7ed29cd 700 //allocate memory for new struct and initialize it
701 //if(whichTypeFirst == 1){ //struct first
a8f6f123 702 //for(pos1=0;pos1<structCount;pos1++){
703 // if(pos1==0) fprintf(fp,
d7ed29cd 704 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
705 // ev->name, facName,ev->name, facName);
706 //MD disabled else fprintf(fp,
707 // "\tstruct %s_%s_%d __%d;\n",
708 // ev->name, facName,pos1+1,pos1+1);
709 //}
710 //}else if(whichTypeFirst == 2){
711 // for(pos1=0;pos1<structCount;pos1++)
a8f6f123 712 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
d7ed29cd 713 // ev->name, facName,pos1+1,pos1+1);
714 //}
3888436c 715 fprintf(fp,"\n");
716
d7ed29cd 717 if(structCount) fprintf(fp,"\t\t//initialize structs\n");
718 //flag = 0;
719 //structCount = 0;
a8f6f123 720 if(ev->type != 0)
721 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
722 fld = (field *)ev->type->fields.array[pos1];
723 td = fld->type;
724 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
725 //if(flag == 0){
726 // flag = 1;
727 // structCount++;
728 // if(structCount > 1) fprintf(fp,"\n");
729 //}
730 fprintf(fp, "\t\t__1->%s = %s;\n", fld->name, fld->name );
731
732 //if(structCount == 1 && whichTypeFirst == 1)
733 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
734 //else
735 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
736 }
737 //else flag = 0;
738 }
739 if(structCount) fprintf(fp,"\n");
3888436c 740 //set ptr to the end of first struct if needed;
1bedc199 741 //if(structCount + hasStrSeq > 1){
742 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
743 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
744 //}
3888436c 745
746 //copy struct, sequence and string to buffer
747 seqCount = 0;
748 strCount = 0;
749 flag = 0;
750 structCount = 0;
a8f6f123 751 if(ev->type != 0)
752 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
753 fld = (field *)ev->type->fields.array[pos1];
754 td = fld->type;
755 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
756 // if(flag == 0) structCount++;
757 // flag++;
758 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
759 // assert(0); // MD : disabled !
760 // fprintf(fp,"\t//copy struct to buffer\n");
761 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
762 // structCount, ev->name, facName,structCount);
763 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
764 // ev->name, facName,structCount);
765 // }
766 // }
767 //else if(td->type == SEQUENCE){
768 if(td->type == SEQUENCE){
769 flag = 0;
770 fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
0f5d12e9 771
4a65a3b9 772 unsigned align = max(alignment, td->alignment);
773 if(align > 1) {
0f5d12e9 774 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 775 align, align, align);
0f5d12e9 776 }
a8f6f123 777 fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
778 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
4a65a3b9 779 if(align > 1) {
0f5d12e9 780 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 781 align, align, align);
0f5d12e9 782 }
a8f6f123 783 fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
784 fld->name, getTypeStr(td), seqCount);
0f5d12e9 785 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
a8f6f123 786 getTypeStr(td), seqCount);
787 }
788 else if(td->type==STRING){
789 flag = 0;
790 fprintf(fp,"\t\t//copy string to buffer\n");
791 fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
4a65a3b9 792 unsigned align = max(alignment, td->alignment);
793 if(align > 1) {
0f5d12e9 794 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 795 align, align, align);
0f5d12e9 796 }
a8f6f123 797 fprintf(fp,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
798 fld->name, strCount);
799 fprintf(fp,"\t\t\tptr += strlength_%d + 1;\n",strCount);
800 fprintf(fp,"\t\t}else{\n");
801 fprintf(fp,"\t\t\t*ptr = '\\0';\n");
802 fprintf(fp,"\t\t\tptr += 1;\n");
803 fprintf(fp,"\t\t}\n\n");
804 }else if(td->type==ARRAY){
805 flag = 0;
806 fprintf(fp,"\t//copy array to buffer\n");
4a65a3b9 807 unsigned align = max(alignment, td->alignment);
808 if(align > 1) {
0f5d12e9 809 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 810 align, align, align);
0f5d12e9 811 }
a8f6f123 812 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
813 fld->name, getTypeStr(td), td->size);
814 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
815 }
816 }
3888436c 817 if(structCount + seqCount > 1) fprintf(fp,"\n");
818
d7ed29cd 819 fprintf(fp,"\n");
820 fprintf(fp, "\t\t/* Commit the work */\n");
a8f6f123 821 fprintf(fp, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
822 "\t\t\t\tbuff, event_length);\n");
1bedc199 823 fprintf(fp, "\t\tltt_write_commit_counter("
824 "channel->rchan->buf[smp_processor_id()],\n"
825 "\t\t\t\tbuff);\n");
d7ed29cd 826
827 /* End of traces iteration */
828 fprintf(fp, "\t}\n\n");
829
a8f6f123 830 fprintf(fp, "\n");
1bedc199 831 // The generated preempt_check_resched is not dangerous because
832 // interrupts are disabled.
833 fprintf(fp, "\tspin_unlock(&ltt_traces.locks[smp_processor_id()]);\n");
2f74104a 834
835 fprintf(fp, "unlock:\n");
1bedc199 836 fprintf(fp, "\tbarrier();\n");
2f74104a 837 fprintf(fp, "\tltt_nesting[smp_processor_id()]--;\n");
838 fprintf(fp, "\t/* Re-enable interrupts */\n");
839 fprintf(fp, "\tlocal_irq_restore(_flags);\n");
1bedc199 840 fprintf(fp, "\tpreempt_enable_no_resched();\n");
2f74104a 841 //fprintf(fp, "\tpreempt_check_resched();\n");
842
3888436c 843 //call trace function
d7ed29cd 844 //fprintf(fp,"\n\t//call trace function\n");
845 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
1bedc199 846 fprintf(fp,"}\n");
847 fprintf(fp, "#endif //CONFIG_LTT\n\n");
3888436c 848 }
849
850}
851
852/*****************************************************************************
853 *Function name
854 * getTypeStr : generate type string
855 *Input Params
856 * td : a type descriptor
857 *Return Values
858 * char * : type string
859 ****************************************************************************/
860char * getTypeStr(type_descriptor * td){
861 type_descriptor * t ;
862
863 switch(td->type){
864 case INT:
865 return intOutputTypes[td->size];
866 case UINT:
867 return uintOutputTypes[td->size];
31cbc5d3 868 case POINTER:
869 return "void *";
870 case LONG:
871 return "long";
872 case ULONG:
873 return "unsigned long";
874 case SIZE_T:
875 return "size_t";
876 case SSIZE_T:
877 return "ssize_t";
878 case OFF_T:
879 return "off_t";
3888436c 880 case FLOAT:
881 return floatOutputTypes[td->size];
882 case STRING:
a8f6f123 883 return "const char";
3888436c 884 case ENUM:
885 return uintOutputTypes[td->size];
886 case ARRAY:
887 case SEQUENCE:
888 t = td->nested_type;
889 switch(t->type){
890 case INT:
a8f6f123 891 return intOutputTypes[t->size];
3888436c 892 case UINT:
a8f6f123 893 return uintOutputTypes[t->size];
31cbc5d3 894 case POINTER:
895 return "void *";
896 case LONG:
897 return "long";
898 case ULONG:
899 return "unsigned long";
900 case SIZE_T:
901 return "size_t";
902 case SSIZE_T:
903 return "ssize_t";
904 case OFF_T:
905 return "off_t";
3888436c 906 case FLOAT:
a8f6f123 907 return floatOutputTypes[t->size];
3888436c 908 case STRING:
a8f6f123 909 return "const char";
3888436c 910 case ENUM:
a8f6f123 911 return uintOutputTypes[t->size];
3888436c 912 default :
a8f6f123 913 error_callback(NULL,"Nested struct is not supportted");
914 break;
3888436c 915 }
916 break;
917 case STRUCT: //for now we do not support nested struct
918 error_callback(NULL,"Nested struct is not supportted");
919 break;
920 default:
921 error_callback(NULL,"No type information");
922 break;
923 }
924 return NULL;
925}
926
927/*****************************************************************************
928 *Function name
6d387597 929 * generateLoaderfile: generate a facility loaded .h file
3888436c 930 *Input Params
931 * fp : file to be written to
932 * facName : name of facility
933 * nbEvent : number of events in the facility
934 * checksum : checksum for the facility
935 ****************************************************************************/
8c6ca411 936void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
a8f6f123 937 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
938 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
8c6ca411 939 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
44cac8a9 940 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
6d387597 941 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
942
a8f6f123 943 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
44cac8a9 944 facName);
a8f6f123 945 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
6d387597 946 facName, checksum);
a8f6f123 947 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum);
948 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName);
949 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent);
950 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
951}
952
953void generateCfile(FILE * fp, char * filefacname){
954
955 fprintf(fp, "/*\n");
956 fprintf(fp, " * ltt-facility-loader-%s.c\n", filefacname);
957 fprintf(fp, " *\n");
958 fprintf(fp, " * (C) Copyright 2005 - \n");
959 fprintf(fp, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
960 fprintf(fp, " *\n");
961 fprintf(fp, " * Contains the LTT facility loader.\n");
962 fprintf(fp, " *\n");
963 fprintf(fp, " */\n");
964 fprintf(fp, "\n");
965 fprintf(fp, "\n");
966 fprintf(fp, "#include <linux/ltt-facilities.h>\n");
967 fprintf(fp, "#include <linux/module.h>\n");
968 fprintf(fp, "#include <linux/init.h>\n");
969 fprintf(fp, "#include <linux/config.h>\n");
970 fprintf(fp, "#include \"ltt-facility-loader-%s.h\"\n", filefacname);
971 fprintf(fp, "\n");
972 fprintf(fp, "\n");
973 fprintf(fp, "#ifdef CONFIG_LTT\n");
974 fprintf(fp, "\n");
975 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
976 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
977 fprintf(fp, "\n");
978 fprintf(fp, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
979 fprintf(fp, "\n");
980 fprintf(fp, "#define SYMBOL_STRING(sym) #sym\n");
981 fprintf(fp, "\n");
982 fprintf(fp, "static struct ltt_facility facility = {\n");
983 fprintf(fp, "\t.name = ltt_facility_name,\n");
984 fprintf(fp, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
985 fprintf(fp, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
e8907e11 986 fprintf(fp, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
987 fprintf(fp, "\t.alignment = %u\n", alignment); /* default alignment */
a8f6f123 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");
3888436c 1042}
1043
1044
This page took 0.070321 seconds and 4 git commands to generate.