add reserve, tsc and alignment atomicity with cmpxchg : add memory barrier to protect.
[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
48/* Named types may be referenced from anywhere */
49
50facility * fac;
51
52int 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) {
a8f6f123 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);
31cbc5d3 95 }
a8f6f123 96 else in.error(&in,"facility token was expected");
3888436c 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 ****************************************************************************/
125void generateFile(char *name){
a8f6f123 126 char *loadName, *hName, *hIdName, *cName, *tmp, *tmp2;
127 FILE * lFp, *hFp, *iFp, *cFp;
3888436c 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 }
6d387597 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;
a8f6f123 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;
6d387597 160 lFp = fopen(loadName,"w");
161 if(!lFp){
162 printf("Cannot open the file : %s\n",loadName);
3888436c 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 }
a8f6f123 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 }
3888436c 183
6d387597 184 free(loadName);
3888436c 185 free(hName);
a8f6f123 186 free(hIdName);
187 free(cName);
3888436c 188
189 generateChecksum(fac->name, &checksum, &(fac->events));
190
191 /* generate .h file, event enumeration then structures and functions */
a8f6f123 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);
1bedc199 194 fprintf(iFp, "#ifdef CONFIG_LTT\n");
a8f6f123 195 generateEnumEvent(iFp, fac->name, &nbEvent, checksum);
1bedc199 196 fprintf(iFp, "#endif //CONFIG_LTT\n");
a8f6f123 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);
1bedc199 202 //fprintf(hFp, "#ifdef CONFIG_LTT\n");
a8f6f123 203 generateTypeDefs(hFp, fac->name);
31cbc5d3 204 generateStructFunc(hFp, fac->name,checksum);
1bedc199 205 //fprintf(hFp, "#endif //CONFIG_LTT\n");
a8f6f123 206 fprintf(hFp, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
3888436c 207
6d387597 208 /* generate .h file, calls to register the facility at init time */
8c6ca411 209 generateLoaderfile(lFp,fac->name,nbEvent,checksum,fac->capname);
3888436c 210
a8f6f123 211 // create ltt-facility-loader-facname.c
212 generateCfile(cFp, tmp);
213
3888436c 214 fclose(hFp);
a8f6f123 215 fclose(iFp);
6d387597 216 fclose(lFp);
a8f6f123 217 fclose(cFp);
218
3888436c 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 ****************************************************************************/
31cbc5d3 231void generateEnumEvent(FILE *fp, char *facName, int * nbEvent, unsigned long checksum) {
3888436c 232 int pos = 0;
233
a8f6f123 234 fprintf(fp,"#include <linux/ltt-facilities.h>\n\n");
3888436c 235
236 fprintf(fp,"/**** facility handle ****/\n\n");
a8f6f123 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);
3888436c 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++) {
a8f6f123 244 fprintf(fp,"\tevent_%s", ((event *)(fac->events.array[pos]))->name);
3888436c 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
31cbc5d3 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 ****************************************************************************/
cb1eb7ce 268
31cbc5d3 269static void
270printStruct(FILE * fp, int len, void ** array, char * name, char * facName,
9774b764 271 int * whichTypeFirst, int * hasStrSeq, int * structCount,
272 type_descriptor *type)
31cbc5d3 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;
a8f6f123 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// }
31cbc5d3 289 if (flag == 0) {
290 flag = 1;
291
cb1eb7ce 292 fprintf(fp,"struct %s_%s",name, facName);
293 if (structCount) {
a8f6f123 294 fprintf(fp, "_%d {\n",++*structCount);
cb1eb7ce 295 } else {
296 fprintf(fp, " {\n");
297 }
31cbc5d3 298 }
cb1eb7ce 299 fprintf(fp, "\t%s %s; /* %s */\n",
300 getTypeStr(td),fld->name,fld->description );
a8f6f123 301#if 0
31cbc5d3 302 } else {
cb1eb7ce 303 if (*whichTypeFirst == 0) {
31cbc5d3 304 //string or sequence or array first
cb1eb7ce 305 *whichTypeFirst = 2;
306 }
307 (*hasStrSeq)++;
308 if(flag) {
309 fprintf(fp,"} __attribute__ ((packed));\n\n");
310 }
311 flag = 0;
31cbc5d3 312 }
a8f6f123 313#endif //0
31cbc5d3 314 }
315
316 if(flag) {
9774b764 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 }
31cbc5d3 327 }
328}
329
330
331/*****************************************************************************
332 *Function name
333 * generateHfile : Create the typedefs
334 *Input Params
335 * fp : file to be written to
336 ****************************************************************************/
337void
a8f6f123 338generateTypeDefs(FILE * fp, char *facName)
31cbc5d3 339{
340 int pos, tmp = 1;
341
a8f6f123 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
9774b764 347#if 0 //broken
31cbc5d3 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 }
9774b764 358#endif //0
31cbc5d3 359}
360
361
3888436c 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 ****************************************************************************/
369void generateEnumDefinition(FILE * fp, type_descriptor * type){
370 int pos;
371
a8f6f123 372 if(type->already_printed) return;
373
3888436c 374 fprintf(fp,"enum {\n");
375 for(pos = 0; pos < type->labels.position; pos++){
a8f6f123 376 fprintf(fp,"\tLTT_ENUM_%s", type->labels.array[pos]);
8c6ca411 377 if (pos != type->labels.position - 1) fprintf(fp,",");
a8f6f123 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");
3888436c 382 }
8c6ca411 383 fprintf(fp,"};\n\n\n");
44cac8a9 384
a8f6f123 385 type->already_printed = 1;
3888436c 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 ****************************************************************************/
31cbc5d3 395void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
3888436c 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;
d7ed29cd 405 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",
406 ev->name);
a8f6f123 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 //}
3888436c 414
415 //if fields contain enum, print out enum definition
d7ed29cd 416 //MD : fixed in generateEnumDefinition to do not print the same enum
417 //twice.
a8f6f123 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 }
3888436c 423
424 //default: no string, array or sequence in the event
425 hasStrSeq = 0;
426 whichTypeFirst = 0;
3888436c 427 structCount = 0;
31cbc5d3 428
429 //structure for kernel
a8f6f123 430 if(ev->type != 0)
431 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
9774b764 432 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount,
433 ev->type);
3888436c 434
1bedc199 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
3888436c 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);
a8f6f123 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 }
d7ed29cd 483 fprintf(fp,")\n{\n");
3888436c 484
1bedc199 485
486
3888436c 487 //allocate buffer
d7ed29cd 488 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
489 // write directly to the channel
490 fprintf(fp, "\tunsigned int index;\n");
491 fprintf(fp, "\tstruct ltt_channel_struct *channel;\n");
492 fprintf(fp, "\tstruct ltt_trace_struct *trace;\n");
a8f6f123 493 fprintf(fp, "\tunsigned long _flags;\n");
2f74104a 494 fprintf(fp, "\tvoid *buff;\n");
5e07c65f 495 fprintf(fp, "\tvoid *old_address;\n");
2f74104a 496 fprintf(fp, "\tunsigned int header_length;\n");
c0d2d4d4 497 fprintf(fp, "\tunsigned int event_length;\n"); // total size (incl hdr)
498 fprintf(fp, "\tunsigned int length;\n"); // Size of the event var data.
1bedc199 499 fprintf(fp, "\tunsigned char _offset;\n");
500 fprintf(fp, "\tstruct rchan_buf *buf;\n");
5e07c65f 501 fprintf(fp, "\tstruct timeval delta;\n");
502 fprintf(fp, "\tu64 tsc;\n");
2f74104a 503
a8f6f123 504 if(ev->type != 0)
505 fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
d7ed29cd 506
1bedc199 507 /* Warning : this is done prior to taking locks :
508 * setting this value must be done at the end of the trace activation.
509 * (we don't care for trace removal, as the list of traces is protected : it
510 * just won't iterate on any trace). */
511 fprintf(fp,
512 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
513
2f74104a 514 fprintf(fp, "\t/* Disable interrupts. */\n");
515 fprintf(fp, "\tlocal_irq_save(_flags);\n");
516 fprintf(fp, "\tpreempt_disable();\n\n");
517
518 fprintf(fp, "\tltt_nesting[smp_processor_id()]++;\n");
1bedc199 519 fprintf(fp, "\tbarrier();\n");
520 fprintf(fp, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
2f74104a 521 fprintf(fp, "\tspin_lock(&ltt_traces.locks[smp_processor_id()]);\n\n");
522
d7ed29cd 523 fprintf(fp,
524 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
a8f6f123 525 "\t\t\t\tevent_%s);\n",
d7ed29cd 526 facName, checksum, ev->name);
527 fprintf(fp,"\n");
528
a8f6f123 529 /* For each trace */
d7ed29cd 530 fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
a8f6f123 531 fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
0f5d12e9 532
533 //length of buffer : length of all structures
0f5d12e9 534 // if(ev->type == 0) fprintf(fp, "0");
535
1bedc199 536 fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
537 fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
5e07c65f 538 fprintf(fp, "\n");
1bedc199 539 /* Warning : not atomic reservation : event size depends on the current
540 * address for alignment */
5e07c65f 541 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
0f5d12e9 542 // Replaces _offset
c3e1c4c4 543 /* NOTE2 : as the read old address from memory must come before any
544 * protected event, let's add a memory barrier() to make sure the compiler
545 * will not reorder this read. */
5e07c65f 546 fprintf(fp, "\t\tdo {\n");
547 fprintf(fp, "\t\t\told_address = buf->data + buf->offset;\n");
c3e1c4c4 548 fprintf(fp, "\t\t\tbarrier();\n");
c0d2d4d4 549 fprintf(fp, "\t\t\tchar *ptr = (char*)old_address;\n");
550
551
5e07c65f 552 fprintf(fp, "\t\t\theader_length = ltt_get_event_header_data(trace, "
553 "channel,\n"
554 "\t\t\t\t\t\t\t\t\t\told_address, &_offset, &delta, &tsc);\n");
555
c0d2d4d4 556 fprintf(fp, "\t\t\tptr += _offset + header_length;\n");
0f5d12e9 557
558 for(pos1=0;pos1<structCount;pos1++){
559
560 if(ev->type->alignment > 1) {
c0d2d4d4 561 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
0f5d12e9 562 ev->type->alignment, ev->type->alignment, ev->type->alignment);
563 }
c0d2d4d4 564 fprintf(fp,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev->name,
0f5d12e9 565 facName,pos1+1);
566// if(pos1 != structCount-1) fprintf(fp," + ");
567 }
568
569 //length of buffer : length of all arrays, sequences and strings
570 seqCount = 0;
571 strCount = 0;
572 flag = 0;
573 if(ev->type != 0)
574 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
575 fld = (field *)ev->type->fields.array[pos1];
576 td = fld->type;
577 if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
578 if(td->type == SEQUENCE) {
579 if(td->alignment > 1) {
c0d2d4d4 580 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
0f5d12e9 581 td->alignment, td->alignment, td->alignment);
582 }
583 fprintf(fp,
c0d2d4d4 584 "\t\t\tptr += sizeof(%s) + (sizeof(%s) * seqlength_%d);\n",
0f5d12e9 585 uintOutputTypes[td->size], getTypeStr(td), ++seqCount);
586 } else if(td->type==STRING) {
587 if(td->alignment > 1) {
c0d2d4d4 588 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
0f5d12e9 589 td->alignment, td->alignment, td->alignment);
590 }
c0d2d4d4 591 fprintf(fp,"ptr += strlength_%d + 1;\n",
0f5d12e9 592 ++strCount);
593 }
594 else if(td->type==ARRAY) {
595 if(td->alignment > 1) {
c0d2d4d4 596 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
0f5d12e9 597 td->alignment, td->alignment, td->alignment);
598 }
c0d2d4d4 599 fprintf(fp,"\t\t\tptr += sizeof(%s) * %d;\n",
0f5d12e9 600 getTypeStr(td),td->size);
601 if(structCount == 0) flag = 1;
602 }
603 }
604 }
605 fprintf(fp,";\n");
606
c0d2d4d4 607 fprintf(fp, "\t\t\tevent_length = (unsigned long)ptr -"
608 "(unsigned long)old_address;\n");
c3e1c4c4 609
610 /* let's put some protection before the cmpxchg : the space reservation and
611 * the get TSC are not dependant from each other. I don't want the compiler
612 * to reorder those in the wrong order. And relay_reserve is inline, so
613 * _yes_, the compiler could mess it up. */
614 fprintf(fp, "\t\t\tbarrier();\n");
5e07c65f 615 fprintf(fp, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
616 "old_address);\n");
617 fprintf(fp, "\n");
618 fprintf(fp, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
619 fprintf(fp, "\n");
620
621
d7ed29cd 622 /* Reserve the channel */
5e07c65f 623 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
a8f6f123 624 fprintf(fp, "\t\tif(buff == NULL) {\n");
625 fprintf(fp, "\t\t\t/* Buffer is full*/\n");
626 fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
627 fprintf(fp, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
e3cc790d 628 fprintf(fp, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
a8f6f123 629 fprintf(fp, "\t\t}\n");
d7ed29cd 630
a8f6f123 631 /* DEBUG */
5e07c65f 632 //fprintf(fp, "\t\tif(resret == 1) {\n");
633 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
634 // facName, checksum, ev->name);
635 //fprintf(fp, "\t\t}\n");
a8f6f123 636
637 /* Write the header */
c0d2d4d4 638 fprintf(fp, "\n");
639 fprintf(fp,"\t\tlength = event_length - header_length;\n");
a8f6f123 640 fprintf(fp, "\n");
641 fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
c0d2d4d4 642 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
643 "\t\t\t\t&delta, &tsc);\n",
a8f6f123 644 facName, checksum, ev->name);
645 fprintf(fp, "\n");
5e07c65f 646
647 if(ev->type != 0)
648 fprintf(fp, "\t\tchar *ptr = (char*)buff + _offset + header_length;\n");
0f5d12e9 649
650
d7ed29cd 651 //declare a char pointer if needed : starts at the end of the structs.
0f5d12e9 652 //if(structCount + hasStrSeq > 1) {
653 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
654 // for(pos1=0;pos1<structCount;pos1++){
655 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
656 // }
657 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
658 //}
d7ed29cd 659
660 // Declare an alias pointer of the struct type to the beginning
661 // of the reserved area, just after the event header.
0f5d12e9 662 if(ev->type != 0) {
663 if(ev->type->alignment > 1) {
664 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
665 ev->type->alignment, ev->type->alignment, ev->type->alignment);
666 }
667
668 fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
a8f6f123 669 ev->name, facName);
0f5d12e9 670 }
d7ed29cd 671 //allocate memory for new struct and initialize it
672 //if(whichTypeFirst == 1){ //struct first
a8f6f123 673 //for(pos1=0;pos1<structCount;pos1++){
674 // if(pos1==0) fprintf(fp,
d7ed29cd 675 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
676 // ev->name, facName,ev->name, facName);
677 //MD disabled else fprintf(fp,
678 // "\tstruct %s_%s_%d __%d;\n",
679 // ev->name, facName,pos1+1,pos1+1);
680 //}
681 //}else if(whichTypeFirst == 2){
682 // for(pos1=0;pos1<structCount;pos1++)
a8f6f123 683 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
d7ed29cd 684 // ev->name, facName,pos1+1,pos1+1);
685 //}
3888436c 686 fprintf(fp,"\n");
687
d7ed29cd 688 if(structCount) fprintf(fp,"\t\t//initialize structs\n");
689 //flag = 0;
690 //structCount = 0;
a8f6f123 691 if(ev->type != 0)
692 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
693 fld = (field *)ev->type->fields.array[pos1];
694 td = fld->type;
695 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
696 //if(flag == 0){
697 // flag = 1;
698 // structCount++;
699 // if(structCount > 1) fprintf(fp,"\n");
700 //}
701 fprintf(fp, "\t\t__1->%s = %s;\n", fld->name, fld->name );
702
703 //if(structCount == 1 && whichTypeFirst == 1)
704 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
705 //else
706 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
707 }
708 //else flag = 0;
709 }
710 if(structCount) fprintf(fp,"\n");
3888436c 711 //set ptr to the end of first struct if needed;
1bedc199 712 //if(structCount + hasStrSeq > 1){
713 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
714 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
715 //}
3888436c 716
717 //copy struct, sequence and string to buffer
718 seqCount = 0;
719 strCount = 0;
720 flag = 0;
721 structCount = 0;
a8f6f123 722 if(ev->type != 0)
723 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
724 fld = (field *)ev->type->fields.array[pos1];
725 td = fld->type;
726 // if(td->type != STRING && td->type != SEQUENCE && td->type != ARRAY){
727 // if(flag == 0) structCount++;
728 // flag++;
729 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
730 // assert(0); // MD : disabled !
731 // fprintf(fp,"\t//copy struct to buffer\n");
732 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
733 // structCount, ev->name, facName,structCount);
734 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
735 // ev->name, facName,structCount);
736 // }
737 // }
738 //else if(td->type == SEQUENCE){
739 if(td->type == SEQUENCE){
740 flag = 0;
741 fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
0f5d12e9 742
743 if(td->alignment > 1) {
744 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
745 td->alignment, td->alignment, td->alignment);
746 }
a8f6f123 747 fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
748 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
0f5d12e9 749 if(td->alignment > 1) {
750 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
751 td->alignment, td->alignment, td->alignment);
752 }
a8f6f123 753 fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
754 fld->name, getTypeStr(td), seqCount);
0f5d12e9 755 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
a8f6f123 756 getTypeStr(td), seqCount);
757 }
758 else if(td->type==STRING){
759 flag = 0;
760 fprintf(fp,"\t\t//copy string to buffer\n");
761 fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
0f5d12e9 762 if(td->alignment > 1) {
763 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
764 td->alignment, td->alignment, td->alignment);
765 }
a8f6f123 766 fprintf(fp,"\t\t\tmemcpy(ptr, %s, strlength_%d + 1);\n",
767 fld->name, strCount);
768 fprintf(fp,"\t\t\tptr += strlength_%d + 1;\n",strCount);
769 fprintf(fp,"\t\t}else{\n");
770 fprintf(fp,"\t\t\t*ptr = '\\0';\n");
771 fprintf(fp,"\t\t\tptr += 1;\n");
772 fprintf(fp,"\t\t}\n\n");
773 }else if(td->type==ARRAY){
774 flag = 0;
775 fprintf(fp,"\t//copy array to buffer\n");
0f5d12e9 776 if(td->alignment > 1) {
777 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
778 td->alignment, td->alignment, td->alignment);
779 }
a8f6f123 780 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
781 fld->name, getTypeStr(td), td->size);
782 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
783 }
784 }
3888436c 785 if(structCount + seqCount > 1) fprintf(fp,"\n");
786
d7ed29cd 787 fprintf(fp,"\n");
788 fprintf(fp, "\t\t/* Commit the work */\n");
a8f6f123 789 fprintf(fp, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
790 "\t\t\t\tbuff, event_length);\n");
1bedc199 791 fprintf(fp, "\t\tltt_write_commit_counter("
792 "channel->rchan->buf[smp_processor_id()],\n"
793 "\t\t\t\tbuff);\n");
d7ed29cd 794
795 /* End of traces iteration */
796 fprintf(fp, "\t}\n\n");
797
a8f6f123 798 fprintf(fp, "\n");
1bedc199 799 // The generated preempt_check_resched is not dangerous because
800 // interrupts are disabled.
801 fprintf(fp, "\tspin_unlock(&ltt_traces.locks[smp_processor_id()]);\n");
2f74104a 802
803 fprintf(fp, "unlock:\n");
1bedc199 804 fprintf(fp, "\tbarrier();\n");
2f74104a 805 fprintf(fp, "\tltt_nesting[smp_processor_id()]--;\n");
806 fprintf(fp, "\t/* Re-enable interrupts */\n");
807 fprintf(fp, "\tlocal_irq_restore(_flags);\n");
1bedc199 808 fprintf(fp, "\tpreempt_enable_no_resched();\n");
2f74104a 809 //fprintf(fp, "\tpreempt_check_resched();\n");
810
3888436c 811 //call trace function
d7ed29cd 812 //fprintf(fp,"\n\t//call trace function\n");
813 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
1bedc199 814 fprintf(fp,"}\n");
815 fprintf(fp, "#endif //CONFIG_LTT\n\n");
3888436c 816 }
817
818}
819
820/*****************************************************************************
821 *Function name
822 * getTypeStr : generate type string
823 *Input Params
824 * td : a type descriptor
825 *Return Values
826 * char * : type string
827 ****************************************************************************/
828char * getTypeStr(type_descriptor * td){
829 type_descriptor * t ;
830
831 switch(td->type){
832 case INT:
833 return intOutputTypes[td->size];
834 case UINT:
835 return uintOutputTypes[td->size];
31cbc5d3 836 case POINTER:
837 return "void *";
838 case LONG:
839 return "long";
840 case ULONG:
841 return "unsigned long";
842 case SIZE_T:
843 return "size_t";
844 case SSIZE_T:
845 return "ssize_t";
846 case OFF_T:
847 return "off_t";
3888436c 848 case FLOAT:
849 return floatOutputTypes[td->size];
850 case STRING:
a8f6f123 851 return "const char";
3888436c 852 case ENUM:
853 return uintOutputTypes[td->size];
854 case ARRAY:
855 case SEQUENCE:
856 t = td->nested_type;
857 switch(t->type){
858 case INT:
a8f6f123 859 return intOutputTypes[t->size];
3888436c 860 case UINT:
a8f6f123 861 return uintOutputTypes[t->size];
31cbc5d3 862 case POINTER:
863 return "void *";
864 case LONG:
865 return "long";
866 case ULONG:
867 return "unsigned long";
868 case SIZE_T:
869 return "size_t";
870 case SSIZE_T:
871 return "ssize_t";
872 case OFF_T:
873 return "off_t";
3888436c 874 case FLOAT:
a8f6f123 875 return floatOutputTypes[t->size];
3888436c 876 case STRING:
a8f6f123 877 return "const char";
3888436c 878 case ENUM:
a8f6f123 879 return uintOutputTypes[t->size];
3888436c 880 default :
a8f6f123 881 error_callback(NULL,"Nested struct is not supportted");
882 break;
3888436c 883 }
884 break;
885 case STRUCT: //for now we do not support nested struct
886 error_callback(NULL,"Nested struct is not supportted");
887 break;
888 default:
889 error_callback(NULL,"No type information");
890 break;
891 }
892 return NULL;
893}
894
895/*****************************************************************************
896 *Function name
6d387597 897 * generateLoaderfile: generate a facility loaded .h file
3888436c 898 *Input Params
899 * fp : file to be written to
900 * facName : name of facility
901 * nbEvent : number of events in the facility
902 * checksum : checksum for the facility
903 ****************************************************************************/
8c6ca411 904void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
a8f6f123 905 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
906 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
8c6ca411 907 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
44cac8a9 908 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
6d387597 909 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
910
a8f6f123 911 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
44cac8a9 912 facName);
a8f6f123 913 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
6d387597 914 facName, checksum);
a8f6f123 915 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum);
916 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName);
917 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent);
918 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
919}
920
921void generateCfile(FILE * fp, char * filefacname){
922
923 fprintf(fp, "/*\n");
924 fprintf(fp, " * ltt-facility-loader-%s.c\n", filefacname);
925 fprintf(fp, " *\n");
926 fprintf(fp, " * (C) Copyright 2005 - \n");
927 fprintf(fp, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
928 fprintf(fp, " *\n");
929 fprintf(fp, " * Contains the LTT facility loader.\n");
930 fprintf(fp, " *\n");
931 fprintf(fp, " */\n");
932 fprintf(fp, "\n");
933 fprintf(fp, "\n");
934 fprintf(fp, "#include <linux/ltt-facilities.h>\n");
935 fprintf(fp, "#include <linux/module.h>\n");
936 fprintf(fp, "#include <linux/init.h>\n");
937 fprintf(fp, "#include <linux/config.h>\n");
938 fprintf(fp, "#include \"ltt-facility-loader-%s.h\"\n", filefacname);
939 fprintf(fp, "\n");
940 fprintf(fp, "\n");
941 fprintf(fp, "#ifdef CONFIG_LTT\n");
942 fprintf(fp, "\n");
943 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
944 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
945 fprintf(fp, "\n");
946 fprintf(fp, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
947 fprintf(fp, "\n");
948 fprintf(fp, "#define SYMBOL_STRING(sym) #sym\n");
949 fprintf(fp, "\n");
950 fprintf(fp, "static struct ltt_facility facility = {\n");
951 fprintf(fp, "\t.name = ltt_facility_name,\n");
952 fprintf(fp, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
953 fprintf(fp, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
954 fprintf(fp, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL)\n");
955 fprintf(fp, "};\n");
956 fprintf(fp, "\n");
957 fprintf(fp, "#ifndef MODULE\n");
958 fprintf(fp, "\n");
959 fprintf(fp, "/* Built-in facility. */\n");
960 fprintf(fp, "\n");
961 fprintf(fp, "static int __init facility_init(void)\n");
962 fprintf(fp, "{\n");
963 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname);
964 fprintf(fp, "\n");
965 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
966 fprintf(fp, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
967 fprintf(fp, "\t\n");
968 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
969 fprintf(fp, "}\n");
970 fprintf(fp, "__initcall(facility_init);\n");
971 fprintf(fp, "\n");
972 fprintf(fp, "\n");
973 fprintf(fp, "\n");
974 fprintf(fp, "#else \n");
975 fprintf(fp, "\n");
976 fprintf(fp, "/* Dynamic facility. */\n");
977 fprintf(fp, "\n");
978 fprintf(fp, "static int __init facility_init(void)\n");
979 fprintf(fp, "{\n");
980 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname);
981 fprintf(fp, "\n");
982 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
983 fprintf(fp, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
984 fprintf(fp, "\n");
985 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
986 fprintf(fp, "}\n");
987 fprintf(fp, "\n");
988 fprintf(fp, "static void __exit facility_exit(void)\n");
989 fprintf(fp, "{\n");
990 fprintf(fp, "\tint err;\n");
991 fprintf(fp, "\n");
992 fprintf(fp, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
993 fprintf(fp, "\tif(err != 0)\n");
994 fprintf(fp, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
995 fprintf(fp, "\n");
996 fprintf(fp, "}\n");
997 fprintf(fp, "\n");
998 fprintf(fp, "module_init(facility_init)\n");
999 fprintf(fp, "module_exit(facility_exit)\n");
1000 fprintf(fp, "\n");
1001 fprintf(fp, "\n");
1002 fprintf(fp, "MODULE_LICENSE(\"GPL\");\n");
1003 fprintf(fp, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1004 fprintf(fp, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1005 fprintf(fp, "\n");
1006 fprintf(fp, "#endif //MODULE\n");
1007 fprintf(fp, "\n");
1008 fprintf(fp, "#endif //CONFIG_LTT\n");
3888436c 1009}
1010
1011
This page took 0.08803 seconds and 4 git commands to generate.