sync genevent and LTTV parsers
[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)++;
d9a67054 302 } else {
31cbc5d3 303 if (flag == 0) {
304 flag = 1;
cb1eb7ce 305 fprintf(fp,"struct %s_%s",name, facName);
306 if (structCount) {
a8f6f123 307 fprintf(fp, "_%d {\n",++*structCount);
cb1eb7ce 308 } else {
309 fprintf(fp, " {\n");
310 }
31cbc5d3 311 }
cb1eb7ce 312 fprintf(fp, "\t%s %s; /* %s */\n",
313 getTypeStr(td),fld->name,fld->description );
31cbc5d3 314 }
315 }
316
317 if(flag) {
4a65a3b9 318 unsigned align = max(alignment, type->alignment);
319
320 if(align == 0)
9774b764 321 fprintf(fp,"} __attribute__ ((packed));\n\n");
322 else {
4a65a3b9 323 if(align != 1 && align != 2
324 && align != 4 && align != 8) {
325 printf("Wrong alignment %i, using packed.\n", align);
9774b764 326 fprintf(fp,"} __attribute__ ((packed));\n\n");
327 } else
4a65a3b9 328 fprintf(fp,"} __attribute__ ((aligned(%i)));\n\n", align);
9774b764 329 }
31cbc5d3 330 }
331}
332
333
334/*****************************************************************************
335 *Function name
336 * generateHfile : Create the typedefs
337 *Input Params
338 * fp : file to be written to
339 ****************************************************************************/
340void
a8f6f123 341generateTypeDefs(FILE * fp, char *facName)
31cbc5d3 342{
343 int pos, tmp = 1;
344
a8f6f123 345 fprintf(fp,"#include <linux/types.h>\n");
346 fprintf(fp,"#include <linux/spinlock.h>\n");
347 fprintf(fp,"#include <linux/ltt/ltt-facility-id-%s.h>\n\n", facName);
348 fprintf(fp,"#include <linux/ltt-core.h>\n");
349
9774b764 350#if 0 //broken
31cbc5d3 351 fprintf(fp, "/**** Basic Type Definitions ****/\n\n");
352
353 for (pos = 0; pos < fac->named_types.values.position; pos++) {
354 type_descriptor * type =
355 (type_descriptor*)fac->named_types.values.array[pos];
356 printStruct(fp, type->fields.position, type->fields.array,
357 "", type->type_name, &tmp, &tmp, NULL);
358 fprintf(fp, "typedef struct _%s %s;\n\n",
359 type->type_name, type->type_name);
360 }
9774b764 361#endif //0
31cbc5d3 362}
363
364
3888436c 365/*****************************************************************************
366 *Function name
367 * generateEnumDefinition: generate enum definition if it exists
368 *Input Params
369 * fp : file to be written to
370 * fHead : enum type
371 ****************************************************************************/
372void generateEnumDefinition(FILE * fp, type_descriptor * type){
373 int pos;
374
a8f6f123 375 if(type->already_printed) return;
376
3888436c 377 fprintf(fp,"enum {\n");
378 for(pos = 0; pos < type->labels.position; pos++){
a8f6f123 379 fprintf(fp,"\tLTT_ENUM_%s", type->labels.array[pos]);
8c6ca411 380 if (pos != type->labels.position - 1) fprintf(fp,",");
a8f6f123 381 if(type->labels_description.array[pos] != NULL)
382 fprintf(fp,"\t/* %s */\n",type->labels_description.array[pos]);
383 else
384 fprintf(fp,"\n");
3888436c 385 }
8c6ca411 386 fprintf(fp,"};\n\n\n");
44cac8a9 387
a8f6f123 388 type->already_printed = 1;
3888436c 389}
390
391/*****************************************************************************
392 *Function name
393 * generateStrucTFunc: output structure and function to .h file
394 *Input Params
395 * fp : file to be written to
396 * facName : name of facility
397 ****************************************************************************/
31cbc5d3 398void generateStructFunc(FILE * fp, char * facName, unsigned long checksum){
3888436c 399 event * ev;
400 field * fld;
401 type_descriptor * td;
402 int pos, pos1;
403 int hasStrSeq, flag, structCount, seqCount,strCount, whichTypeFirst=0;
276a9e6f 404 int args_empty;
3888436c 405
406 for(pos = 0; pos < fac->events.position; pos++){
407 ev = (event *) fac->events.array[pos];
408 //yxx if(ev->nested)continue;
d7ed29cd 409 fprintf(fp,"/**** structure and trace function for event: %s ****/\n\n",
410 ev->name);
a8f6f123 411 //if(ev->type == 0){ // event without type
412 // fprintf(fp,"static inline void trace_%s_%s(void){\n",facName,ev->name);
413 // fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, event_%s, 0, NULL);\n",
414 // facName,checksum,ev->name);
415 // fprintf(fp,"};\n\n\n");
416 // continue;
417 //}
3888436c 418
419 //if fields contain enum, print out enum definition
d7ed29cd 420 //MD : fixed in generateEnumDefinition to do not print the same enum
421 //twice.
a8f6f123 422 if(ev->type != 0)
423 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
424 fld = (field *)ev->type->fields.array[pos1];
425 if(fld->type->type == ENUM) generateEnumDefinition(fp, fld->type);
426 }
3888436c 427
428 //default: no string, array or sequence in the event
429 hasStrSeq = 0;
430 whichTypeFirst = 0;
3888436c 431 structCount = 0;
31cbc5d3 432
433 //structure for kernel
a8f6f123 434 if(ev->type != 0)
435 printStruct(fp, ev->type->fields.position, ev->type->fields.array,
9774b764 436 ev->name, facName, &whichTypeFirst, &hasStrSeq, &structCount,
437 ev->type);
3888436c 438
1bedc199 439
440 //trace function : function name and parameters : stub function.
441 seqCount = 0;
442 strCount = 0;
443 fprintf(fp, "#ifndef CONFIG_LTT\n");
444 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
276a9e6f 445
446 args_empty = 1;
447
448 /* Does it support per trace tracing ? */
449 if(ev->per_trace) {
450 fprintf(fp, "struct ltt_trace_struct *dest_trace");
451 args_empty = 0;
452 }
453
454 /* Does it support per tracefile tracing ? */
455 if(ev->per_tracefile) {
456 if(!args_empty) fprintf(fp, ", ");
457 fprintf(fp, "unsigned int tracefile_index");
458 args_empty = 0;
459 }
460
461 if(ev->type != 0) {
1bedc199 462 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
463 fld = (field *)ev->type->fields.array[pos1];
464 td = fld->type;
276a9e6f 465 if(!args_empty) fprintf(fp, ", ");
1bedc199 466 if(td->type == ARRAY ){
467 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
276a9e6f 468 args_empty = 0;
1bedc199 469 }else if(td->type == STRING){
470 fprintf(fp,"short int strlength_%d, %s * %s",
471 ++strCount, getTypeStr(td), fld->name);
276a9e6f 472 args_empty = 0;
473 }else if(td->type == SEQUENCE){
1bedc199 474 fprintf(fp,"%s seqlength_%d, %s * %s",
475 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
276a9e6f 476 args_empty = 0;
477 }else {
478 fprintf(fp,"%s %s",getTypeStr(td), fld->name);
479 args_empty = 0;
480 }
1bedc199 481 }
276a9e6f 482 }
483 if(args_empty) fprintf(fp, "void");
484
1bedc199 485 fprintf(fp,")\n{\n");
486 fprintf(fp,"}\n");
487 fprintf(fp,"#else\n");
488
3888436c 489 //trace function : function name and parameters
490 seqCount = 0;
491 strCount = 0;
492 fprintf(fp,"static inline void trace_%s_%s(",facName,ev->name);
276a9e6f 493
494 args_empty = 1;
495
496 /* Does it support per trace tracing ? */
497 if(ev->per_trace) {
498 fprintf(fp, "struct ltt_trace_struct *dest_trace");
499 args_empty = 0;
500 }
501
502 /* Does it support per tracefile tracing ? */
503 if(ev->per_tracefile) {
504 if(!args_empty) fprintf(fp, ", ");
505 fprintf(fp, "unsigned int tracefile_index");
506 args_empty = 0;
507 }
508
509 if(ev->type != 0) {
a8f6f123 510 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
511 fld = (field *)ev->type->fields.array[pos1];
512 td = fld->type;
276a9e6f 513 if(!args_empty) fprintf(fp, ", ");
a8f6f123 514 if(td->type == ARRAY ){
515 fprintf(fp,"%s * %s",getTypeStr(td), fld->name);
276a9e6f 516 args_empty = 0;
a8f6f123 517 }else if(td->type == STRING){
518 fprintf(fp,"short int strlength_%d, %s * %s",
519 ++strCount, getTypeStr(td), fld->name);
276a9e6f 520 args_empty = 0;
521 }else if(td->type == SEQUENCE){
a8f6f123 522 fprintf(fp,"%s seqlength_%d, %s * %s",
523 uintOutputTypes[td->size], ++seqCount,getTypeStr(td), fld->name);
276a9e6f 524 args_empty = 0;
525 }else {
526 fprintf(fp,"%s %s",getTypeStr(td), fld->name);
527 args_empty = 0;
528 }
a8f6f123 529 }
276a9e6f 530 }
531 if(args_empty) fprintf(fp, "void");
1bedc199 532
276a9e6f 533 fprintf(fp,")\n{\n");
1bedc199 534
3888436c 535 //allocate buffer
d7ed29cd 536 // MD no more need. fprintf(fp,"\tchar buff[buflength];\n");
537 // write directly to the channel
538 fprintf(fp, "\tunsigned int index;\n");
539 fprintf(fp, "\tstruct ltt_channel_struct *channel;\n");
540 fprintf(fp, "\tstruct ltt_trace_struct *trace;\n");
a8f6f123 541 fprintf(fp, "\tunsigned long _flags;\n");
2f74104a 542 fprintf(fp, "\tvoid *buff;\n");
e8907e11 543 fprintf(fp, "\tunsigned old_offset;\n");
2f74104a 544 fprintf(fp, "\tunsigned int header_length;\n");
c0d2d4d4 545 fprintf(fp, "\tunsigned int event_length;\n"); // total size (incl hdr)
546 fprintf(fp, "\tunsigned int length;\n"); // Size of the event var data.
1bedc199 547 fprintf(fp, "\tunsigned char _offset;\n");
548 fprintf(fp, "\tstruct rchan_buf *buf;\n");
5e07c65f 549 fprintf(fp, "\tstruct timeval delta;\n");
550 fprintf(fp, "\tu64 tsc;\n");
e8907e11 551 fprintf(fp, "\tchar *ptr;\n");
2f74104a 552
a8f6f123 553 if(ev->type != 0)
554 fprintf(fp, "\tstruct %s_%s_1* __1;\n\n", ev->name, facName);
d7ed29cd 555
1bedc199 556 /* Warning : this is done prior to taking locks :
557 * setting this value must be done at the end of the trace activation.
558 * (we don't care for trace removal, as the list of traces is protected : it
559 * just won't iterate on any trace). */
560 fprintf(fp,
561 "\tif(ltt_traces.num_active_traces == 0) return;\n\n");
562
2f74104a 563 fprintf(fp, "\t/* Disable interrupts. */\n");
564 fprintf(fp, "\tlocal_irq_save(_flags);\n");
565 fprintf(fp, "\tpreempt_disable();\n\n");
566
567 fprintf(fp, "\tltt_nesting[smp_processor_id()]++;\n");
1bedc199 568 fprintf(fp, "\tbarrier();\n");
569 fprintf(fp, "\tif(ltt_nesting[smp_processor_id()] > 1) goto unlock;\n");
2f74104a 570 fprintf(fp, "\tspin_lock(&ltt_traces.locks[smp_processor_id()]);\n\n");
571
276a9e6f 572 if(ev->per_tracefile) {
573 fprintf(fp, "\tindex = tracefile_index;\n");
574 } else {
575 fprintf(fp,
d7ed29cd 576 "\tindex = ltt_get_index_from_facility(ltt_facility_%s_%X,\n"\
a8f6f123 577 "\t\t\t\tevent_%s);\n",
d7ed29cd 578 facName, checksum, ev->name);
276a9e6f 579 }
d7ed29cd 580 fprintf(fp,"\n");
581
a8f6f123 582 /* For each trace */
d7ed29cd 583 fprintf(fp, "\tlist_for_each_entry(trace, &ltt_traces.head, list) {\n");
a8f6f123 584 fprintf(fp, "\t\tif(!trace->active) continue;\n\n");
0f5d12e9 585
276a9e6f 586 if(ev->per_trace) {
587 fprintf(fp, "\t\tif(dest_trace != trace) continue;\n\n");
588 }
0f5d12e9 589 //length of buffer : length of all structures
0f5d12e9 590 // if(ev->type == 0) fprintf(fp, "0");
591
1bedc199 592 fprintf(fp, "\t\tchannel = ltt_get_channel_from_index(trace, index);\n");
593 fprintf(fp, "\t\tbuf = channel->rchan->buf[smp_processor_id()];\n");
5e07c65f 594 fprintf(fp, "\n");
1bedc199 595 /* Warning : not atomic reservation : event size depends on the current
596 * address for alignment */
5e07c65f 597 /* NOTE : using cmpxchg in reserve with repeat for atomicity */
0f5d12e9 598 // Replaces _offset
c3e1c4c4 599 /* NOTE2 : as the read old address from memory must come before any
600 * protected event, let's add a memory barrier() to make sure the compiler
601 * will not reorder this read. */
5e07c65f 602 fprintf(fp, "\t\tdo {\n");
e8907e11 603 fprintf(fp, "\t\t\told_offset = buf->offset;\n");
c3e1c4c4 604 fprintf(fp, "\t\t\tbarrier();\n");
e8907e11 605 fprintf(fp, "\t\t\tptr = (char*)buf->data + old_offset;\n");
c0d2d4d4 606
607
5e07c65f 608 fprintf(fp, "\t\t\theader_length = ltt_get_event_header_data(trace, "
609 "channel,\n"
e8907e11 610 "\t\t\t\t\t\t\t\t\t\tptr, &_offset, &delta, &tsc);\n");
5e07c65f 611
c0d2d4d4 612 fprintf(fp, "\t\t\tptr += _offset + header_length;\n");
0f5d12e9 613
614 for(pos1=0;pos1<structCount;pos1++){
615
4a65a3b9 616 unsigned align = max(alignment, ev->type->alignment);
617 if(align > 1) {
c0d2d4d4 618 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1) ;\n",
4a65a3b9 619 align, align, align);
0f5d12e9 620 }
c0d2d4d4 621 fprintf(fp,"\t\t\tptr += sizeof(struct %s_%s_%d);\n",ev->name,
0f5d12e9 622 facName,pos1+1);
623// if(pos1 != structCount-1) fprintf(fp," + ");
624 }
625
626 //length of buffer : length of all arrays, sequences and strings
627 seqCount = 0;
628 strCount = 0;
629 flag = 0;
630 if(ev->type != 0)
631 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
632 fld = (field *)ev->type->fields.array[pos1];
633 td = fld->type;
634 if(td->type == SEQUENCE || td->type==STRING || td->type==ARRAY){
635 if(td->type == SEQUENCE) {
4a65a3b9 636
637 unsigned align = max(alignment, td->alignment);
638 if(align > 1) {
639 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
640 align, align, align);
641 }
642 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
643 if(align > 1) {
644 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
645 align, align, align);
646 }
647 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
648 getTypeStr(td), seqCount);
649
0f5d12e9 650 } else if(td->type==STRING) {
4a65a3b9 651 unsigned align = max(alignment, td->alignment);
652 if(align > 1) {
c0d2d4d4 653 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1)) ;\n",
4a65a3b9 654 align, align, align);
0f5d12e9 655 }
c0d2d4d4 656 fprintf(fp,"ptr += strlength_%d + 1;\n",
0f5d12e9 657 ++strCount);
658 }
659 else if(td->type==ARRAY) {
4a65a3b9 660 unsigned align = max(alignment, td->alignment);
661 if(align > 1) {
c0d2d4d4 662 fprintf(fp,"\t\t\tptr += (%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 663 align, align, align);
0f5d12e9 664 }
c0d2d4d4 665 fprintf(fp,"\t\t\tptr += sizeof(%s) * %d;\n",
0f5d12e9 666 getTypeStr(td),td->size);
667 if(structCount == 0) flag = 1;
668 }
669 }
670 }
c0d2d4d4 671 fprintf(fp, "\t\t\tevent_length = (unsigned long)ptr -"
e8907e11 672 "(unsigned long)(buf->data + old_offset);\n");
c3e1c4c4 673
674 /* let's put some protection before the cmpxchg : the space reservation and
675 * the get TSC are not dependant from each other. I don't want the compiler
676 * to reorder those in the wrong order. And relay_reserve is inline, so
677 * _yes_, the compiler could mess it up. */
678 fprintf(fp, "\t\t\tbarrier();\n");
5e07c65f 679 fprintf(fp, "\t\t\tbuff = relay_reserve(channel->rchan, event_length, "
e8907e11 680 "old_offset);\n");
5e07c65f 681 fprintf(fp, "\n");
682 fprintf(fp, "\t\t} while(PTR_ERR(buff) == -EAGAIN);\n");
683 fprintf(fp, "\n");
684
685
d7ed29cd 686 /* Reserve the channel */
5e07c65f 687 //fprintf(fp, "\t\tbuff = relay_reserve(channel->rchan, event_length);\n");
a8f6f123 688 fprintf(fp, "\t\tif(buff == NULL) {\n");
689 fprintf(fp, "\t\t\t/* Buffer is full*/\n");
690 fprintf(fp, "\t\t\t/* for debug BUG(); */\n"); // DEBUG!
691 fprintf(fp, "\t\t\tchannel->events_lost[smp_processor_id()]++;\n");
e3cc790d 692 fprintf(fp, "\t\t\tbreak;\n"); /* don't commit a NULL reservation! */
a8f6f123 693 fprintf(fp, "\t\t}\n");
d7ed29cd 694
a8f6f123 695 /* DEBUG */
5e07c65f 696 //fprintf(fp, "\t\tif(resret == 1) {\n");
697 //fprintf(fp, "printk(\"f%%lu e\%%u \", ltt_facility_%s_%X, event_%s);",
698 // facName, checksum, ev->name);
699 //fprintf(fp, "\t\t}\n");
a8f6f123 700
701 /* Write the header */
c0d2d4d4 702 fprintf(fp, "\n");
e8907e11 703 fprintf(fp,"\t\tlength = event_length - _offset - header_length;\n");
a8f6f123 704 fprintf(fp, "\n");
705 fprintf(fp, "\t\tltt_write_event_header(trace, channel, buff, \n"
c0d2d4d4 706 "\t\t\t\tltt_facility_%s_%X, event_%s, length, _offset,\n"
707 "\t\t\t\t&delta, &tsc);\n",
a8f6f123 708 facName, checksum, ev->name);
709 fprintf(fp, "\n");
5e07c65f 710
711 if(ev->type != 0)
276a9e6f 712 fprintf(fp, "\t\tptr = (char*)buff + _offset + header_length;\n");
3888436c 713
714 //copy struct, sequence and string to buffer
276a9e6f 715 //FIXME : they always come before the structs.
3888436c 716 seqCount = 0;
717 strCount = 0;
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 != STRING && td->type != SEQUENCE && td->type != ARRAY){
725 // if(flag == 0) structCount++;
726 // flag++;
727 // if((structCount > 1 || whichTypeFirst == 2) && flag == 1){
728 // assert(0); // MD : disabled !
729 // fprintf(fp,"\t//copy struct to buffer\n");
730 // fprintf(fp,"\tmemcpy(ptr, &__%d, sizeof(struct %s_%s_%d));\n",
731 // structCount, ev->name, facName,structCount);
732 // fprintf(fp,"\tptr += sizeof(struct %s_%s_%d);\n\n",
733 // ev->name, facName,structCount);
734 // }
735 // }
736 //else if(td->type == SEQUENCE){
737 if(td->type == SEQUENCE){
738 flag = 0;
739 fprintf(fp,"\t\t//copy sequence length and sequence to buffer\n");
0f5d12e9 740
4a65a3b9 741 unsigned align = max(alignment, td->alignment);
742 if(align > 1) {
0f5d12e9 743 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 744 align, align, align);
0f5d12e9 745 }
a8f6f123 746 fprintf(fp,"\t\t*ptr = seqlength_%d;\n",++seqCount);
747 fprintf(fp,"\t\tptr += sizeof(%s);\n",uintOutputTypes[td->size]);
4a65a3b9 748 if(align > 1) {
0f5d12e9 749 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 750 align, align, align);
0f5d12e9 751 }
a8f6f123 752 fprintf(fp,"\t\tmemcpy(ptr, %s, sizeof(%s) * seqlength_%d);\n",
753 fld->name, getTypeStr(td), seqCount);
0f5d12e9 754 fprintf(fp,"\t\tptr += sizeof(%s) * seqlength_%d;\n\n",
a8f6f123 755 getTypeStr(td), seqCount);
756 }
757 else if(td->type==STRING){
758 flag = 0;
759 fprintf(fp,"\t\t//copy string to buffer\n");
760 fprintf(fp,"\t\tif(strlength_%d > 0){\n",++strCount);
4a65a3b9 761 unsigned align = max(alignment, td->alignment);
762 if(align > 1) {
0f5d12e9 763 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 764 align, align, align);
0f5d12e9 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");
4a65a3b9 776 unsigned align = max(alignment, td->alignment);
777 if(align > 1) {
0f5d12e9 778 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
4a65a3b9 779 align, align, align);
0f5d12e9 780 }
a8f6f123 781 fprintf(fp,"\tmemcpy(ptr, %s, sizeof(%s) * %d);\n",
782 fld->name, getTypeStr(td), td->size);
783 fprintf(fp,"\tptr += sizeof(%s) * %d;\n\n", getTypeStr(td), td->size);
784 }
785 }
3888436c 786 if(structCount + seqCount > 1) fprintf(fp,"\n");
787
276a9e6f 788
789
790
791 //declare a char pointer if needed : starts at the end of the structs.
792 //if(structCount + hasStrSeq > 1) {
793 // fprintf(fp,"\t\tchar * ptr = (char*)buff + header_length");
794 // for(pos1=0;pos1<structCount;pos1++){
795 // fprintf(fp," + sizeof(struct %s_%s_%d)",ev->name, facName,pos1+1);
796 // }
797 // if(structCount + hasStrSeq > 1) fprintf(fp,";\n");
798 //}
799
800 // Declare an alias pointer of the struct type to the beginning
801 // of the reserved area, just after the event header.
802 if(ev->type != 0) {
803 unsigned align = max(alignment, td->alignment);
804 if(align > 1) {
805 fprintf(fp,"\t\tptr+=(%u - ((unsigned int)ptr&(%u-1)))&(%u-1);\n",
806 align, align, align);
807 }
808
809 fprintf(fp, "\t\t__1 = (struct %s_%s_1 *)(ptr);\n",
810 ev->name, facName);
811 }
812 //allocate memory for new struct and initialize it
813 //if(whichTypeFirst == 1){ //struct first
814 //for(pos1=0;pos1<structCount;pos1++){
815 // if(pos1==0) fprintf(fp,
816 // "\tstruct %s_%s_1 * __1 = (struct %s_%s_1 *)buff;\n",
817 // ev->name, facName,ev->name, facName);
818 //MD disabled else fprintf(fp,
819 // "\tstruct %s_%s_%d __%d;\n",
820 // ev->name, facName,pos1+1,pos1+1);
821 //}
822 //}else if(whichTypeFirst == 2){
823 // for(pos1=0;pos1<structCount;pos1++)
824 // fprintf(fp,"\tstruct %s_%s_%d __%d;\n",
825 // ev->name, facName,pos1+1,pos1+1);
826 //}
827 fprintf(fp,"\n");
828
829 if(structCount) fprintf(fp,"\t\t//initialize structs\n");
830 //flag = 0;
831 //structCount = 0;
832 if(ev->type != 0)
833 for(pos1 = 0; pos1 < ev->type->fields.position; pos1++){
834 fld = (field *)ev->type->fields.array[pos1];
835 td = fld->type;
836 if(td->type != ARRAY && td->type != SEQUENCE && td->type != STRING){
837 //if(flag == 0){
838 // flag = 1;
839 // structCount++;
840 // if(structCount > 1) fprintf(fp,"\n");
841 //}
842 fprintf(fp, "\t\t__1->%s = %s;\n", fld->name, fld->name );
843
844 //if(structCount == 1 && whichTypeFirst == 1)
845 // fprintf(fp, "\t__1->%s = %s;\n",fld->name,fld->name );
846 //else
847 // fprintf(fp, "\t__%d.%s = %s;\n",structCount ,fld->name,fld->name);
848 }
849 //else flag = 0;
850 }
851 if(structCount) fprintf(fp,"\n");
852 //set ptr to the end of first struct if needed;
853 //if(structCount + hasStrSeq > 1){
854 // fprintf(fp,"\n\t\t//set ptr to the end of the first struct\n");
855 // fprintf(fp,"\t\tptr += sizeof(struct %s_%s_1);\n\n",ev->name, facName);
856 //}
857
d7ed29cd 858 fprintf(fp,"\n");
859 fprintf(fp, "\t\t/* Commit the work */\n");
a8f6f123 860 fprintf(fp, "\t\trelay_commit(channel->rchan->buf[smp_processor_id()],\n"
861 "\t\t\t\tbuff, event_length);\n");
1bedc199 862 fprintf(fp, "\t\tltt_write_commit_counter("
863 "channel->rchan->buf[smp_processor_id()],\n"
864 "\t\t\t\tbuff);\n");
d7ed29cd 865
866 /* End of traces iteration */
867 fprintf(fp, "\t}\n\n");
868
a8f6f123 869 fprintf(fp, "\n");
1bedc199 870 // The generated preempt_check_resched is not dangerous because
871 // interrupts are disabled.
872 fprintf(fp, "\tspin_unlock(&ltt_traces.locks[smp_processor_id()]);\n");
2f74104a 873
874 fprintf(fp, "unlock:\n");
1bedc199 875 fprintf(fp, "\tbarrier();\n");
2f74104a 876 fprintf(fp, "\tltt_nesting[smp_processor_id()]--;\n");
877 fprintf(fp, "\t/* Re-enable interrupts */\n");
878 fprintf(fp, "\tlocal_irq_restore(_flags);\n");
1bedc199 879 fprintf(fp, "\tpreempt_enable_no_resched();\n");
2f74104a 880 //fprintf(fp, "\tpreempt_check_resched();\n");
881
3888436c 882 //call trace function
d7ed29cd 883 //fprintf(fp,"\n\t//call trace function\n");
884 //fprintf(fp,"\tltt_log_event(ltt_facility_%s_%X, %s, bufLength, buff);\n",facName,checksum,ev->name);
1bedc199 885 fprintf(fp,"}\n");
886 fprintf(fp, "#endif //CONFIG_LTT\n\n");
3888436c 887 }
888
889}
890
891/*****************************************************************************
892 *Function name
893 * getTypeStr : generate type string
894 *Input Params
895 * td : a type descriptor
896 *Return Values
897 * char * : type string
898 ****************************************************************************/
899char * getTypeStr(type_descriptor * td){
900 type_descriptor * t ;
901
902 switch(td->type){
903 case INT:
904 return intOutputTypes[td->size];
905 case UINT:
906 return uintOutputTypes[td->size];
31cbc5d3 907 case POINTER:
908 return "void *";
909 case LONG:
910 return "long";
911 case ULONG:
912 return "unsigned long";
913 case SIZE_T:
914 return "size_t";
915 case SSIZE_T:
916 return "ssize_t";
917 case OFF_T:
918 return "off_t";
3888436c 919 case FLOAT:
920 return floatOutputTypes[td->size];
921 case STRING:
a8f6f123 922 return "const char";
3888436c 923 case ENUM:
924 return uintOutputTypes[td->size];
925 case ARRAY:
926 case SEQUENCE:
927 t = td->nested_type;
928 switch(t->type){
929 case INT:
a8f6f123 930 return intOutputTypes[t->size];
3888436c 931 case UINT:
a8f6f123 932 return uintOutputTypes[t->size];
31cbc5d3 933 case POINTER:
934 return "void *";
935 case LONG:
936 return "long";
937 case ULONG:
938 return "unsigned long";
939 case SIZE_T:
940 return "size_t";
941 case SSIZE_T:
942 return "ssize_t";
943 case OFF_T:
944 return "off_t";
3888436c 945 case FLOAT:
a8f6f123 946 return floatOutputTypes[t->size];
3888436c 947 case STRING:
a8f6f123 948 return "const char";
3888436c 949 case ENUM:
a8f6f123 950 return uintOutputTypes[t->size];
3888436c 951 default :
a8f6f123 952 error_callback(NULL,"Nested struct is not supportted");
953 break;
3888436c 954 }
955 break;
956 case STRUCT: //for now we do not support nested struct
957 error_callback(NULL,"Nested struct is not supportted");
958 break;
959 default:
960 error_callback(NULL,"No type information");
961 break;
962 }
963 return NULL;
964}
965
966/*****************************************************************************
967 *Function name
6d387597 968 * generateLoaderfile: generate a facility loaded .h file
3888436c 969 *Input Params
970 * fp : file to be written to
971 * facName : name of facility
972 * nbEvent : number of events in the facility
973 * checksum : checksum for the facility
974 ****************************************************************************/
8c6ca411 975void generateLoaderfile(FILE * fp, char * facName, int nbEvent, unsigned long checksum, char *capname){
a8f6f123 976 fprintf(fp, "#ifndef _LTT_FACILITY_LOADER_%s_H_\n",capname);
977 fprintf(fp, "#define _LTT_FACILITY_LOADER_%s_H_\n\n",capname);
8c6ca411 978 fprintf(fp,"#include <linux/ltt-facilities.h>\n", facName, checksum);
44cac8a9 979 fprintf(fp,"ltt_facility_t\tltt_facility_%s;\n", facName, checksum);
6d387597 980 fprintf(fp,"ltt_facility_t\tltt_facility_%s_%X;\n\n", facName, checksum);
981
a8f6f123 982 fprintf(fp,"#define LTT_FACILITY_SYMBOL\t\t\t\t\t\t\tltt_facility_%s\n",
44cac8a9 983 facName);
a8f6f123 984 fprintf(fp,"#define LTT_FACILITY_CHECKSUM_SYMBOL\t\tltt_facility_%s_%X\n",
6d387597 985 facName, checksum);
a8f6f123 986 fprintf(fp,"#define LTT_FACILITY_CHECKSUM\t\t\t\t\t\t0x%X\n", checksum);
987 fprintf(fp,"#define LTT_FACILITY_NAME\t\t\t\t\t\t\t\t\"%s\"\n", facName);
988 fprintf(fp,"#define LTT_FACILITY_NUM_EVENTS\t\t\t\t\t%d\n\n", nbEvent);
989 fprintf(fp, "#endif //_LTT_FACILITY_LOADER_%s_H_\n",capname);
990}
991
992void generateCfile(FILE * fp, char * filefacname){
993
994 fprintf(fp, "/*\n");
995 fprintf(fp, " * ltt-facility-loader-%s.c\n", filefacname);
996 fprintf(fp, " *\n");
997 fprintf(fp, " * (C) Copyright 2005 - \n");
998 fprintf(fp, " * Mathieu Desnoyers (mathieu.desnoyers@polymtl.ca)\n");
999 fprintf(fp, " *\n");
1000 fprintf(fp, " * Contains the LTT facility loader.\n");
1001 fprintf(fp, " *\n");
1002 fprintf(fp, " */\n");
1003 fprintf(fp, "\n");
1004 fprintf(fp, "\n");
1005 fprintf(fp, "#include <linux/ltt-facilities.h>\n");
1006 fprintf(fp, "#include <linux/module.h>\n");
1007 fprintf(fp, "#include <linux/init.h>\n");
1008 fprintf(fp, "#include <linux/config.h>\n");
1009 fprintf(fp, "#include \"ltt-facility-loader-%s.h\"\n", filefacname);
1010 fprintf(fp, "\n");
1011 fprintf(fp, "\n");
1012 fprintf(fp, "#ifdef CONFIG_LTT\n");
1013 fprintf(fp, "\n");
1014 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_SYMBOL);\n");
1015 fprintf(fp, "EXPORT_SYMBOL(LTT_FACILITY_CHECKSUM_SYMBOL);\n");
1016 fprintf(fp, "\n");
1017 fprintf(fp, "static const char ltt_facility_name[] = LTT_FACILITY_NAME;\n");
1018 fprintf(fp, "\n");
1019 fprintf(fp, "#define SYMBOL_STRING(sym) #sym\n");
1020 fprintf(fp, "\n");
1021 fprintf(fp, "static struct ltt_facility facility = {\n");
1022 fprintf(fp, "\t.name = ltt_facility_name,\n");
1023 fprintf(fp, "\t.num_events = LTT_FACILITY_NUM_EVENTS,\n");
1024 fprintf(fp, "\t.checksum = LTT_FACILITY_CHECKSUM,\n");
e8907e11 1025 fprintf(fp, "\t.symbol = SYMBOL_STRING(LTT_FACILITY_SYMBOL),\n");
1026 fprintf(fp, "\t.alignment = %u\n", alignment); /* default alignment */
a8f6f123 1027 fprintf(fp, "};\n");
1028 fprintf(fp, "\n");
1029 fprintf(fp, "#ifndef MODULE\n");
1030 fprintf(fp, "\n");
1031 fprintf(fp, "/* Built-in facility. */\n");
1032 fprintf(fp, "\n");
1033 fprintf(fp, "static int __init facility_init(void)\n");
1034 fprintf(fp, "{\n");
1035 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init in kernel\\n\");\n", filefacname);
1036 fprintf(fp, "\n");
1037 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_builtin_register(&facility);\n");
1038 fprintf(fp, "\tLTT_FACILITY_CHECKSUM_SYMBOL = LTT_FACILITY_SYMBOL;\n");
1039 fprintf(fp, "\t\n");
1040 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
1041 fprintf(fp, "}\n");
1042 fprintf(fp, "__initcall(facility_init);\n");
1043 fprintf(fp, "\n");
1044 fprintf(fp, "\n");
1045 fprintf(fp, "\n");
1046 fprintf(fp, "#else \n");
1047 fprintf(fp, "\n");
1048 fprintf(fp, "/* Dynamic facility. */\n");
1049 fprintf(fp, "\n");
1050 fprintf(fp, "static int __init facility_init(void)\n");
1051 fprintf(fp, "{\n");
1052 fprintf(fp, "\tprintk(KERN_INFO \"LTT : ltt-facility-%s init dynamic\\n\");\n", filefacname);
1053 fprintf(fp, "\n");
1054 fprintf(fp, "\tLTT_FACILITY_SYMBOL = ltt_facility_dynamic_register(&facility);\n");
1055 fprintf(fp, "\tLTT_FACILITY_SYMBOL_CHECKSUM = LTT_FACILITY_SYMBOL;\n");
1056 fprintf(fp, "\n");
1057 fprintf(fp, "\treturn LTT_FACILITY_SYMBOL;\n");
1058 fprintf(fp, "}\n");
1059 fprintf(fp, "\n");
1060 fprintf(fp, "static void __exit facility_exit(void)\n");
1061 fprintf(fp, "{\n");
1062 fprintf(fp, "\tint err;\n");
1063 fprintf(fp, "\n");
1064 fprintf(fp, "\terr = ltt_facility_dynamic_unregister(LTT_FACILITY_SYMBOL);\n");
1065 fprintf(fp, "\tif(err != 0)\n");
1066 fprintf(fp, "\t\tprintk(KERN_ERR \"LTT : Error in unregistering facility.\\n\");\n");
1067 fprintf(fp, "\n");
1068 fprintf(fp, "}\n");
1069 fprintf(fp, "\n");
1070 fprintf(fp, "module_init(facility_init)\n");
1071 fprintf(fp, "module_exit(facility_exit)\n");
1072 fprintf(fp, "\n");
1073 fprintf(fp, "\n");
1074 fprintf(fp, "MODULE_LICENSE(\"GPL\");\n");
1075 fprintf(fp, "MODULE_AUTHOR(\"Mathieu Desnoyers\");\n");
1076 fprintf(fp, "MODULE_DESCRIPTION(\"Linux Trace Toolkit Facility\");\n");
1077 fprintf(fp, "\n");
1078 fprintf(fp, "#endif //MODULE\n");
1079 fprintf(fp, "\n");
1080 fprintf(fp, "#endif //CONFIG_LTT\n");
3888436c 1081}
1082
1083
This page took 0.078206 seconds and 4 git commands to generate.