+#define __KERNEL__
+
#include <assert.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
+
+#include <linux/compiler.h>
#define min(a,b) (((a)<(b))?a:b)
#define max(a,b) (((a)>(b))?a:b)
#define BUG_ON(a) assert(!(a))
+// Useful outside __KERNEL__. Not used here because inline is already redefined.
+#define force_inline inline __attribute__((always_inline))
+
/* Calculate the offset needed to align the type */
static inline unsigned int ltt_align(size_t align_drift,
size_t size_of_type)
//struct lttng_mystruct teststr1;
};
-
+#if 0
static inline size_t lttng_get_size_mystruct2(
struct lttng_mystruct2 * obj)
{
return sizeof(struct lttng_mystruct2);
}
+#endif //0
static inline size_t lttng_get_alignment_mystruct2(
struct lttng_mystruct2 *obj)
return align;
}
-static inline size_t lttng_write_mystruct2(
- void *buf,
+static inline void lttng_write_mystruct2(
+ void *buffer,
+ size_t *to_base,
size_t *to,
void **from,
size_t *len,
struct lttng_mystruct2 *obj)
{
- size_t align, size, varalign;
+ size_t align, size;
align = lttng_get_alignment_mystruct2(obj);
- size = lttng_get_size_mystruct2(obj);
+ //size = lttng_get_size_mystruct2(obj);
+ size = sizeof(struct lttng_mystruct2);
if(*len == 0) {
- varalign = ltt_align(*to, align); /* align output */
- *to += varalign;
+ *to += ltt_align(*to, align); /* align output */
} else {
- varalign = ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
- *len += varalign;
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
*len += size;
-
- return varalign+size;
}
#define LTTNG_ARRAY_SIZE_mystruct_myarray 10
typedef uint64_t lttng_array_mystruct_myarray[LTTNG_ARRAY_SIZE_mystruct_myarray];
+#if 0
static inline size_t lttng_get_size_array_mystruct_myarray(
lttng_array_mystruct_myarray obj)
{
BUG_ON(ltt_align(size, locsize) != 0);
size += LTTNG_ARRAY_SIZE_mystruct_myarray * locsize;
- BUG_ON(size != LTTNG_ARRAY_SIZE_mystruct_myarray * sizeof(uint64_t));
+ BUG_ON(sizeof(lttng_array_mystruct_myarray) != size);
- return size;
+ return sizeof(lttng_array_mystruct_myarray);
}
+#endif //0
static inline size_t lttng_get_alignment_array_mystruct_myarray(
lttng_array_mystruct_myarray obj)
}
-static inline size_t lttng_write_array_mystruct_myarray(
- void *buf,
+static inline void lttng_write_array_mystruct_myarray(
+ void *buffer,
+ size_t *to_base,
size_t *to,
void **from,
size_t *len,
lttng_array_mystruct_myarray obj)
{
- size_t align, size, varalign;
+ size_t align, size;
align = lttng_get_alignment_array_mystruct_myarray(obj);
- size = lttng_get_size_array_mystruct_myarray(obj);
+ //size = lttng_get_size_array_mystruct_myarray(obj);
+ size = sizeof(lttng_array_mystruct_myarray);
if(*len == 0) {
- varalign = ltt_align(*to, align); /* align output */
- *to += varalign;
+ *to += ltt_align(*to, align); /* align output */
} else {
- varalign = ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
- *len += varalign;
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
*len += size;
+#if 0
+ /* For varlen child : let the child align itself. */
+ for(unsigned int i=0; i<LTTNG_ARRAY_SIZE_mystruct_myarray; i++) {
+ lttng_write_child(buffer, to_base, to, from, len, obj[i]);
+ }
+#endif //0
- return varalign + size; /* offset in the from */
}
double *array;
};
-
+#if 0
static inline size_t lttng_get_size_sequence_mystruct_mysequence(
lttng_sequence_mystruct_mysequence *obj)
{
locsize = sizeof(double);
size += ltt_align(size, locsize) + (obj->len * locsize);
+ /* Realign on arch size */
+ locsize = sizeof(void *);
+ size += ltt_align(size, locsize);
+
return size;
}
+#endif //0
static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
lttng_sequence_mystruct_mysequence *obj)
}
-static inline size_t lttng_write_sequence_mystruct_mysequence(
- void *buf,
+static inline void lttng_write_sequence_mystruct_mysequence(
+ void *buffer,
+ size_t *to_base,
size_t *to,
void **from,
size_t *len,
lttng_sequence_mystruct_mysequence *obj)
{
size_t align;
- size_t size=0;
- void *varfrom;
- size_t varlen=0;
- size_t varalign=0;
+ size_t size;
/* Flush pending memcpy */
if(*len != 0) {
- memcpy(buf+*to, *from, *len);
- *to += *len;
- *len = 0;
+ if(buffer != NULL)
+ memcpy(buffer+*to_base+*to, *from, *len);
}
+ *to += *len;
+ *len = 0;
align = lttng_get_alignment_sequence_mystruct_mysequence(obj);
//no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
/* Align output */
- varalign = ltt_align((size_t)(*to), align);
- size += varalign;
+ *to += ltt_align(*to, align); /* *len = 0 in this function */
/* Copy members */
- varalign = ltt_align(size, sizeof(unsigned int));
- size += varalign;
- varfrom = &obj->len;
- varlen += sizeof(unsigned int);
- memcpy(buf+*to+size, varfrom, varlen);
- size += varlen;
- varlen = 0;
-
- varalign = ltt_align(size, sizeof(double));
- size += varalign;
- varfrom = obj->array;
- varlen += obj->len * sizeof(double);
- memcpy(buf+*to+size, varfrom, varlen);
- size += varlen;
- varlen = 0;
+ size = sizeof(unsigned int);
+ *to += ltt_align(*to, size);
+ if(buffer != NULL)
+ memcpy(buffer+*to_base+*to, &obj->len, size);
+ *to += size;
+ size = sizeof(double);
+ *to += ltt_align(*to, size);
+ size = obj->len * sizeof(double);
+ if(buffer != NULL)
+ memcpy(buffer+*to_base+*to, obj->array, size);
*to += size;
+#if 0
+ /* If varlen child : let child align itself */
+ for(unsigned int i=0; i<obj->len; i++) {
+ lttng_write_child(buffer, to_base, to, from, len, obj->array[i]);
+ }
+#endif //0
+
+
+ /* Realign the *to_base on arch size, set *to to 0 */
+ *to = ltt_align(*to, sizeof(void *));
+ *to_base = *to_base+*to;
+ *to = 0;
/* Put source *from just after the C sequence */
*from = obj+1;
-
- return size;
}
unsigned long myulong;
};
-
+#if 0
static inline size_t lttng_get_size_mystruct_myunion(
union lttng_mystruct_myunion *obj)
{
BUG_ON(size != sizeof(union lttng_mystruct_myunion));
- return size;
+ return sizeof(union lttng_mystruct_myunion);
}
-
+#endif //0
static inline size_t lttng_get_alignment_mystruct_myunion(
union lttng_mystruct_myunion *obj)
}
-static inline size_t lttng_write_mystruct_myunion(
- void *buf,
+static inline void lttng_write_mystruct_myunion(
+ void *buffer,
+ size_t *to_base,
size_t *to,
void **from,
size_t *len,
union lttng_mystruct_myunion *obj)
{
- size_t align, size, varalign;
+ size_t align, size;
align = lttng_get_alignment_mystruct_myunion(obj);
- size = lttng_get_size_mystruct_myunion(obj);
+ //size = lttng_get_size_mystruct_myunion(obj);
+ size = sizeof(union lttng_mystruct_myunion);
if(*len == 0) {
- varalign = ltt_align(*to, align); /* align output */
- *to += varalign;
+ *to += ltt_align(*to, align); /* align output */
} else {
- varalign = ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
- *len += varalign;
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
*len += size;
- return varalign + size;
+ /* Assert : no varlen child. */
}
union lttng_mystruct_myunion myunion;
};
+#if 0
static inline size_t lttng_get_size_mystruct(
struct lttng_mystruct *obj)
{
return size;
}
-
+#endif //0
static inline size_t lttng_get_alignment_mystruct(
struct lttng_mystruct *obj)
}
static inline void lttng_write_mystruct(
- void *buf,
+ void *buffer,
+ size_t *to_base,
size_t *to,
void **from,
size_t *len,
struct lttng_mystruct *obj)
{
- size_t align, size=0, locsize;
+ size_t align, size;
align = lttng_get_alignment_mystruct(obj);
// no need : contains variable size fields.
/* Contains variable sized fields : must explode the structure */
- locsize = sizeof(unsigned int);
- locsize += ltt_align(size, locsize) + locsize;
- *len += locsize;
- size += locsize;
+ size = sizeof(unsigned int);
+ size += ltt_align(*to+*len, size) + size;
+ *len += size;
- locsize = sizeof(enum lttng_irq_mode);
- locsize += ltt_align(size, locsize) + locsize;
- *len += locsize;
- size += locsize;
+ size = sizeof(enum lttng_irq_mode);
+ size += ltt_align(*to+*len, size) + size;
+ *len += size;
- size += lttng_write_mystruct2(buf, to, from, len, &obj->teststr);
+ lttng_write_mystruct2(buffer, to_base, to, from, len, &obj->teststr);
- size += lttng_write_array_mystruct_myarray(buf, to, from, len, obj->myarray);
+ lttng_write_array_mystruct_myarray(buffer, to_base, to, from, len, obj->myarray);
/* Variable length field */
- size += lttng_write_sequence_mystruct_mysequence(buf, to, from, len, &obj->mysequence);
-
- size += lttng_write_mystruct_myunion(buf, to, from, len, &obj->myunion);
+ lttng_write_sequence_mystruct_mysequence(buffer, to_base, to, from, len, &obj->mysequence);
+ /* After this previous write, we are sure that *to is 0, *len is 0 and
+ * *to_base is aligned on the architecture size : to rest of alignment will
+ * be calculated statically. */
+
+ lttng_write_mystruct_myunion(buffer, to_base, to, from, len, &obj->myunion);
/* Don't forget to flush last write..... */
}
test.mysequence.len = 20;
test.mysequence.array = malloc(20);
- size_t size = lttng_get_size_mystruct(&test);
- size_t align = lttng_get_alignment_mystruct(&test);
-
- /* the buffer is allocated on arch_size alignment */
- void *buf = malloc(align + size);
+ //size_t size = lttng_get_size_mystruct(&test);
+ //size_t align = lttng_get_alignment_mystruct(&test);
+ //
+ size_t to_base = 0; /* the buffer is allocated on arch_size alignment */
size_t to = 0;
void *from = &test;
size_t len = 0;
- lttng_write_mystruct(buf, &to, &from, &len, &test);
+ /* Get size */
+ lttng_write_mystruct(NULL, &to_base, &to, &from, &len, &test);
+ /* Size = to_base + to + len */
+
+ void *buffer = malloc(to_base + to + len);
+ to_base = 0; /* the buffer is allocated on arch_size alignment */
+ to = 0;
+ from = &test;
+ len = 0;
+
+ lttng_write_mystruct(buffer, &to_base, &to, &from, &len, &test);
/* Final flush */
/* Flush pending memcpy */
if(len != 0) {
- memcpy(buf+to, from, len);
+ // Assert buffer != NULL */
+ memcpy(buffer+to_base+to, from, len);
to += len;
from += len;
len = 0;
}
free(test.mysequence.array);
- free(buf);
+ free(buffer);
}