From: compudj Date: Fri, 11 Nov 2005 04:11:04 +0000 (+0000) Subject: write and size calc template X-Git-Tag: v0.12.20~2171 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=a67cd958dd88555bd8f2352d8ecfe2bc678e9d6f;p=lttv.git write and size calc template git-svn-id: http://ltt.polymtl.ca/svn@1318 04897980-b3bd-0310-b5e0-8ef037075253 --- diff --git a/genevent-new/README b/genevent-new/README index 951f146c..7b16fcdf 100644 --- a/genevent-new/README +++ b/genevent-new/README @@ -44,7 +44,7 @@ to the slowest. size. A typical use for this case is filenames in the Linux kernel. The - dentry strucure has a d_name members, which is a struct qstr containing + dentry strucure has a d_name member, which is a struct qstr containing a unsigned int len and const unsigned char *name. you must use a sequence to declare this efficiently : diff --git a/genevent-new/genevent.c b/genevent-new/genevent.c index c1b1363e..124168d2 100644 --- a/genevent-new/genevent.c +++ b/genevent-new/genevent.c @@ -86,6 +86,10 @@ #define dprintf(...) #endif +void preset_field_type_size(event_t *event_type, + off_t offset_root, off_t offset_parent, + enum field_status *fixed_root, enum field_status *fixed_parent, + field_t *field); /* Code printing */ @@ -366,23 +370,26 @@ int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs, case ARRAY: dprintf("%s\n", basename); assert(td->size >= 0); - if(td->nested_type->type_name == NULL) { + if(((field_t*)td->fields.array[0])->type->type_name == NULL) { /* Not a named nested type : we must print its declaration first */ - if(print_type_declaration(td->nested_type, + if(print_type_declaration(((field_t*)td->fields.array[0])->type, fd, 0, basename, "")) return 1; } fprintf(fd, "#define LTTNG_ARRAY_SIZE_%s %llu\n", basename, td->size); fprintf(fd, "typedef "); - if(print_type(td->nested_type, fd, tabs, basename, "")) return 1; + if(print_type(((field_t*)td->fields.array[0])->type, + fd, tabs, basename, "")) return 1; fprintf(fd, " lttng_array_%s[LTTNG_ARRAY_SIZE_%s];\n", basename, basename); fprintf(fd, "\n"); break; case SEQUENCE: - if(td->nested_type->type_name == NULL) { + /* We assume that the sequence length type does not need to be declared. + */ + if(((field_t*)td->fields.array[1])->type->type_name == NULL) { /* Not a named nested type : we must print its declaration first */ - if(print_type_declaration(td->nested_type, + if(print_type_declaration(((field_t*)td->fields.array[1])->type, fd, 0, basename, "")) return 1; } fprintf(fd, "typedef struct lttng_sequence_%s lttng_sequence_%s;\n", @@ -393,7 +400,8 @@ int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs, print_tabs(1, fd); fprintf(fd, "unsigned int len;\n"); print_tabs(1, fd); - if(print_type(td->nested_type, fd, tabs, basename, "")) return 1; + if(print_type(((field_t*)td->fields.array[1])->type, + fd, tabs, basename, "")) return 1; fprintf(fd, " *array;\n"); fprintf(fd, "};\n"); fprintf(fd, "\n"); @@ -456,6 +464,461 @@ int print_type_declaration(type_descriptor_t * td, FILE *fd, unsigned int tabs, return 0; } + + + + +/***************************************************************************** + *Function name + * set_named_type_offsets : set the precomputable offset of the named type + *Input params + * type : the type + ****************************************************************************/ +void set_named_type_offsets(type_descriptor_t *type) +{ + enum field_status current_child_status = FIELD_FIXED_GENEVENT; + off_t current_offset = 0; + + preset_type_size( + current_offset, + ¤t_child_status, + type); + if(current_child_status == FIELD_FIXED_GENEVENT) { + current_offset += type->size; + } else { + current_offset = 0; + } +} + + +/***************************************************************************** + *Function name + * set_event_fields_offsets : set the precomputable offset of the fields + *Input params + * event : the event + ****************************************************************************/ +void set_event_fields_offsets(event_t *event) +{ + enum field_status current_child_status = FIELD_FIXED; + off_t current_offset = 0; + + for(unsigned int i = 0; i < event->type->fields.position; i++) { + /* For each field, set the field offset. */ + field_t *child_field = (field_t*)event->type->fields.array[i]; + type_descriptor_t *t = f->type; + /* Skip named types */ + if(t->type_name != NULL) continue; + + preset_type_size( + current_offset, + ¤t_child_status, + t); + if(current_child_status == FIELD_FIXED_GENEVENT) { + current_offset += type->size; + } else { + current_offset = 0; + } + } +} + + + +/***************************************************************************** + *Function name + * print_type_size : print the fixed sizes of the field type + * taken from LTTV. + * + * use offset_parent as offset to calculate alignment. + *Input params + * offset_parent : offset from the parent + * fixed_parent : Do we know a fixed offset to the parent ? + * type : type + ****************************************************************************/ +void print_type_size( + off_t offset_parent, + enum field_status *fixed_parent, + type_descriptor_t *type, + FILE *fd, + char *size_name) +{ + enum field_status local_fixed_parent; + guint i; + + g_assert(type->fixed_size == FIELD_UNKNOWN); + + size_t current_offset; + enum field_status current_child_status, final_child_status; + size_t max_size; + + switch(type->type) { + /* type sizes known by genevent/compiler */ + case INT_FIXED: + case UINT_FIXED: + case FLOAT: + case CHAR: + case UCHAR: + case SHORT: + case USHORT: + /* Align */ + fprintf(fd, "%s += ltt_align(%s, %s)", size_name); + /* Data */ + type->fixed_size = FIELD_FIXED_GENEVENT; + break; + /* host type sizes unknown by genevent, but known by the compiler */ + case INT: + case UINT: + case ENUM: + /* An enum is either : char or int. In gcc, always int. Hope + * it's always like this. */ + type->fixed_size = FIELD_FIXED_COMPILER; + type->compiler_size = COMPILER_INT; + break; + case LONG: + case ULONG: + type->fixed_size = FIELD_FIXED_COMPILER; + type->compiler_size = COMPILER_LONG; + break; + case POINTER: + type->fixed_size = FIELD_FIXED_COMPILER; + type->compiler_size = COMPILER_POINTER; + break; + case SIZE_T: + case SSIZE_T: + case OFF_T: + type->fixed_size = FIELD_FIXED_COMPILER; + type->compiler_size = COMPILER_SIZE_T; + break; + /* compound types : + * if all children has fixed size, then the parent size can be + * known directly and the copy can be done efficiently. + * if only part of the children has fixed size, then the contiguous + * elements will be copied in one bulk, but the variable size elements + * will be copied separately. This is necessary because those variable + * size elements are referenced by pointer in C. + */ + case SEQUENCE: + current_offset = 0; + local_fixed_parent = FIELD_FIXED_GENEVENT; + preset_type_size( + 0, + &local_fixed_parent, + ((field_t*)type->fields.array[0])->type); + preset_field_type_size( + 0, + &local_fixed_parent, + ((field_t*)type->fields.array[1])->type); + type->fixed_size = FIELD_VARIABLE; + *fixed_parent = FIELD_VARIABLE; + break; + case LTT_STRING: + field->fixed_size = FIELD_VARIABLE; + *fixed_parent = FIELD_VARIABLE; + break; + case LTT_ARRAY: + local_fixed_parent = FIELD_FIXED_GENEVENT; + preset_type_size( + 0, + &local_fixed_parent, + ((field_t*)type->fields.array[0])->type); + type->fixed_size = local_fixed_parent; + if(type->fixed_size == FIELD_FIXED_GENEVENT) { + type->size = + type->element_number * ((field_t*)type->fields.array[0])->type->size; + } else if(type->fixed_size == FIELD_FIXED_COMPILER) { + type->size = + type->element_number; + } else { + type->size = 0; + *fixed_parent = FIELD_VARIABLE; + } + break; + case LTT_STRUCT: + current_offset = 0; + current_child_status = FIELD_FIXED_GENEVENT; + for(i=0;ielement_number;i++) { + preset_field_type_size( + current_offset, + ¤t_child_status, + ((field_t*)type->fields.array[i])->type); + if(current_child_status == FIELD_FIXED_GENEVENT) { + current_offset += field->child[i]->field_size; + } else { + current_offset = 0; + } + } + if(current_child_status != FIELD_FIXED_GENEVENT) { + *fixed_parent = current_child_status; + type->size = 0; + type->fixed_size = current_child_status; + } else { + type->size = current_offset; + type->fixed_size = FIELD_FIXED_GENEVENT; + } + break; + case LTT_UNION: + current_offset = 0; + max_size = 0; + final_child_status = FIELD_FIXED_GENEVENT; + for(i=0;ielement_number;i++) { + enum field_status current_child_status = FIELD_FIXED; + preset_field_type_size( + current_offset, + ¤t_child_status, + ((field_t*)type->fields.array[i])->type); + if(current_child_status != FIELD_FIXED_GENEVENT) + final_child_status = current_child_status; + else + max_size = + max(max_size, ((field_t*)type->fields.array[i])->type->size); + } + if(final_child_status != FIELD_FIXED_GENEVENT AND COMPILER) { + g_error("LTTV does not support variable size fields in unions."); + /* This will stop the application. */ + *fixed_parent = final_child_status; + type->size = 0; + type->fixed_size = current_child_status; + } else { + type->size = max_size; + type->fixed_size = FIELD_FIXED_GENEVENT; + } + break; + } + +} + + +size_t get_field_type_size(LttTracefile *tf, LttEventType *event_type, + off_t offset_root, off_t offset_parent, + LttField *field, void *data) +{ + size_t size = 0; + guint i; + LttType *type; + + g_assert(field->fixed_root != FIELD_UNKNOWN); + g_assert(field->fixed_parent != FIELD_UNKNOWN); + g_assert(field->fixed_size != FIELD_UNKNOWN); + + field->offset_root = offset_root; + field->offset_parent = offset_parent; + + type = field->field_type; + + switch(type->type_class) { + case LTT_INT: + case LTT_UINT: + case LTT_FLOAT: + case LTT_ENUM: + case LTT_POINTER: + case LTT_LONG: + case LTT_ULONG: + case LTT_SIZE_T: + case LTT_SSIZE_T: + case LTT_OFF_T: + g_assert(field->fixed_size == FIELD_FIXED); + size = field->field_size; + break; + case LTT_SEQUENCE: + { + gint seqnum = ltt_get_uint(LTT_GET_BO(tf), + field->sequ_number_size, + data + offset_root); + + if(field->child[0]->fixed_size == FIELD_FIXED) { + size = field->sequ_number_size + + (seqnum * get_field_type_size(tf, event_type, + offset_root, offset_parent, + field->child[0], data)); + } else { + size += field->sequ_number_size; + for(i=0;ichild[0], data); + offset_root += child_size; + offset_parent += child_size; + size += child_size; + } + } + field->field_size = size; + } + break; + case LTT_STRING: + size = strlen((char*)(data+offset_root)) + 1;// length + \0 + field->field_size = size; + break; + case LTT_ARRAY: + if(field->fixed_size == FIELD_FIXED) + size = field->field_size; + else { + for(i=0;ifield_type->element_number;i++) { + size_t child_size; + child_size = get_field_type_size(tf, event_type, + offset_root, offset_parent, + field->child[0], data); + offset_root += child_size; + offset_parent += child_size; + size += child_size; + } + field->field_size = size; + } + break; + case LTT_STRUCT: + if(field->fixed_size == FIELD_FIXED) + size = field->field_size; + else { + size_t current_root_offset = offset_root; + size_t current_offset = 0; + size_t child_size = 0; + for(i=0;ielement_number;i++) { + child_size = get_field_type_size(tf, + event_type, current_root_offset, current_offset, + field->child[i], data); + current_offset += child_size; + current_root_offset += child_size; + + } + size = current_offset; + field->field_size = size; + } + break; + case LTT_UNION: + if(field->fixed_size == FIELD_FIXED) + size = field->field_size; + else { + size_t current_root_offset = field->offset_root; + size_t current_offset = 0; + for(i=0;ielement_number;i++) { + size = get_field_type_size(tf, event_type, + current_root_offset, current_offset, + field->child[i], data); + size = max(size, field->child[i]->field_size); + } + field->field_size = size; + } + break; + } + + return size; +} + + + + + +/* Print the code that calculates the length of an field */ +int print_field_len(type_descriptor_t * td, FILE *fd, unsigned int tabs, + char *nest_type_name, char *nest_field_name, char *field_name, + char *output_var, char *member_var) +{ + /* Type name : basename */ + char basename[PATH_MAX]; + unsigned int basename_len = 0; + + strcpy(basename, nest_type_name); + basename_len = strlen(basename); + + /* For a named type, we use the type_name directly */ + if(td->type_name != NULL) { + strncpy(basename, td->type_name, PATH_MAX); + basename_len = strlen(basename); + } else { + /* For a unnamed type, there must be a field name */ + if((basename_len != 0) + && (basename[basename_len-1] != '_') + && (field_name[0] != '\0')) { + strncat(basename, "_", PATH_MAX - basename_len); + basename_len = strlen(basename); + } + strncat(basename, field_name, PATH_MAX - basename_len); + } + + /* Field name : basefieldname */ + char basefieldname[PATH_MAX]; + unsigned int basefieldname_len = 0; + + strcpy(basefieldname, nest_field_name); + basefieldname_len = strlen(basefieldname); + + /* there must be a field name */ + strncat(basefieldname, field_name, PATH_MAX - basefieldname_len); + basefieldname_len = strlen(basefieldname); + + print_tabs(tabs, fd); + + switch(td->type) { + case INT_FIXED: + case UINT_FIXED: + case CHAR: + case UCHAR: + case SHORT: + case USHORT: + case INT: + case UINT: + case FLOAT: + case POINTER: + case LONG: + case ULONG: + case SIZE_T: + case SSIZE_T: + case OFF_T: + case ENUM: + fprintf(fd, "/* Size of %s */", field_name); + print_tabs(tabs, fd); + fprintf(fd, "%s = sizeof(", member_var); + if(print_type(td, fd, tabs, basename, "")) return 1; + fprintf(fd, ");\n"); + fprintf(fd, "%s += ltt_align(%s, %s);\n", output_var, member_var); + print_tabs(tabs, fd); + fprintf(fd, "%s += %s;\n", output_var, member_var); + break; + case STRING: + /* strings are made of bytes : no alignment. */ + fprintf(fd, "/* Size of %s */", basefieldname); + print_tabs(tabs, fd); + fprintf(fd, "%s = strlen(%s);", member_var, basefieldname); + break; + case ARRAY: + fprintf(fd, "/* Size of %s */", basefieldname); + print_tabs(tabs, fd); + + strncat(basefieldname, ".", PATH_MAX - basefieldname_len); + basefieldname_len = strlen(basefieldname); + + if(print_field_len(((field_t*)td->fields.array[0])->type, + fd, tabs, + basename, basefieldname, + output_var, member_var)) return 1; + + fprintf(fd, "%s = strlen(%s);", member_var, basefieldname); + + fprintf(fd, "lttng_array_%s", basename); + fprintf(fd, " %s", field_name); + break; + case SEQUENCE: + fprintf(fd, "lttng_sequence_%s *", basename); + fprintf(fd, " %s", field_name); + break; + case STRUCT: + fprintf(fd, "struct lttng_%s *", basename); + fprintf(fd, " %s", field_name); + break; + case UNION: + fprintf(fd, "union lttng_%s *", basename); + fprintf(fd, " %s", field_name); + break; + default: + printf("print_type : unknown type\n"); + return 1; + } + + 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) { @@ -481,10 +944,29 @@ int print_event_logging_function(char *basename, event_t *event, FILE *fd) fprintf(fd,"#else\n"); fprintf(fd, "{\n"); /* Print the function variables */ + print_tabs(1, fd); + fprintf(fd, "size_t member_length;"); + fprintf(fd, "size_t event_length = 0;"); - /* Calculate event variable len + event alignment offset. + /* Calculate event variable len + event data alignment offset. * Assume that the padding for alignment starts at a void* - * address. */ + * address. + * This excludes the header size and alignment. */ + + + for(unsigned int j = 0; j < event->fields.position; j++) { + /* For each field, calculate the field size. */ + field_t *f = (field_t*)event->fields.array[j]; + type_descriptor_t *t = f->type; + if(print_field_len(t, fd, 1, basename, "", + f->name, + "event_length", + "member_length")) return 1; + if(j < event->fields.position-1) { + fprintf(fd, ","); + fprintf(fd, "\n"); + } + } /* Take locks : make sure the trace does not vanish while we write on * it. A simple preemption disabling is enough (using rcu traces). */ @@ -780,7 +1262,7 @@ facility_t *ltt_facility_open(char * pathname) checkNamedTypesImplemented(&fac->named_types); generateChecksum(fac->name, &checksum, &fac->events); - + generated = TRUE; } else { diff --git a/genevent-new/ltt-facility-test-template.h b/genevent-new/ltt-facility-test-template.h new file mode 100644 index 00000000..c7e50ca4 --- /dev/null +++ b/genevent-new/ltt-facility-test-template.h @@ -0,0 +1,484 @@ +#ifndef _LTT_FACILITY_TEST_H_ +#define _LTT_FACILITY_TEST_H_ + + +/* Facility activation at compile time. */ +#ifdef CONFIG_LTT_FACILITY_TEST + +/* Named types */ + +enum lttng_tasklet_priority { + LTTNG_LOW, + LTTNG_HIGH, +}; + +enum lttng_irq_mode { + LTTNG_user, + LTTNG_kernel, +}; + +struct lttng_mystruct2 { + unsigned int irq_id; + enum lttng_irq_mode mode; + //struct lttng_mystruct teststr1; +}; + +size_t lttng_get_size_mystruct2(size_t *ret_align, + struct lttng_mystruct2 *obj) +{ + size_t size=0, align=0, locsize, localign; + + locsize = sizeof(unsigned int); + align = max(align, locsize); + size += ltt_align(size, locsize) + locsize; + + locsize = sizeof(enum lttng_irq_mode); + align = max(align, locsize); + size += ltt_align(size, locsize) + locsize; + + *ret_align = align; + + return size; +} + +void lttng_write_mystruct2(void **ws, + void **we, + struct lttng_mystruct2 *obj) +{ + size_t align=0, locsize, localign; + + locsize = lttng_get_size_mystruct2(&align, + obj); + + if(*ws == *we) { + *we += ltt_align(*we, align); + *ws = *we; + } else { + *we += ltt_align(*we, align); /* C alignment, ok to do a memcpy of it */ + } + + BUG_ON(locsize != sizeof(struct lttng_mystruct2)); + *we += locsize; +} + + + +#define LTTNG_ARRAY_SIZE_mystruct_myarray 10 +typedef uint64_t lttng_array_mystruct_myarray[LTTNG_ARRAY_SIZE_mystruct_myarray]; + +size_t lttng_get_size_array_mystruct_myarray(size_t *ret_align, + lttng_array_mystruct_myarray obj) +{ + size_t size=0, align=0, locsize, localign; + + locsize = sizeof(uint64_t); + align = max(align, locsize); + size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize); + + *ret_align = align; + + return size; +} + +void lttng_write_array_mystruct_myarray(void **ws, + void **we, + struct lttng_mystruct2 *obj) +{ + size_t align=0, locsize, localign; + + locsize = lttng_get_size_array_mystruct_myarray(&align, + obj); + + if(*ws == *we) { + *we += ltt_align(*we, align); + *ws = *we; + } else { + *we += ltt_align(*we, align); /* C alignment, ok to do a memcpy of it */ + } + + BUG_ON(locsize != LTTNG_ARRAY_SIZE_mystruct_myarray * sizeof(uint64_t)); + + *we += locsize; +} + + +typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence; +struct lttng_sequence_mystruct_mysequence { + unsigned int len; + double *array; +}; + + +size_t lttng_get_size_sequence_mystruct_mysequence(size_t *ret_align, + lttng_sequence_mystruct_mysequence *obj) +{ + size_t size=0, align=0, locsize, localign; + + locsize = sizeof(unsigned int); + align = max(align, locsize); + size += ltt_align(size, locsize) + locsize; + + locsize = sizeof(double); + align = max(align, locsize); + size += ltt_align(size, locsize) + (obj->len * locsize); + + *ret_align = align; + + return size; +} + +void lttng_write_sequence_mystruct_mysequence(void **ws, + void **we, + lttng_sequence_mystruct_mysequence *obj) +{ + size_t align=0, locsize, localign; + + /* Flush pending memcpy */ + if(*ws != *we) { + memcpy(*ws, obj, *we-*ws); + *ws = *we; + } + + lttng_get_size_sequence_mystruct_mysequence(&align, + obj); + + *we += ltt_align(*we, align); + *ws = *we; + + *we += ltt_align(*we, sizeof(unsigned int)); + *ws = *we; + *we += sizeof(unsigned int); + memcpy(*ws, &obj->len, *we-*ws); + *ws = *we; + + *we += ltt_align(*we, sizeof(double)); + *ws = *we; + *we += obj->len * sizeof(double); + memcpy(*ws, obj->array, *we-*ws); + *ws = *we; +} + + + +union lttng_mystruct_myunion { + double myfloat; + unsigned long myulong; +}; + +size_t lttng_get_size_mystruct_myunion(size_t *ret_align, + union lttng_mystruct_myunion *obj) +{ + size_t size=0, align=0, locsize, localign; + + locsize = sizeof(double); + align = max(align, locsize); + size = max(size, locsize); + + locsize = sizeof(unsigned long); + align = max(align, locsize); + size = max(size, locsize); + + *ret_align = align; + + return size; +} + + +void lttng_write_mystruct_myunion(void **ws, + void **we, + union lttng_mystruct_myunion *obj) +{ + size_t align=0, locsize, localign; + + locsize = lttng_get_size_mystruct_myunion(&align, + obj); + + if(*ws == *we) { + *we += ltt_align(*we, align); + *ws = *we; + } else { + *we += ltt_align(*we, align); /* C alignment, ok to do a memcpy of it */ + } + + BUG_ON(locsize != sizeof(union lttng_mystruct_myunion)); + + *we += locsize; +} + + +struct lttng_mystruct { + unsigned int irq_id; + enum lttng_irq_mode mode; + struct lttng_mystruct2 teststr; + lttng_array_mystruct_myarray myarray; + lttng_sequence_mystruct_mysequence mysequence; + union lttng_mystruct_myunion myunion; +}; + +size_t lttng_get_size_mystruct(size_t *ret_align, + struct lttng_mystruct *obj) +{ + size_t size=0, align=0, locsize, localign; + + locsize = sizeof(unsigned int); + align = max(align, locsize); + size += ltt_align(size, locsize) + locsize; + + locsize = sizeof(enum lttng_irq_mode); + align = max(align, locsize); + size += ltt_align(size, locsize) + locsize; + + locsize = lttng_get_size_mystruct2(&localign, + &obj->teststr); + align = max(align, localign); + size += ltt_align(size, localign) + locsize; + + locsize = lttng_get_size_array_mystruct_myarray(&localign, + obj->myarray); + align = max(align, localign); + size += ltt_align(size, localign) + locsize; + + locsize = lttng_get_size_sequence_mystruct_mysequence(&localign, + &obj->mysequence); + align = max(align, localign); + size += ltt_align(size, localign) + locsize; + + locsize = lttng_get_size_mystruct_myunion(&localign, + &obj->myunion); + align = max(align, localign); + size += ltt_align(size, localign) + locsize; + + *ret_align = align; + + return size; +} + +struct lttng_mystruct { + unsigned int irq_id; + enum lttng_irq_mode mode; + struct lttng_mystruct2 teststr; + lttng_array_mystruct_myarray myarray; + lttng_sequence_mystruct_mysequence mysequence; + union lttng_mystruct_myunion myunion; +}; + + +void lttng_write_mystruct(void **ws, + void **we, + struct lttng_mystruct *obj) +{ + size_t align=0, locsize, localign; + + lttng_get_size_mystruct(&align, + obj); + + if(*ws == *we) { + *we += ltt_align(*we, align); + *ws = *we; + } else { + *we += ltt_align(*we, align); /* C alignment, ok to do a memcpy of it */ + } + + locsize = sizeof(unsigned int); + *we += ltt_align(*we, locsize) + locsize; + + locsize = sizeof(enum lttng_irq_mode); + *we += ltt_align(*we, locsize) + locsize; + + lttng_write_mystruct2(ws, we, + &obj->teststr); + + lttng_write_array_mystruct_myarray(ws, we, + obj->myarray); + + /* Variable length field */ + lttng_write_sequence_mystruct_mysequence(ws, we, + &obj->mysequence); + + lttng_write_mystruct_myunion(ws, we, + obj->myunion); + + /* Don't forget to flush last write..... */ +} + + + +/* Event syscall_entry structures */ + +/* Event syscall_entry logging function */ +static inline void trace_test_syscall_entry( + unsigned int syscall_id, + void * address) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event syscall_exit structures */ + +/* Event syscall_exit logging function */ +static inline void trace_test_syscall_exit( + void) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event trap_entry structures */ + +/* Event trap_entry logging function */ +static inline void trace_test_trap_entry( + unsigned int trap_id, + void * address) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event trap_exit structures */ + +/* Event trap_exit logging function */ +static inline void trace_test_trap_exit( + void) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event soft_irq_entry structures */ + +/* Event soft_irq_entry logging function */ +static inline void trace_test_soft_irq_entry( + void * softirq_id) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event soft_irq_exit structures */ + +/* Event soft_irq_exit logging function */ +static inline void trace_test_soft_irq_exit( + void * softirq_id) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event tasklet_entry structures */ + +/* Event tasklet_entry logging function */ +static inline void trace_test_tasklet_entry( + enum lttng_tasklet_priority priority, + void * address, + unsigned long data) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event tasklet_exit structures */ + +/* Event tasklet_exit logging function */ +static inline void trace_test_tasklet_exit( + enum lttng_tasklet_priority priority, + void * address, + unsigned long data) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event irq_entry structures */ + +/* Event irq_entry logging function */ +static inline void trace_test_irq_entry( + unsigned int irq_id, + enum lttng_irq_mode mode) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event irq_exit structures */ + +/* Event irq_exit logging function */ +static inline void trace_test_irq_exit( + void) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +/* Event big_array structures */ +union lttng_test_big_array_myarray_b { + void * c; +}; + +struct lttng_test_big_array_myarray { + void * a; + union lttng_test_big_array_myarray_b b; +}; + +#define LTTNG_ARRAY_SIZE_test_big_array_myarray 2 +typedef struct lttng_test_big_array_myarray lttng_array_test_big_array_myarray[LTTNG_ARRAY_SIZE_test_big_array_myarray]; + +#define LTTNG_ARRAY_SIZE_test_big_array_myarray 10000 +typedef lttng_array_test_big_array_myarray lttng_array_test_big_array_myarray[LTTNG_ARRAY_SIZE_test_big_array_myarray]; + + +/* Event big_array logging function */ +static inline void trace_test_big_array( + lttng_array_test_big_array_myarray myarray) +#ifndef CONFIG_LTT +{ +} +#else +{ +} +#endif //CONFIG_LTT + + +#endif //CONFIG_LTT_FACILITY_TEST + +#endif //_LTT_FACILITY_TEST_H_ diff --git a/genevent-new/parser.c b/genevent-new/parser.c index 17ebef72..a2a07e21 100644 --- a/genevent-new/parser.c +++ b/genevent-new/parser.c @@ -498,7 +498,7 @@ void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types, 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); + parseFields(in, f, unnamed_types, named_types, 1); break; default: in->error(in, "expecting or "); @@ -535,30 +535,40 @@ void parseEvent(parse_file_t *in, event_t * ev, sequence_t * unnamed_types, * f : field * unnamed_types : array of unamed types * named_types : array of named types + * tag : is field surrounded by a tag ? ****************************************************************************/ void parseFields(parse_file_t *in, field_t *f, sequence_t * unnamed_types, - table_t * named_types) + table_t * named_types, + int tag) { char * token; + if(tag) { + // + getFieldAttributes(in, f); + if(f->name == NULL) in->error(in, "Field not named"); + getRAnglebracket(in); - // - getFieldAttributes(in, f); - if(f->name == NULL) in->error(in, "Field not named"); - getRAnglebracket(in); - - f->description = getDescription(in); + f->description = getDescription(in); + } // getLAnglebracket(in); f->type = parseType(in,NULL, unnamed_types, named_types); - getLAnglebracket(in); - getForwardslash(in); - token = getName(in); - if(strcmp("field",token))in->error(in,"not a valid field definition"); - getRAnglebracket(in); // + /* Those will be set later by preset_field_type_size */ + f->fixed_root = FIELD_UNKNOWN; + f->fixed_parent = FIELD_UNKNOWN; + f->fixed_size = FIELD_UNKNOWN; + + if(tag) { + getLAnglebracket(in); + getForwardslash(in); + token = getName(in); + if(strcmp("field",token))in->error(in,"not a valid field definition"); + getRAnglebracket(in); // + } } @@ -611,7 +621,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, f = (field_t *)memAlloc(sizeof(field_t)); sequence_push(&(t->fields),f); - parseFields(in, f, unnamed_types, named_types); + parseFields(in, f, unnamed_types, named_types, 1); //next field getLAnglebracket(in); @@ -634,7 +644,7 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, while(strcmp("field",token) == 0){ f = (field_t *)memAlloc(sizeof(field_t)); sequence_push(&(t->fields),f); - parseFields(in, f, unnamed_types, named_types); + parseFields(in, f, unnamed_types, named_types, 1); //next field getLAnglebracket(in); @@ -648,13 +658,20 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, } else if(strcmp(token,"array") == 0) { t->type = ARRAY; + sequence_init(&(t->fields)); getTypeAttributes(in, t, unnamed_types, named_types); if(t->size == 0) in->error(in, "Array has empty size"); getForwardslash(in); getRAnglebracket(in); // - getLAnglebracket(in); // - t->nested_type = parseType(in, NULL, unnamed_types, named_types); + getLAnglebracket(in); // + /* subfield */ + f = (field_t *)memAlloc(sizeof(field_t)); + sequence_push(&(t->fields),f); + parseFields(in, f, unnamed_types, named_types, 0); + + //getLAnglebracket(in); // + //t->nested_type = parseType(in, NULL, unnamed_types, named_types); getLAnglebracket(in); // getForwardslash(in); @@ -664,19 +681,33 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, } else if(strcmp(token,"sequence") == 0) { t->type = SEQUENCE; + sequence_init(&(t->fields)); //getTypeAttributes(in, t, unnamed_types, named_types); //getForwardslash(in); getRAnglebracket(in); // - getLAnglebracket(in); // - t->length_type = parseType(in, NULL, unnamed_types, named_types); + getLAnglebracket(in); // + /* subfield */ + f = (field_t *)memAlloc(sizeof(field_t)); + sequence_push(&(t->fields),f); + parseFields(in, f, unnamed_types, named_types, 0); + + getLAnglebracket(in); // + /* subfield */ + f = (field_t *)memAlloc(sizeof(field_t)); + sequence_push(&(t->fields),f); + parseFields(in, f, unnamed_types, named_types, 0); - getLAnglebracket(in); // + //getLAnglebracket(in); // + //t->length_type = parseType(in, NULL, unnamed_types, named_types); - t->nested_type = parseType(in, NULL, unnamed_types, named_types); + //getLAnglebracket(in); // - if(t->length_type == NULL) in->error(in, "Sequence has no length type"); - switch(t->length_type->type) { + //t->nested_type = parseType(in, NULL, unnamed_types, named_types); + + if(t->fields.position < 1) in->error(in, "Sequence has no length type"); + if(t->fields.position < 2) in->error(in, "Sequence has no subtype"); + switch(((field_t*)t->fields.array[0])->type->type) { case UINT_FIXED : case UCHAR : case USHORT : @@ -689,8 +720,6 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, in->error(in, "Wrong length type for sequence"); } - - if(t->nested_type == NULL) in->error(in, "Sequence has no nested type"); getLAnglebracket(in); // getForwardslash(in); token = getName(in); @@ -759,24 +788,28 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, } else if(strcmp(token,"char") == 0) { t->type = CHAR; + t->size = 1; getTypeAttributes(in, t, unnamed_types, named_types); getForwardslash(in); getRAnglebracket(in); } else if(strcmp(token,"uchar") == 0) { t->type = UCHAR; + t->size = 1; getTypeAttributes(in, t, unnamed_types, named_types); getForwardslash(in); getRAnglebracket(in); } else if(strcmp(token,"short") == 0) { t->type = SHORT; + t->size = 2; getTypeAttributes(in, t, unnamed_types, named_types); getForwardslash(in); getRAnglebracket(in); } else if(strcmp(token,"ushort") == 0) { t->type = USHORT; + t->size = 2; getTypeAttributes(in, t, unnamed_types, named_types); getForwardslash(in); getRAnglebracket(in); @@ -844,17 +877,14 @@ type_descriptor_t *parseType(parse_file_t *in, type_descriptor_t *inType, } else if(strcmp(token,"typeref") == 0){ // Must be a named type - if(inType != NULL) - in->error(in,"Named type cannot refer to a named type"); - else { - free(t); - sequence_pop(unnamed_types); - token = getNameAttribute(in); - t = find_named_type(token, named_types); - getForwardslash(in); // - getRAnglebracket(in); - return t; - } + free(t); + sequence_pop(unnamed_types); + token = getNameAttribute(in); + t = find_named_type(token, named_types); + if(t == NULL) in->error(in,"Named referred to must be pre-declared."); + getForwardslash(in); // + getRAnglebracket(in); + return t; }else in->error(in,"not a valid type"); return t; diff --git a/genevent-new/parser.h b/genevent-new/parser.h index 58879098..edcaeb04 100644 --- a/genevent-new/parser.h +++ b/genevent-new/parser.h @@ -101,25 +101,21 @@ typedef enum _data_type { NONE } data_type_t; -/* Event type descriptors */ - typedef struct _type_descriptor { char * type_name; //used for named type data_type_t type; char *fmt; - unsigned long long size; + size_t size; sequence_t labels; // for enumeration sequence_t labels_description; int already_printed; - sequence_t fields; // for structure - struct _type_descriptor *nested_type; // for array and sequence - struct _type_descriptor *length_type; // for sequence + sequence_t fields; // for structure, array and sequence int alignment; } type_descriptor_t; -/* Fields within types */ +/* Fields within types or events */ typedef struct _field{ char *name; char *description;