+#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)
};
-size_t lttng_get_size_mystruct2(
- struct lttng_mystruct2 *obj)
+static inline size_t lttng_get_size_mystruct2(
+ struct lttng_mystruct2 * obj)
{
size_t size=0, locsize;
return sizeof(struct lttng_mystruct2);
}
-size_t lttng_get_alignment_mystruct2(
+static inline size_t lttng_get_alignment_mystruct2(
struct lttng_mystruct2 *obj)
{
size_t align=0, localign;
return align;
}
-void lttng_write_mystruct2(void **to,
+static inline void lttng_write_mystruct2(
+ void **to_base,
+ size_t *to,
void **from,
size_t *len,
struct lttng_mystruct2 *obj)
size = lttng_get_size_mystruct2(obj);
if(*len == 0) {
- *to += ltt_align((size_t)(*to), align); /* align output */
+ *to += ltt_align(*to, align); /* align output */
} else {
- *len += ltt_align((size_t)(*to+*len), align); /* C alignment, ok to do a memcpy of it */
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
*len += size;
#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(
+static inline size_t lttng_get_size_array_mystruct_myarray(
lttng_array_mystruct_myarray obj)
{
size_t size=0, locsize;
return size;
}
-size_t lttng_get_alignment_array_mystruct_myarray(
+static inline size_t lttng_get_alignment_array_mystruct_myarray(
lttng_array_mystruct_myarray obj)
{
size_t align=0, localign;
}
-void lttng_write_array_mystruct_myarray(void **to,
+static inline void lttng_write_array_mystruct_myarray(
+ void **to_base,
+ size_t *to,
void **from,
size_t *len,
lttng_array_mystruct_myarray obj)
size = lttng_get_size_array_mystruct_myarray(obj);
if(*len == 0) {
- *to += ltt_align((size_t)(*to), align); /* align output */
+ *to += ltt_align(*to, align); /* align output */
} else {
- *len += ltt_align((size_t)(*to+*len), align); /* C alignment, ok to do a memcpy of it */
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
*len += size;
};
-size_t lttng_get_size_sequence_mystruct_mysequence(
+static inline size_t lttng_get_size_sequence_mystruct_mysequence(
lttng_sequence_mystruct_mysequence *obj)
{
size_t size=0, locsize;
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;
}
-size_t lttng_get_alignment_sequence_mystruct_mysequence(
+static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
lttng_sequence_mystruct_mysequence *obj)
{
size_t align=0, localign;
}
-void lttng_write_sequence_mystruct_mysequence(void **to,
+static inline void lttng_write_sequence_mystruct_mysequence(
+ void **to_base,
+ size_t *to,
void **from,
size_t *len,
lttng_sequence_mystruct_mysequence *obj)
{
- size_t align, size;
+ size_t align;
void *varfrom;
size_t varlen=0;
/* Flush pending memcpy */
if(*len != 0) {
- memcpy(*to, *from, *len);
+ memcpy(*to_base+*to, *from, *len);
*to += *len;
*len = 0;
}
//no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
/* Align output */
- *to += ltt_align((size_t)(*to), align);
+ *to += ltt_align(*to, align); /* *len = 0 in this function */
/* Copy members */
- *to += ltt_align((size_t)*to, sizeof(unsigned int));
+ *to += ltt_align(*to, sizeof(unsigned int));
varfrom = &obj->len;
varlen += sizeof(unsigned int);
- memcpy(*to, varfrom, varlen);
+ memcpy(*to_base+*to, varfrom, varlen);
*to += varlen;
varlen = 0;
- *to += ltt_align((size_t)*to, sizeof(double));
+ *to += ltt_align(*to, sizeof(double));
varfrom = obj->array;
varlen += obj->len * sizeof(double);
- memcpy(*to, varfrom, varlen);
+ memcpy(*to_base+*to, varfrom, varlen);
*to += varlen;
varlen = 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;
}
};
-size_t lttng_get_size_mystruct_myunion(
+static inline size_t lttng_get_size_mystruct_myunion(
union lttng_mystruct_myunion *obj)
{
size_t size=0, locsize;
}
-size_t lttng_get_alignment_mystruct_myunion(
+static inline size_t lttng_get_alignment_mystruct_myunion(
union lttng_mystruct_myunion *obj)
{
size_t align=0, localign;
}
-void lttng_write_mystruct_myunion(void **to,
+static inline void lttng_write_mystruct_myunion(
+ void **to_base,
+ size_t *to,
void **from,
size_t *len,
union lttng_mystruct_myunion *obj)
size = lttng_get_size_mystruct_myunion(obj);
if(*len == 0) {
- *to += ltt_align((size_t)(*to), align); /* align output */
+ *to += ltt_align(*to, align); /* align output */
} else {
- *len += ltt_align((size_t)(*to+*len), align); /* C alignment, ok to do a memcpy of it */
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
*len += size;
union lttng_mystruct_myunion myunion;
};
-size_t lttng_get_size_mystruct(
+static inline size_t lttng_get_size_mystruct(
struct lttng_mystruct *obj)
{
size_t size=0, locsize, localign;
}
-size_t lttng_get_alignment_mystruct(
+static inline size_t lttng_get_alignment_mystruct(
struct lttng_mystruct *obj)
{
size_t align=0, localign;
return align;
}
-void lttng_write_mystruct(void **to,
+static inline void lttng_write_mystruct(
+ void **to_base,
+ size_t *to,
void **from,
size_t *len,
struct lttng_mystruct *obj)
// locsize = lttng_get_size_mystruct(obj);
if(*len == 0) {
- *to += ltt_align((size_t)(*to), align); /* align output */
+ *to += ltt_align(*to, align); /* align output */
} else {
- *len += ltt_align((size_t)(*to+*len), align); /* C alignment, ok to do a memcpy of it */
+ *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
}
/* Contains variable sized fields : must explode the structure */
size = sizeof(unsigned int);
- *len += ltt_align((size_t)(*to+*len), size) + size;
+ size += ltt_align(*to+*len, size) + size;
+ *len += size;
size = sizeof(enum lttng_irq_mode);
- *len += ltt_align((size_t)(*to+*len), size) + size;
+ size += ltt_align(*to+*len, size) + size;
+ *len += size;
- lttng_write_mystruct2(to, from, len, &obj->teststr);
+ lttng_write_mystruct2(to_base, to, from, len, &obj->teststr);
- lttng_write_array_mystruct_myarray(to, from, len, obj->myarray);
+ lttng_write_array_mystruct_myarray(to_base, to, from, len, obj->myarray);
/* Variable length field */
- lttng_write_sequence_mystruct_mysequence(to, from, len, &obj->mysequence);
-
- lttng_write_mystruct_myunion(to, from, len, &obj->myunion);
+ lttng_write_sequence_mystruct_mysequence(to_base, to, from, len, &obj->mysequence);
+ //*to = 0; /* Force the compiler to know it's 0 */
+ /* After this previous write, we are sure that *to is 0, and *to_base is
+ * aligned on the architecture size : to rest of alignment will be calculated
+ * statically. */
+
+ lttng_write_mystruct_myunion(to_base, to, from, len, &obj->myunion);
/* Don't forget to flush last write..... */
}
-void main()
+//void main()
+void test()
{
struct lttng_mystruct test;
test.mysequence.len = 20;
size_t align = lttng_get_alignment_mystruct(&test);
void *buf = malloc(align + size);
- void *to = buf;
+ void *to_base = buf; /* the buffer is allocated on arch_size alignment */
+ size_t to = 0;
void *from = &test;
size_t len = 0;
- lttng_write_mystruct(&to, &from, &len, &test);
+ lttng_write_mystruct(&to_base, &to, &from, &len, &test);
/* Final flush */
/* Flush pending memcpy */
if(len != 0) {
- memcpy(to, from, len);
+ memcpy(to_base+to, from, len);
to += len;
from += len;
len = 0;