write and size calc template
authorcompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 11 Nov 2005 04:11:04 +0000 (04:11 +0000)
committercompudj <compudj@04897980-b3bd-0310-b5e0-8ef037075253>
Fri, 11 Nov 2005 04:11:04 +0000 (04:11 +0000)
git-svn-id: http://ltt.polymtl.ca/svn@1318 04897980-b3bd-0310-b5e0-8ef037075253

genevent-new/README
genevent-new/genevent.c
genevent-new/ltt-facility-test-template.h [new file with mode: 0644]
genevent-new/parser.c
genevent-new/parser.h

index 951f146cc556c6bad382207aaf45b982abb146bf..7b16fcdf406a01815ce33b742e58ed7c31d07004 100644 (file)
@@ -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 :
index c1b1363e6d2ba83d8cc384dc7b6f4082df341a64..124168d27efc51baeb7d12ef3d2e1ee7a96f6858 100644 (file)
 #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,
+                       &current_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,
+        &current_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;i<type->element_number;i++) {
+        preset_field_type_size(
+          current_offset, 
+          &current_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;i<type->element_number;i++) {
+        enum field_status current_child_status = FIELD_FIXED;
+        preset_field_type_size(
+          current_offset, 
+          &current_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;i<seqnum;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_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;i<field->field_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;i<type->element_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;i<type->element_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 (file)
index 0000000..c7e50ca
--- /dev/null
@@ -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_
index 17ebef72373e87de845e524021e659a0b8e6a21e..a2a07e212c054adaca1dea3b9e95152b6a3f91aa 100644 (file)
@@ -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 </event> or <field >");
@@ -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 <field> </field> 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) {
+               //<field name=field_name> <description> <type> </field>
+               getFieldAttributes(in, f);
+               if(f->name == NULL) in->error(in, "Field not named");
+               getRAnglebracket(in);
 
-  //<field name=field_name> <description> <type> </field>
-  getFieldAttributes(in, f);
-  if(f->name == NULL) in->error(in, "Field not named");
-  getRAnglebracket(in);
-
-  f->description = getDescription(in);
+               f->description = getDescription(in);
+       }
 
   //<int size=...>
   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); //</field>
+       /* 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); //</field>
+       }
 }
 
 
@@ -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); //<array size=n>
 
-    getLAnglebracket(in); //<type struct> 
-    t->nested_type = parseType(in, NULL, unnamed_types, named_types);
+    getLAnglebracket(in); //<subtype> 
+               /* subfield */
+               f = (field_t *)memAlloc(sizeof(field_t));
+               sequence_push(&(t->fields),f);
+    parseFields(in, f, unnamed_types, named_types, 0);
+
+    //getLAnglebracket(in); //<type struct> 
+    //t->nested_type = parseType(in, NULL, unnamed_types, named_types);
 
     getLAnglebracket(in); //</array>
     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); //<sequence>
 
-    getLAnglebracket(in); //<type sequence> 
-    t->length_type = parseType(in, NULL, unnamed_types, named_types);
+    getLAnglebracket(in); //<sequence size type> 
+               /* subfield */
+               f = (field_t *)memAlloc(sizeof(field_t));
+               sequence_push(&(t->fields),f);
+    parseFields(in, f, unnamed_types, named_types, 0);
+
+    getLAnglebracket(in); //<subtype> 
+               /* subfield */
+               f = (field_t *)memAlloc(sizeof(field_t));
+               sequence_push(&(t->fields),f);
+    parseFields(in, f, unnamed_types, named_types, 0);
 
-    getLAnglebracket(in); //<type sequence> 
+    //getLAnglebracket(in); //<type sequence> 
+    //t->length_type = parseType(in, NULL, unnamed_types, named_types);
 
-    t->nested_type = parseType(in, NULL, unnamed_types, named_types);
+    //getLAnglebracket(in); //<type sequence> 
 
-    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); //</sequence>
     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);  //<typeref name=type_name/>
-      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);  //<typeref name=type_name/>
+               getRAnglebracket(in);
+               return t;
   }else in->error(in,"not a valid type");
 
   return t;
index 588790989895417e8e483487873a983a24dc4342..edcaeb041352afda280dd588ea77795b61c5ed00 100644 (file)
@@ -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;
This page took 0.038617 seconds and 4 git commands to generate.