8 #define min(a,b) (((a)<(b))?a:b)
9 #define max(a,b) (((a)>(b))?a:b)
10 #define BUG_ON(a) assert(!(a))
12 #define force_inline inline __attribute__((always_inline))
14 /* Calculate the offset needed to align the type */
15 static force_inline
unsigned int ltt_align(size_t align_drift
,
18 size_t alignment
= min(sizeof(void*), size_of_type
);
20 return ((alignment
- align_drift
) & (alignment
-1));
26 enum lttng_tasklet_priority
{
36 struct lttng_mystruct2
{
38 enum lttng_irq_mode mode
;
39 //struct lttng_mystruct teststr1;
43 static force_inline
size_t lttng_get_size_mystruct2(
44 struct lttng_mystruct2
* obj
)
46 size_t size
=0, locsize
;
48 locsize
= sizeof(unsigned int);
49 size
+= ltt_align(size
, locsize
) + locsize
;
51 locsize
= sizeof(enum lttng_irq_mode
);
52 size
+= ltt_align(size
, locsize
) + locsize
;
54 BUG_ON(sizeof(struct lttng_mystruct2
) != size
);
56 return sizeof(struct lttng_mystruct2
);
59 static force_inline
size_t lttng_get_alignment_mystruct2(
60 struct lttng_mystruct2
*obj
)
62 size_t align
=0, localign
;
64 localign
= sizeof(unsigned int);
65 align
= max(align
, localign
);
67 localign
= sizeof(enum lttng_irq_mode
);
68 align
= max(align
, localign
);
73 static force_inline
void lttng_write_mystruct2(
78 struct lttng_mystruct2
*obj
)
82 align
= lttng_get_alignment_mystruct2(obj
);
83 size
= lttng_get_size_mystruct2(obj
);
86 *to
+= ltt_align(*to
, align
); /* align output */
88 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
96 #define LTTNG_ARRAY_SIZE_mystruct_myarray 10
97 typedef uint64_t lttng_array_mystruct_myarray
[LTTNG_ARRAY_SIZE_mystruct_myarray
];
99 static force_inline
size_t lttng_get_size_array_mystruct_myarray(
100 lttng_array_mystruct_myarray obj
)
102 size_t size
=0, locsize
;
104 locsize
= sizeof(uint64_t);
105 /* ltt_align == 0 always*/
106 //size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize);
107 BUG_ON(ltt_align(size
, locsize
) != 0);
108 size
+= LTTNG_ARRAY_SIZE_mystruct_myarray
* locsize
;
110 BUG_ON(size
!= LTTNG_ARRAY_SIZE_mystruct_myarray
* sizeof(uint64_t));
115 static force_inline
size_t lttng_get_alignment_array_mystruct_myarray(
116 lttng_array_mystruct_myarray obj
)
118 size_t align
=0, localign
;
120 localign
= sizeof(uint64_t);
121 align
= max(align
, localign
);
127 static force_inline
void lttng_write_array_mystruct_myarray(
132 lttng_array_mystruct_myarray obj
)
136 align
= lttng_get_alignment_array_mystruct_myarray(obj
);
137 size
= lttng_get_size_array_mystruct_myarray(obj
);
140 *to
+= ltt_align(*to
, align
); /* align output */
142 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
149 typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence
;
150 struct lttng_sequence_mystruct_mysequence
{
156 static force_inline
size_t lttng_get_size_sequence_mystruct_mysequence(
157 lttng_sequence_mystruct_mysequence
*obj
)
159 size_t size
=0, locsize
;
161 locsize
= sizeof(unsigned int);
162 size
+= ltt_align(size
, locsize
) + locsize
;
164 locsize
= sizeof(double);
165 size
+= ltt_align(size
, locsize
) + (obj
->len
* locsize
);
170 static force_inline
size_t lttng_get_alignment_sequence_mystruct_mysequence(
171 lttng_sequence_mystruct_mysequence
*obj
)
173 size_t align
=0, localign
;
175 localign
= sizeof(unsigned int);
176 align
= max(align
, localign
);
178 localign
= sizeof(double);
179 align
= max(align
, localign
);
185 static force_inline
void lttng_write_sequence_mystruct_mysequence(
190 lttng_sequence_mystruct_mysequence
*obj
)
196 /* Flush pending memcpy */
198 memcpy(*to_base
+*to
, *from
, *len
);
203 align
= lttng_get_alignment_sequence_mystruct_mysequence(obj
);
204 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
207 *to
+= ltt_align(*to
, align
); /* *len = 0 in this function */
210 *to
+= ltt_align(*to
, sizeof(unsigned int));
212 varlen
+= sizeof(unsigned int);
213 memcpy(*to_base
+*to
, varfrom
, varlen
);
217 *to
+= ltt_align(*to
, sizeof(double));
218 varfrom
= obj
->array
;
219 varlen
+= obj
->len
* sizeof(double);
220 memcpy(*to_base
+*to
, varfrom
, varlen
);
224 /* Realign the *to_base on arch size, set *to to 0 */
225 *to
= ltt_align(*to
, sizeof(void *));
226 *to_base
= *to_base
+*to
;
229 /* Put source *from just after the C sequence */
235 union lttng_mystruct_myunion
{
237 unsigned long myulong
;
241 static force_inline
size_t lttng_get_size_mystruct_myunion(
242 union lttng_mystruct_myunion
*obj
)
244 size_t size
=0, locsize
;
246 locsize
= sizeof(double);
247 size
= max(size
, locsize
);
249 locsize
= sizeof(unsigned long);
250 size
= max(size
, locsize
);
252 BUG_ON(size
!= sizeof(union lttng_mystruct_myunion
));
258 static force_inline
size_t lttng_get_alignment_mystruct_myunion(
259 union lttng_mystruct_myunion
*obj
)
261 size_t align
=0, localign
;
263 localign
= sizeof(double);
264 align
= max(align
, localign
);
266 localign
= sizeof(unsigned long);
267 align
= max(align
, localign
);
273 static force_inline
void lttng_write_mystruct_myunion(
278 union lttng_mystruct_myunion
*obj
)
282 align
= lttng_get_alignment_mystruct_myunion(obj
);
283 size
= lttng_get_size_mystruct_myunion(obj
);
286 *to
+= ltt_align(*to
, align
); /* align output */
288 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
295 struct lttng_mystruct
{
297 enum lttng_irq_mode mode
;
298 struct lttng_mystruct2 teststr
;
299 lttng_array_mystruct_myarray myarray
;
300 lttng_sequence_mystruct_mysequence mysequence
;
301 union lttng_mystruct_myunion myunion
;
304 static force_inline
size_t lttng_get_size_mystruct(
305 struct lttng_mystruct
*obj
)
307 size_t size
=0, locsize
, localign
;
309 locsize
= sizeof(unsigned int);
310 size
+= ltt_align(size
, locsize
) + locsize
;
312 locsize
= sizeof(enum lttng_irq_mode
);
313 size
+= ltt_align(size
, locsize
) + locsize
;
315 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
316 locsize
= lttng_get_size_mystruct2(&obj
->teststr
);
317 size
+= ltt_align(size
, localign
) + locsize
;
319 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
320 locsize
= lttng_get_size_array_mystruct_myarray(obj
->myarray
);
321 size
+= ltt_align(size
, localign
) + locsize
;
323 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
324 locsize
= lttng_get_size_sequence_mystruct_mysequence(&obj
->mysequence
);
325 size
+= ltt_align(size
, localign
) + locsize
;
327 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
328 locsize
= lttng_get_size_mystruct_myunion(&obj
->myunion
);
329 size
+= ltt_align(size
, localign
) + locsize
;
335 static force_inline
size_t lttng_get_alignment_mystruct(
336 struct lttng_mystruct
*obj
)
338 size_t align
=0, localign
;
340 localign
= sizeof(unsigned int);
341 align
= max(align
, localign
);
343 localign
= sizeof(enum lttng_irq_mode
);
344 align
= max(align
, localign
);
346 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
347 align
= max(align
, localign
);
349 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
350 align
= max(align
, localign
);
352 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
353 align
= max(align
, localign
);
355 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
356 align
= max(align
, localign
);
361 static force_inline
void lttng_write_mystruct(
366 struct lttng_mystruct
*obj
)
370 align
= lttng_get_alignment_mystruct(obj
);
371 // no need : contains variable size fields.
372 // locsize = lttng_get_size_mystruct(obj);
375 *to
+= ltt_align(*to
, align
); /* align output */
377 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
380 /* Contains variable sized fields : must explode the structure */
382 size
= sizeof(unsigned int);
383 size
+= ltt_align(*to
+*len
, size
) + size
;
386 size
= sizeof(enum lttng_irq_mode
);
387 size
+= ltt_align(*to
+*len
, size
) + size
;
390 lttng_write_mystruct2(to_base
, to
, from
, len
, &obj
->teststr
);
392 lttng_write_array_mystruct_myarray(to_base
, to
, from
, len
, obj
->myarray
);
394 /* Variable length field */
395 lttng_write_sequence_mystruct_mysequence(to_base
, to
, from
, len
, &obj
->mysequence
);
396 *to
= 0; /* Force the compiler to know it's 0 */
397 /* After this previous write, we are sure that *to is 0, and *to_base is
398 * aligned on the architecture size : to rest of alignment will be calculated
401 lttng_write_mystruct_myunion(to_base
, to
, from
, len
, &obj
->myunion
);
403 /* Don't forget to flush last write..... */
414 struct lttng_mystruct test
;
415 test
.mysequence
.len
= 20;
416 test
.mysequence
.array
= malloc(20);
418 size_t size
= lttng_get_size_mystruct(&test
);
419 size_t align
= lttng_get_alignment_mystruct(&test
);
421 void *buf
= malloc(align
+ size
);
422 void *to_base
= buf
; /* the buffer is allocated on arch_size alignment */
427 lttng_write_mystruct(&to_base
, &to
, &from
, &len
, &test
);
429 /* Flush pending memcpy */
431 memcpy(to_base
+to
, from
, len
);
437 free(test
.mysequence
.array
);