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