10 #include <linux/compiler.h>
12 #define min(a,b) (((a)<(b))?a:b)
13 #define max(a,b) (((a)>(b))?a:b)
14 #define BUG_ON(a) assert(!(a))
16 // Useful outside __KERNEL__. Not used here because inline is already redefined.
17 #define force_inline inline __attribute__((always_inline))
19 /* Calculate the offset needed to align the type */
20 static inline unsigned int ltt_align(size_t align_drift
,
23 size_t alignment
= min(sizeof(void*), size_of_type
);
25 return ((alignment
- align_drift
) & (alignment
-1));
31 enum lttng_tasklet_priority
{
41 struct lttng_mystruct2
{
43 enum lttng_irq_mode mode
;
44 //struct lttng_mystruct teststr1;
48 static inline size_t lttng_get_size_mystruct2(
49 struct lttng_mystruct2
* obj
)
51 size_t size
=0, locsize
;
53 locsize
= sizeof(unsigned int);
54 size
+= ltt_align(size
, locsize
) + locsize
;
56 locsize
= sizeof(enum lttng_irq_mode
);
57 size
+= ltt_align(size
, locsize
) + locsize
;
59 BUG_ON(sizeof(struct lttng_mystruct2
) != size
);
61 return sizeof(struct lttng_mystruct2
);
65 static inline size_t lttng_get_alignment_mystruct2(
66 struct lttng_mystruct2
*obj
)
68 size_t align
=0, localign
;
70 localign
= sizeof(unsigned int);
71 align
= max(align
, localign
);
73 localign
= sizeof(enum lttng_irq_mode
);
74 align
= max(align
, localign
);
79 static inline void lttng_write_mystruct2(
85 struct lttng_mystruct2
*obj
)
89 align
= lttng_get_alignment_mystruct2(obj
);
90 //size = lttng_get_size_mystruct2(obj);
91 size
= sizeof(struct lttng_mystruct2
);
94 *to
+= ltt_align(*to
, align
); /* align output */
96 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
104 #define LTTNG_ARRAY_SIZE_mystruct_myarray 10
105 typedef uint64_t lttng_array_mystruct_myarray
[LTTNG_ARRAY_SIZE_mystruct_myarray
];
108 static inline size_t lttng_get_size_array_mystruct_myarray(
109 lttng_array_mystruct_myarray obj
)
111 size_t size
=0, locsize
;
113 locsize
= sizeof(uint64_t);
114 /* ltt_align == 0 always*/
115 //size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize);
116 BUG_ON(ltt_align(size
, locsize
) != 0);
117 size
+= LTTNG_ARRAY_SIZE_mystruct_myarray
* locsize
;
119 BUG_ON(sizeof(lttng_array_mystruct_myarray
) != size
);
121 return sizeof(lttng_array_mystruct_myarray
);
125 static inline size_t lttng_get_alignment_array_mystruct_myarray(
126 lttng_array_mystruct_myarray obj
)
128 size_t align
=0, localign
;
130 localign
= sizeof(uint64_t);
131 align
= max(align
, localign
);
137 static inline void lttng_write_array_mystruct_myarray(
143 lttng_array_mystruct_myarray obj
)
147 align
= lttng_get_alignment_array_mystruct_myarray(obj
);
148 //size = lttng_get_size_array_mystruct_myarray(obj);
149 size
= sizeof(lttng_array_mystruct_myarray
);
152 *to
+= ltt_align(*to
, align
); /* align output */
154 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
159 /* For varlen child : let the child align itself. */
160 for(unsigned int i
=0; i
<LTTNG_ARRAY_SIZE_mystruct_myarray
; i
++) {
161 lttng_write_child(buffer
, to_base
, to
, from
, len
, obj
[i
]);
168 typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence
;
169 struct lttng_sequence_mystruct_mysequence
{
175 static inline size_t lttng_get_size_sequence_mystruct_mysequence(
176 lttng_sequence_mystruct_mysequence
*obj
)
178 size_t size
=0, locsize
;
180 locsize
= sizeof(unsigned int);
181 size
+= ltt_align(size
, locsize
) + locsize
;
183 locsize
= sizeof(double);
184 size
+= ltt_align(size
, locsize
) + (obj
->len
* locsize
);
186 /* Realign on arch size */
187 locsize
= sizeof(void *);
188 size
+= ltt_align(size
, locsize
);
194 static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
195 lttng_sequence_mystruct_mysequence
*obj
)
197 size_t align
=0, localign
;
199 localign
= sizeof(unsigned int);
200 align
= max(align
, localign
);
202 localign
= sizeof(double);
203 align
= max(align
, localign
);
209 static inline void lttng_write_sequence_mystruct_mysequence(
215 lttng_sequence_mystruct_mysequence
*obj
)
220 /* Flush pending memcpy */
223 memcpy(buffer
+*to_base
+*to
, *from
, *len
);
228 align
= lttng_get_alignment_sequence_mystruct_mysequence(obj
);
229 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
232 *to
+= ltt_align(*to
, align
); /* *len = 0 in this function */
235 size
= sizeof(unsigned int);
236 *to
+= ltt_align(*to
, size
);
238 memcpy(buffer
+*to_base
+*to
, &obj
->len
, size
);
241 size
= sizeof(double);
242 *to
+= ltt_align(*to
, size
);
243 size
= obj
->len
* sizeof(double);
245 memcpy(buffer
+*to_base
+*to
, obj
->array
, size
);
248 /* If varlen child : let child align itself */
249 for(unsigned int i
=0; i
<obj
->len
; i
++) {
250 lttng_write_child(buffer
, to_base
, to
, from
, len
, obj
->array
[i
]);
255 /* Realign the *to_base on arch size, set *to to 0 */
256 *to
= ltt_align(*to
, sizeof(void *));
257 *to_base
= *to_base
+*to
;
260 /* Put source *from just after the C sequence */
266 union lttng_mystruct_myunion
{
268 unsigned long myulong
;
272 static inline size_t lttng_get_size_mystruct_myunion(
273 union lttng_mystruct_myunion
*obj
)
275 size_t size
=0, locsize
;
277 locsize
= sizeof(double);
278 size
= max(size
, locsize
);
280 locsize
= sizeof(unsigned long);
281 size
= max(size
, locsize
);
283 BUG_ON(size
!= sizeof(union lttng_mystruct_myunion
));
285 return sizeof(union lttng_mystruct_myunion
);
289 static inline size_t lttng_get_alignment_mystruct_myunion(
290 union lttng_mystruct_myunion
*obj
)
292 size_t align
=0, localign
;
294 localign
= sizeof(double);
295 align
= max(align
, localign
);
297 localign
= sizeof(unsigned long);
298 align
= max(align
, localign
);
304 static inline void lttng_write_mystruct_myunion(
310 union lttng_mystruct_myunion
*obj
)
314 align
= lttng_get_alignment_mystruct_myunion(obj
);
315 //size = lttng_get_size_mystruct_myunion(obj);
316 size
= sizeof(union lttng_mystruct_myunion
);
319 *to
+= ltt_align(*to
, align
); /* align output */
321 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
326 /* Assert : no varlen child. */
330 struct lttng_mystruct
{
332 enum lttng_irq_mode mode
;
333 struct lttng_mystruct2 teststr
;
334 lttng_array_mystruct_myarray myarray
;
335 lttng_sequence_mystruct_mysequence mysequence
;
336 union lttng_mystruct_myunion myunion
;
340 static inline size_t lttng_get_size_mystruct(
341 struct lttng_mystruct
*obj
)
343 size_t size
=0, locsize
, localign
;
345 locsize
= sizeof(unsigned int);
346 size
+= ltt_align(size
, locsize
) + locsize
;
348 locsize
= sizeof(enum lttng_irq_mode
);
349 size
+= ltt_align(size
, locsize
) + locsize
;
351 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
352 locsize
= lttng_get_size_mystruct2(&obj
->teststr
);
353 size
+= ltt_align(size
, localign
) + locsize
;
355 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
356 locsize
= lttng_get_size_array_mystruct_myarray(obj
->myarray
);
357 size
+= ltt_align(size
, localign
) + locsize
;
359 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
360 locsize
= lttng_get_size_sequence_mystruct_mysequence(&obj
->mysequence
);
361 size
+= ltt_align(size
, localign
) + locsize
;
363 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
364 locsize
= lttng_get_size_mystruct_myunion(&obj
->myunion
);
365 size
+= ltt_align(size
, localign
) + locsize
;
371 static inline size_t lttng_get_alignment_mystruct(
372 struct lttng_mystruct
*obj
)
374 size_t align
=0, localign
;
376 localign
= sizeof(unsigned int);
377 align
= max(align
, localign
);
379 localign
= sizeof(enum lttng_irq_mode
);
380 align
= max(align
, localign
);
382 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
383 align
= max(align
, localign
);
385 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
386 align
= max(align
, localign
);
388 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
389 align
= max(align
, localign
);
391 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
392 align
= max(align
, localign
);
397 static inline void lttng_write_mystruct(
403 struct lttng_mystruct
*obj
)
407 align
= lttng_get_alignment_mystruct(obj
);
408 // no need : contains variable size fields.
409 // locsize = lttng_get_size_mystruct(obj);
412 *to
+= ltt_align(*to
, align
); /* align output */
414 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
417 /* Contains variable sized fields : must explode the structure */
419 size
= sizeof(unsigned int);
420 size
+= ltt_align(*to
+*len
, size
) + size
;
423 size
= sizeof(enum lttng_irq_mode
);
424 size
+= ltt_align(*to
+*len
, size
) + size
;
427 lttng_write_mystruct2(buffer
, to_base
, to
, from
, len
, &obj
->teststr
);
429 lttng_write_array_mystruct_myarray(buffer
, to_base
, to
, from
, len
, obj
->myarray
);
431 /* Variable length field */
432 lttng_write_sequence_mystruct_mysequence(buffer
, to_base
, to
, from
, len
, &obj
->mysequence
);
433 /* After this previous write, we are sure that *to is 0, *len is 0 and
434 * *to_base is aligned on the architecture size : to rest of alignment will
435 * be calculated statically. */
437 lttng_write_mystruct_myunion(buffer
, to_base
, to
, from
, len
, &obj
->myunion
);
439 /* Don't forget to flush last write..... */
450 struct lttng_mystruct test
;
451 test
.mysequence
.len
= 20;
452 test
.mysequence
.array
= malloc(20);
454 //size_t size = lttng_get_size_mystruct(&test);
455 //size_t align = lttng_get_alignment_mystruct(&test);
457 size_t to_base
= 0; /* the buffer is allocated on arch_size alignment */
463 lttng_write_mystruct(NULL
, &to_base
, &to
, &from
, &len
, &test
);
464 /* Size = to_base + to + len */
466 void *buffer
= malloc(to_base
+ to
+ len
);
467 to_base
= 0; /* the buffer is allocated on arch_size alignment */
472 lttng_write_mystruct(buffer
, &to_base
, &to
, &from
, &len
, &test
);
474 /* Flush pending memcpy */
476 // Assert buffer != NULL */
477 memcpy(buffer
+to_base
+to
, from
, len
);
483 free(test
.mysequence
.array
);