}
fprintf(fd, "#define LTTNG_ARRAY_SIZE_%s %llu\n", basename,
td->size);
- print_type(td->nested_type, fd, tabs, basename, "");
+ if(print_type(td->nested_type, fd, tabs, basename, "")) return 1;
fprintf(fd, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename,
basename);
fprintf(fd, "\n");
print_tabs(1, fd);
fprintf(fd, "unsigned int len;\n");
print_tabs(1, fd);
- print_type(td->nested_type, fd, tabs, basename, "");
+ if(print_type(td->nested_type, fd, tabs, basename, "")) return 1;
fprintf(fd, " *array;\n");
fprintf(fd, "};\n");
fprintf(fd, "\n");
field_t *field = (field_t*)(td->fields.array[i]);
type_descriptor_t *type = field->type;
print_tabs(1, fd);
- print_type(type, fd, tabs, basename, field->name);
+ if(print_type(type, fd, tabs, basename, field->name)) return 1;
fprintf(fd, " ");
fprintf(fd, "%s", field->name);
fprintf(fd, ";\n");
type_descriptor_t *type = field->type;
if(type->type_name == NULL) {
/* Not a named nested type : we must print its declaration first */
- //if(print_type_declaration(type,
- // fd, 0, basename, field->name)) return 1;
+ if(print_type_declaration(type,
+ fd, 0, basename, field->name)) return 1;
}
}
fprintf(fd, "union lttng_%s", basename);
field_t *field = (field_t*)(td->fields.array[i]);
type_descriptor_t *type = field->type;
print_tabs(1, fd);
- print_type(type, fd, tabs, basename, field->name);
+ if(print_type(type, fd, tabs, basename, field->name)) return 1;
fprintf(fd, " ");
fprintf(fd, "%s", field->name);
fprintf(fd, ";\n");
return 0;
}
+/* Print the logging function of an event. This is the core of genevent */
+int print_event_logging_function(char *basename, event_t *event, FILE *fd)
+{
+ fprintf(fd, "static inline void trace_%s(\n", basename);
+ for(unsigned int j = 0; j < event->fields.position; j++) {
+ /* For each field, print the function argument */
+ field_t *f = (field_t*)event->fields.array[j];
+ type_descriptor_t *t = f->type;
+ print_tabs(2, fd);
+ if(print_type(t, fd, 0, basename, f->name)) return 1;
+ fprintf(fd, " %s", f->name);
+ if(j < event->fields.position-1) {
+ fprintf(fd, ",");
+ fprintf(fd, "\n");
+ }
+ }
+ if(event->fields.position == 0) {
+ print_tabs(2, fd);
+ fprintf(fd, "void");
+ }
+ fprintf(fd,")\n");
+ fprintf(fd, "#ifndef CONFIG_LTT\n");
+ fprintf(fd, "{\n");
+ fprintf(fd, "}\n");
+ fprintf(fd,"#else\n");
+ fprintf(fd, "{\n");
+
+ fprintf(fd, "}\n");
+ fprintf(fd, "#endif //CONFIG_LTT\n\n");
+ return 0;
+}
/* ltt-facility-name.h : main logging header.
{
fprintf(fd, "#ifndef _LTT_FACILITY_%s_H_\n", fac->capname);
fprintf(fd, "#define _LTT_FACILITY_%s_H_\n\n", fac->capname);
+ fprintf(fd, "\n");
+ fprintf(fd, "/* Facility activation at compile time. */\n");
+ fprintf(fd, "#ifdef CONFIG_LTT_FACILITY_%s\n\n", fac->capname);
}
-
int print_log_header_types(facility_t *fac, FILE *fd)
{
sequence_t *types = &fac->named_types.values;
int print_log_header_events(facility_t *fac, FILE *fd)
{
+ sequence_t *events = &fac->events;
+ char basename[PATH_MAX];
+ unsigned int facname_len;
+
+ strncpy(basename, fac->name, PATH_MAX);
+ facname_len = strlen(basename);
+ strncat(basename, "_", PATH_MAX-facname_len);
+ facname_len = strlen(basename);
+
+ for(unsigned int i = 0; i < events->position; i++) {
+ event_t *event = (event_t*)events->array[i];
+ strncpy(&basename[facname_len], event->name, PATH_MAX-facname_len);
+
+ /* For each event, print structure, and then logging function */
+ fprintf(fd, "/* Event %s structures */\n",
+ event->name);
+ for(unsigned int j = 0; j < event->fields.position; j++) {
+ /* For each unnamed type, print the definition */
+ field_t *f = (field_t*)event->fields.array[j];
+ type_descriptor_t *t = f->type;
+ if(t->type_name == NULL)
+ if((print_type_declaration(t, fd, 0, basename, f->name))) return 1;
+ }
+ fprintf(fd, "\n");
+
+ fprintf(fd, "/* Event %s logging function */\n",
+ event->name);
+
+ if(print_event_logging_function(basename, event, fd)) return 1;
+ fprintf(fd, "\n");
+ }
+
return 0;
}
void print_log_header_tail(facility_t *fac, FILE *fd)
{
+ fprintf(fd, "#endif //CONFIG_LTT_FACILITY_%s\n\n", fac->capname);
fprintf(fd, "#endif //_LTT_FACILITY_%s_H_\n",fac->capname);
}
table_t * named_types)
{
char *token;
+ field_t *f;
+ sequence_init(&(ev->fields));
//<event name=eventtype_name>
getEventAttributes(in, ev);
if(ev->name == NULL) in->error(in, "Event not named");
getRAnglebracket(in);
- //<description>...</descriptio>
+ //<description>...</description>
ev->description = getDescription(in);
- //event can have STRUCT, TYPEREF or NOTHING
- getLAnglebracket(in);
-
- token = getToken(in);
- if(in->type == FORWARDSLASH){ //</event> NOTHING
- ev->type = NULL;
- }else if(in->type == NAME){
- if(strcmp("struct",token)==0 || strcmp("typeref",token)==0){
- ungetToken(in);
- ev->type = parseType(in,NULL, unnamed_types, named_types);
- if(ev->type->type != STRUCT && ev->type->type != NONE)
- in->error(in,"type must be a struct");
- }else in->error(in, "not a valid type");
-
- getLAnglebracket(in);
- getForwardslash(in);
- }else in->error(in,"not a struct type");
-
- token = getName(in);
- if(strcmp("event",token))in->error(in,"not an event definition");
- getRAnglebracket(in); //</event>
+ int got_end = 0;
+ /* Events can have multiple fields. each field form at least a function
+ * parameter of the logging function. */
+ while(!got_end) {
+ getLAnglebracket(in);
+ token = getToken(in);
+
+ switch(in->type) {
+ case FORWARDSLASH: /* </event> */
+ token = getName(in);
+ if(strcmp("event",token))in->error(in,"not an event definition");
+ getRAnglebracket(in); //</event>
+ got_end = 1;
+ break;
+ case NAME: /* a field */
+ if(strcmp("field",token))in->error(in,"expecting a field");
+ f = (field_t *)memAlloc(sizeof(field_t));
+ sequence_push(&(ev->fields),f);
+ parseFields(in, f, unnamed_types, named_types);
+ break;
+ default:
+ in->error(in, "expecting </event> or <field >");
+ break;
+ }
+ }
+#if 0
+ if(in->type == FORWARDSLASH){ //</event> NOTHING
+ ev->type = NULL;
+ }else if(in->type == NAME){
+ if(strcmp("struct",token)==0 || strcmp("typeref",token)==0){
+ ungetToken(in);
+ ev->type = parseType(in,NULL, unnamed_types, named_types);
+ if(ev->type->type != STRUCT && ev->type->type != NONE)
+ in->error(in,"type must be a struct");
+ }else in->error(in, "not a valid type");
+
+ getLAnglebracket(in);
+ getForwardslash(in);
+ }else in->error(in,"not a struct type");
+ getLAnglebracket(in);
+ getForwardslash(in);
+ token = getName(in);
+ if(strcmp("event",token))in->error(in,"not an event definition");
+ getRAnglebracket(in); //</event>
+#endif //0
}
/*****************************************************************************
* parseField : get field infomation from buffer
*Input params
* in : input file handle
- * t : type descriptor
+ * f : field
* unnamed_types : array of unamed types
* named_types : array of named types
****************************************************************************/
-void parseFields(parse_file_t *in, type_descriptor_t *t,
+void parseFields(parse_file_t *in, field_t *f,
sequence_t * unnamed_types,
table_t * named_types)
{
char * token;
- field_t *f;
-
- f = (field_t *)memAlloc(sizeof(field_t));
- sequence_push(&(t->fields),f);
//<field name=field_name> <description> <type> </field>
getFieldAttributes(in, f);
{
char *token;
type_descriptor_t *t;
+ field_t *f;
if(inType == NULL) {
t = (type_descriptor_t *) memAlloc(sizeof(type_descriptor_t));
token = getToken(in);
sequence_init(&(t->fields));
while(strcmp("field",token) == 0){
- parseFields(in,t, unnamed_types, named_types);
+ f = (field_t *)memAlloc(sizeof(field_t));
+ sequence_push(&(t->fields),f);
+
+ parseFields(in, f, unnamed_types, named_types);
//next field
getLAnglebracket(in);
token = getToken(in);
sequence_init(&(t->fields));
while(strcmp("field",token) == 0){
- parseFields(in,t, unnamed_types, named_types);
+ f = (field_t *)memAlloc(sizeof(field_t));
+ sequence_push(&(t->fields),f);
+ parseFields(in, f, unnamed_types, named_types);
//next field
getLAnglebracket(in);
unsigned long crc ;
int pos;
event_t * ev;
- char str[256];
crc = crc32(facName);
for(pos = 0; pos < events->position; pos++){
ev = (event_t *)(events->array[pos]);
- crc = partial_crc32(ev->name,crc);
- if(!ev->type) continue; //event without type
- if(ev->type->type != STRUCT){
- sprintf(str,"event '%s' has a type other than STRUCT",ev->name);
- error_callback(NULL, str);
- }
- crc = getTypeChecksum(crc, ev->type);
+ crc = partial_crc32(ev->name, crc);
+ for(unsigned int i = 0; i < ev->fields.position; i++) {
+ field_t *f = (field_t*)ev->fields.array[i];
+ crc = partial_crc32(f->name, crc);
+ crc = getTypeChecksum(crc, f->type);
+ }
}
*checksum = crc;
}
ev = (event_t *) t->array[pos];
free(ev->name);
free(ev->description);
+ sequence_dispose(&ev->fields);
free(ev);
}
typedef struct _event {
char *name;
char *description;
- type_descriptor_t *type;
+ //type_descriptor_t *type;
+ sequence_t fields; /* event fields */
int per_trace; /* Is the event able to be logged to a specific trace ? */
int per_tracefile; /* Must we log this event in a specific tracefile ? */
} event_t;
sequence_t * unnamed_types, table_t * named_types);
type_descriptor_t *parseType(parse_file_t *in,
type_descriptor_t *t, sequence_t * unnamed_types, table_t * named_types);
-void parseFields(parse_file_t *in, type_descriptor_t *t,
+void parseFields(parse_file_t *in, field_t *f,
sequence_t * unnamed_types, table_t * named_types);
void checkNamedTypesImplemented(table_t * namedTypes);
type_descriptor_t * find_named_type(char *name, table_t * named_types);
<event name=syscall_entry>
<description>System call entry</description>
- <struct>
- <field name="syscall_id"> <description>Syscall entry number in entry.S</description> <uint size=1/> </field>
- <field name="address"> <description>Address from which call was made</description> <pointer/> </field>
- </struct>
+ <field name="syscall_id"> <description>Syscall entry number in entry.S</description> <uint size=1/> </field>
+ <field name="address"> <description>Address from which call was made</description> <pointer/> </field>
</event>
<event name=syscall_exit>
<event name=trap_entry>
<description>Entry in a trap</description>
- <struct>
- <field name="trap_id"> <description>Trap number</description> <uint size=2/> </field>
- <field name="address"> <description>Address where trap occured</description> <pointer/> </field>
- </struct>
+ <field name="trap_id"> <description>Trap number</description> <uint size=2/> </field>
+ <field name="address"> <description>Address where trap occured</description> <pointer/> </field>
</event>
<event name=trap_exit>
- <description>Exit from a trap</description>
+ <description>Exit from a trap</description>
</event>
<event name=soft_irq_entry>
- <description>Soft IRQ entry</description>
- <struct>
- <field name="softirq_id"> <description>Soft IRQ number</description> <pointer/> </field>
- </struct>
+ <description>Soft IRQ entry</description>
+ <field name="softirq_id"> <description>Soft IRQ number</description> <pointer/> </field>
</event>
<event name=soft_irq_exit>
- <description>Soft IRQ exit</description>
- <struct>
- <field name="softirq_id"> <description>Soft IRQ number</description> <pointer/> </field>
- </struct>
+ <description>Soft IRQ exit</description>
+ <field name="softirq_id"> <description>Soft IRQ number</description> <pointer/> </field>
</event>
<event name=tasklet_entry>
- <description>Tasklet entry</description>
- <struct>
- <field name="priority"> <description>Tasklet priority</description> <typeref name=tasklet_priority/> </field>
- <field name="address"> <description>Tasklet function address</description> <pointer/> </field>
- <field name="data"> <description>Tasklet data address</description> <ulong/> </field>
- </struct>
+ <description>Tasklet entry</description>
+ <field name="priority"> <description>Tasklet priority</description> <typeref name=tasklet_priority/> </field>
+ <field name="address"> <description>Tasklet function address</description> <pointer/> </field>
+ <field name="data"> <description>Tasklet data address</description> <ulong/> </field>
</event>
<event name=tasklet_exit>
- <description>Tasklet exit</description>
- <struct>
- <field name="priority"> <description>Tasklet priority</description> <typeref name=tasklet_priority/> </field>
- <field name="address"> <description>Tasklet function address</description> <pointer/> </field>
- <field name="data"> <description>Tasklet data address</description> <ulong/> </field>
- </struct>
+ <description>Tasklet exit</description>
+ <field name="priority"> <description>Tasklet priority</description> <typeref name=tasklet_priority/> </field>
+ <field name="address"> <description>Tasklet function address</description> <pointer/> </field>
+ <field name="data"> <description>Tasklet data address</description> <ulong/> </field>
</event>
<event name=irq_entry>
- <description>Entry in an irq</description>
- <struct>
- <field name="irq_id"> <description>IRQ number</description> <uint size=4/> </field>
- <field name="mode"> <description>Are we executing kernel code</description> <typeref name=irq_mode/> </field>
- </struct>
+ <description>Entry in an irq</description>
+ <field name="irq_id"> <description>IRQ number</description> <uint size=4/> </field>
+ <field name="mode"> <description>Are we executing kernel code</description> <typeref name=irq_mode/> </field>
</event>
<event name=irq_exit>
- <description>Exit from an IRQ</description>
+ <description>Exit from an IRQ</description>
</event>
+ <event name=big_array>
+ <field name="myarray"><array size=10000><pointer></array></field>
+ </event>
+
<type name=tasklet_priority>
<enum>
<label name=LOW value=0/> <description>Low priority tasklet</description>