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 :
#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 */
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",
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");
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;i<type->element_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;i<type->element_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;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)
{
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). */
checkNamedTypesImplemented(&fac->named_types);
generateChecksum(fac->name, &checksum, &fac->events);
-
+
generated = TRUE;
}
else {
--- /dev/null
+#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_
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 >");
* 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>
+ }
}
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);
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);
}
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);
}
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 :
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);
}
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);
}
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;
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;