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 /* Calculate the offset needed to align the type */
13 static inline unsigned int ltt_align(size_t align_drift
,
16 size_t alignment
= min(sizeof(void*), size_of_type
);
18 return ((alignment
- align_drift
) & (alignment
-1));
24 enum lttng_tasklet_priority
{
34 struct lttng_mystruct2
{
36 enum lttng_irq_mode mode
;
37 //struct lttng_mystruct teststr1;
41 static inline size_t lttng_get_size_mystruct2(
42 struct lttng_mystruct2
* obj
)
44 size_t size
=0, locsize
;
46 locsize
= sizeof(unsigned int);
47 size
+= ltt_align(size
, locsize
) + locsize
;
49 locsize
= sizeof(enum lttng_irq_mode
);
50 size
+= ltt_align(size
, locsize
) + locsize
;
52 BUG_ON(sizeof(struct lttng_mystruct2
) != size
);
54 return sizeof(struct lttng_mystruct2
);
57 static inline size_t lttng_get_alignment_mystruct2(
58 struct lttng_mystruct2
*obj
)
60 size_t align
=0, localign
;
62 localign
= sizeof(unsigned int);
63 align
= max(align
, localign
);
65 localign
= sizeof(enum lttng_irq_mode
);
66 align
= max(align
, localign
);
71 static inline void lttng_write_mystruct2(
76 struct lttng_mystruct2
*obj
)
80 align
= lttng_get_alignment_mystruct2(obj
);
81 size
= lttng_get_size_mystruct2(obj
);
84 *to
+= ltt_align(*to
, align
); /* align output */
86 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
94 #define LTTNG_ARRAY_SIZE_mystruct_myarray 10
95 typedef uint64_t lttng_array_mystruct_myarray
[LTTNG_ARRAY_SIZE_mystruct_myarray
];
97 static inline size_t lttng_get_size_array_mystruct_myarray(
98 lttng_array_mystruct_myarray obj
)
100 size_t size
=0, locsize
;
102 locsize
= sizeof(uint64_t);
103 /* ltt_align == 0 always*/
104 //size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize);
105 BUG_ON(ltt_align(size
, locsize
) != 0);
106 size
+= LTTNG_ARRAY_SIZE_mystruct_myarray
* locsize
;
108 BUG_ON(size
!= LTTNG_ARRAY_SIZE_mystruct_myarray
* sizeof(uint64_t));
113 static inline size_t lttng_get_alignment_array_mystruct_myarray(
114 lttng_array_mystruct_myarray obj
)
116 size_t align
=0, localign
;
118 localign
= sizeof(uint64_t);
119 align
= max(align
, localign
);
125 static inline void lttng_write_array_mystruct_myarray(
130 lttng_array_mystruct_myarray obj
)
134 align
= lttng_get_alignment_array_mystruct_myarray(obj
);
135 size
= lttng_get_size_array_mystruct_myarray(obj
);
138 *to
+= ltt_align(*to
, align
); /* align output */
140 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
147 typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence
;
148 struct lttng_sequence_mystruct_mysequence
{
154 static inline size_t lttng_get_size_sequence_mystruct_mysequence(
155 lttng_sequence_mystruct_mysequence
*obj
)
157 size_t size
=0, locsize
;
159 locsize
= sizeof(unsigned int);
160 size
+= ltt_align(size
, locsize
) + locsize
;
162 locsize
= sizeof(double);
163 size
+= ltt_align(size
, locsize
) + (obj
->len
* locsize
);
168 static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
169 lttng_sequence_mystruct_mysequence
*obj
)
171 size_t align
=0, localign
;
173 localign
= sizeof(unsigned int);
174 align
= max(align
, localign
);
176 localign
= sizeof(double);
177 align
= max(align
, localign
);
183 static inline void lttng_write_sequence_mystruct_mysequence(
188 lttng_sequence_mystruct_mysequence
*obj
)
194 /* Flush pending memcpy */
196 memcpy(*to_base
+*to
, *from
, *len
);
201 align
= lttng_get_alignment_sequence_mystruct_mysequence(obj
);
202 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
205 *to
+= ltt_align(*to
, align
); /* *len = 0 in this function */
208 *to
+= ltt_align(*to
, sizeof(unsigned int));
210 varlen
+= sizeof(unsigned int);
211 memcpy(*to_base
+*to
, varfrom
, varlen
);
215 *to
+= ltt_align(*to
, sizeof(double));
216 varfrom
= obj
->array
;
217 varlen
+= obj
->len
* sizeof(double);
218 memcpy(*to_base
+*to
, varfrom
, varlen
);
222 /* Realign the *to_base on arch size, set *to to 0 */
223 *to
= ltt_align(*to
, sizeof(void *));
224 *to_base
= *to_base
+*to
;
227 /* Put source *from just after the C sequence */
233 union lttng_mystruct_myunion
{
235 unsigned long myulong
;
239 static inline size_t lttng_get_size_mystruct_myunion(
240 union lttng_mystruct_myunion
*obj
)
242 size_t size
=0, locsize
;
244 locsize
= sizeof(double);
245 size
= max(size
, locsize
);
247 locsize
= sizeof(unsigned long);
248 size
= max(size
, locsize
);
250 BUG_ON(size
!= sizeof(union lttng_mystruct_myunion
));
256 static inline size_t lttng_get_alignment_mystruct_myunion(
257 union lttng_mystruct_myunion
*obj
)
259 size_t align
=0, localign
;
261 localign
= sizeof(double);
262 align
= max(align
, localign
);
264 localign
= sizeof(unsigned long);
265 align
= max(align
, localign
);
271 static inline void lttng_write_mystruct_myunion(
276 union lttng_mystruct_myunion
*obj
)
280 align
= lttng_get_alignment_mystruct_myunion(obj
);
281 size
= lttng_get_size_mystruct_myunion(obj
);
284 *to
+= ltt_align(*to
, align
); /* align output */
286 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
293 struct lttng_mystruct
{
295 enum lttng_irq_mode mode
;
296 struct lttng_mystruct2 teststr
;
297 lttng_array_mystruct_myarray myarray
;
298 lttng_sequence_mystruct_mysequence mysequence
;
299 union lttng_mystruct_myunion myunion
;
302 static inline size_t lttng_get_size_mystruct(
303 struct lttng_mystruct
*obj
)
305 size_t size
=0, locsize
, localign
;
307 locsize
= sizeof(unsigned int);
308 size
+= ltt_align(size
, locsize
) + locsize
;
310 locsize
= sizeof(enum lttng_irq_mode
);
311 size
+= ltt_align(size
, locsize
) + locsize
;
313 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
314 locsize
= lttng_get_size_mystruct2(&obj
->teststr
);
315 size
+= ltt_align(size
, localign
) + locsize
;
317 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
318 locsize
= lttng_get_size_array_mystruct_myarray(obj
->myarray
);
319 size
+= ltt_align(size
, localign
) + locsize
;
321 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
322 locsize
= lttng_get_size_sequence_mystruct_mysequence(&obj
->mysequence
);
323 size
+= ltt_align(size
, localign
) + locsize
;
325 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
326 locsize
= lttng_get_size_mystruct_myunion(&obj
->myunion
);
327 size
+= ltt_align(size
, localign
) + locsize
;
333 static inline size_t lttng_get_alignment_mystruct(
334 struct lttng_mystruct
*obj
)
336 size_t align
=0, localign
;
338 localign
= sizeof(unsigned int);
339 align
= max(align
, localign
);
341 localign
= sizeof(enum lttng_irq_mode
);
342 align
= max(align
, localign
);
344 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
345 align
= max(align
, localign
);
347 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
348 align
= max(align
, localign
);
350 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
351 align
= max(align
, localign
);
353 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
354 align
= max(align
, localign
);
359 static inline void lttng_write_mystruct(
364 struct lttng_mystruct
*obj
)
368 align
= lttng_get_alignment_mystruct(obj
);
369 // no need : contains variable size fields.
370 // locsize = lttng_get_size_mystruct(obj);
373 *to
+= ltt_align(*to
, align
); /* align output */
375 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
378 /* Contains variable sized fields : must explode the structure */
380 size
= sizeof(unsigned int);
381 size
+= ltt_align(*to
+*len
, size
) + size
;
384 size
= sizeof(enum lttng_irq_mode
);
385 size
+= ltt_align(*to
+*len
, size
) + size
;
388 lttng_write_mystruct2(to_base
, to
, from
, len
, &obj
->teststr
);
390 lttng_write_array_mystruct_myarray(to_base
, to
, from
, len
, obj
->myarray
);
392 /* Variable length field */
393 lttng_write_sequence_mystruct_mysequence(to_base
, to
, from
, len
, &obj
->mysequence
);
394 *to
= 0; /* Force the compiler to know it's 0 */
395 /* After this previous write, we are sure that *to is 0, and *to_base is
396 * aligned on the architecture size : to rest of alignment will be calculated
399 lttng_write_mystruct_myunion(to_base
, to
, from
, len
, &obj
->myunion
);
401 /* Don't forget to flush last write..... */
412 struct lttng_mystruct test
;
413 test
.mysequence
.len
= 20;
414 test
.mysequence
.array
= malloc(20);
416 size_t size
= lttng_get_size_mystruct(&test
);
417 size_t align
= lttng_get_alignment_mystruct(&test
);
419 void *buf
= malloc(align
+ size
);
420 void *to_base
= buf
; /* the buffer is allocated on arch_size alignment */
425 lttng_write_mystruct(&to_base
, &to
, &from
, &len
, &test
);
427 /* Flush pending memcpy */
429 memcpy(to_base
+to
, from
, len
);
435 free(test
.mysequence
.array
);