7 #define min(a,b) (((a)<(b))?a:b)
8 #define max(a,b) (((a)>(b))?a:b)
9 #define BUG_ON(a) assert(!(a))
11 /* Calculate the offset needed to align the type */
12 static inline unsigned int ltt_align(size_t align_drift
,
15 size_t alignment
= min(sizeof(void*), size_of_type
);
17 return ((alignment
- align_drift
) & (alignment
-1));
23 enum lttng_tasklet_priority
{
33 struct lttng_mystruct2
{
35 enum lttng_irq_mode mode
;
36 //struct lttng_mystruct teststr1;
40 static inline size_t lttng_get_size_mystruct2(
41 struct lttng_mystruct2
* obj
)
43 size_t size
=0, locsize
;
45 locsize
= sizeof(unsigned int);
46 size
+= ltt_align(size
, locsize
) + locsize
;
48 locsize
= sizeof(enum lttng_irq_mode
);
49 size
+= ltt_align(size
, locsize
) + locsize
;
51 BUG_ON(sizeof(struct lttng_mystruct2
) != size
);
53 return sizeof(struct lttng_mystruct2
);
56 static inline size_t lttng_get_alignment_mystruct2(
57 struct lttng_mystruct2
*obj
)
59 size_t align
=0, localign
;
61 localign
= sizeof(unsigned int);
62 align
= max(align
, localign
);
64 localign
= sizeof(enum lttng_irq_mode
);
65 align
= max(align
, localign
);
70 static inline void lttng_write_mystruct2(
75 struct lttng_mystruct2
*obj
)
77 size_t align
, size
, varalign
;
79 align
= lttng_get_alignment_mystruct2(obj
);
80 size
= lttng_get_size_mystruct2(obj
);
83 *to
+= ltt_align(*to
, align
); /* align output */
85 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
93 #define LTTNG_ARRAY_SIZE_mystruct_myarray 10
94 typedef uint64_t lttng_array_mystruct_myarray
[LTTNG_ARRAY_SIZE_mystruct_myarray
];
96 static inline size_t lttng_get_size_array_mystruct_myarray(
97 lttng_array_mystruct_myarray obj
)
99 size_t size
=0, locsize
;
101 locsize
= sizeof(uint64_t);
102 /* ltt_align == 0 always*/
103 //size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize);
104 BUG_ON(ltt_align(size
, locsize
) != 0);
105 size
+= LTTNG_ARRAY_SIZE_mystruct_myarray
* locsize
;
107 BUG_ON(size
!= LTTNG_ARRAY_SIZE_mystruct_myarray
* sizeof(uint64_t));
112 static inline size_t lttng_get_alignment_array_mystruct_myarray(
113 lttng_array_mystruct_myarray obj
)
115 size_t align
=0, localign
;
117 localign
= sizeof(uint64_t);
118 align
= max(align
, localign
);
124 static inline void lttng_write_array_mystruct_myarray(
129 lttng_array_mystruct_myarray obj
)
133 align
= lttng_get_alignment_array_mystruct_myarray(obj
);
134 size
= lttng_get_size_array_mystruct_myarray(obj
);
137 *to
+= ltt_align(*to
, align
); /* align output */
139 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
146 typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence
;
147 struct lttng_sequence_mystruct_mysequence
{
153 static inline size_t lttng_get_size_sequence_mystruct_mysequence(
154 lttng_sequence_mystruct_mysequence
*obj
)
156 size_t size
=0, locsize
;
158 locsize
= sizeof(unsigned int);
159 size
+= ltt_align(size
, locsize
) + locsize
;
161 locsize
= sizeof(double);
162 size
+= ltt_align(size
, locsize
) + (obj
->len
* locsize
);
167 static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
168 lttng_sequence_mystruct_mysequence
*obj
)
170 size_t align
=0, localign
;
172 localign
= sizeof(unsigned int);
173 align
= max(align
, localign
);
175 localign
= sizeof(double);
176 align
= max(align
, localign
);
182 static inline void lttng_write_sequence_mystruct_mysequence(
187 lttng_sequence_mystruct_mysequence
*obj
)
193 /* Flush pending memcpy */
195 memcpy(*to_base
+*to
, *from
, *len
);
200 align
= lttng_get_alignment_sequence_mystruct_mysequence(obj
);
201 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
204 *to
+= ltt_align(*to
, align
); /* *len = 0 in this function */
207 *to
+= ltt_align(*to
, sizeof(unsigned int));
209 varlen
+= sizeof(unsigned int);
210 memcpy(*to_base
+*to
, varfrom
, varlen
);
214 *to
+= ltt_align(*to
, sizeof(double));
215 varfrom
= obj
->array
;
216 varlen
+= obj
->len
* sizeof(double);
217 memcpy(*to_base
+*to
, varfrom
, varlen
);
221 /* Realign the *to_base on arch size, set *to to 0 */
222 *to
= ltt_align(*to
, sizeof(void *));
223 *to_base
= *to_base
+*to
;
226 /* Put source *from just after the C sequence */
232 union lttng_mystruct_myunion
{
234 unsigned long myulong
;
238 static inline size_t lttng_get_size_mystruct_myunion(
239 union lttng_mystruct_myunion
*obj
)
241 size_t size
=0, locsize
;
243 locsize
= sizeof(double);
244 size
= max(size
, locsize
);
246 locsize
= sizeof(unsigned long);
247 size
= max(size
, locsize
);
249 BUG_ON(size
!= sizeof(union lttng_mystruct_myunion
));
255 static inline size_t lttng_get_alignment_mystruct_myunion(
256 union lttng_mystruct_myunion
*obj
)
258 size_t align
=0, localign
;
260 localign
= sizeof(double);
261 align
= max(align
, localign
);
263 localign
= sizeof(unsigned long);
264 align
= max(align
, localign
);
270 static inline void lttng_write_mystruct_myunion(
275 union lttng_mystruct_myunion
*obj
)
279 align
= lttng_get_alignment_mystruct_myunion(obj
);
280 size
= lttng_get_size_mystruct_myunion(obj
);
283 *to
+= ltt_align(*to
, align
); /* align output */
285 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
292 struct lttng_mystruct
{
294 enum lttng_irq_mode mode
;
295 struct lttng_mystruct2 teststr
;
296 lttng_array_mystruct_myarray myarray
;
297 lttng_sequence_mystruct_mysequence mysequence
;
298 union lttng_mystruct_myunion myunion
;
301 static inline size_t lttng_get_size_mystruct(
302 struct lttng_mystruct
*obj
)
304 size_t size
=0, locsize
, localign
;
306 locsize
= sizeof(unsigned int);
307 size
+= ltt_align(size
, locsize
) + locsize
;
309 locsize
= sizeof(enum lttng_irq_mode
);
310 size
+= ltt_align(size
, locsize
) + locsize
;
312 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
313 locsize
= lttng_get_size_mystruct2(&obj
->teststr
);
314 size
+= ltt_align(size
, localign
) + locsize
;
316 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
317 locsize
= lttng_get_size_array_mystruct_myarray(obj
->myarray
);
318 size
+= ltt_align(size
, localign
) + locsize
;
320 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
321 locsize
= lttng_get_size_sequence_mystruct_mysequence(&obj
->mysequence
);
322 size
+= ltt_align(size
, localign
) + locsize
;
324 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
325 locsize
= lttng_get_size_mystruct_myunion(&obj
->myunion
);
326 size
+= ltt_align(size
, localign
) + locsize
;
332 static inline size_t lttng_get_alignment_mystruct(
333 struct lttng_mystruct
*obj
)
335 size_t align
=0, localign
;
337 localign
= sizeof(unsigned int);
338 align
= max(align
, localign
);
340 localign
= sizeof(enum lttng_irq_mode
);
341 align
= max(align
, localign
);
343 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
344 align
= max(align
, localign
);
346 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
347 align
= max(align
, localign
);
349 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
350 align
= max(align
, localign
);
352 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
353 align
= max(align
, localign
);
358 static inline void lttng_write_mystruct(
363 struct lttng_mystruct
*obj
)
367 align
= lttng_get_alignment_mystruct(obj
);
368 // no need : contains variable size fields.
369 // locsize = lttng_get_size_mystruct(obj);
372 *to
+= ltt_align(*to
, align
); /* align output */
374 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
377 /* Contains variable sized fields : must explode the structure */
379 size
= sizeof(unsigned int);
380 size
+= ltt_align(*to
+*len
, size
) + size
;
383 size
= sizeof(enum lttng_irq_mode
);
384 size
+= ltt_align(*to
+*len
, size
) + size
;
387 lttng_write_mystruct2(to_base
, to
, from
, len
, &obj
->teststr
);
389 lttng_write_array_mystruct_myarray(to_base
, to
, from
, len
, obj
->myarray
);
391 /* Variable length field */
392 lttng_write_sequence_mystruct_mysequence(to_base
, to
, from
, len
, &obj
->mysequence
);
393 /* After this previous write, we are sure that *to is 0, and *to_base is
394 * aligned on the architecture size : to rest of alignment will be calculated
398 lttng_write_mystruct_myunion(to_base
, to
, from
, len
, &obj
->myunion
);
400 /* Don't forget to flush last write..... */
411 struct lttng_mystruct test
;
412 test
.mysequence
.len
= 20;
413 test
.mysequence
.array
= malloc(20);
415 size_t size
= lttng_get_size_mystruct(&test
);
416 size_t align
= lttng_get_alignment_mystruct(&test
);
418 void *buf
= malloc(align
+ size
);
419 void *to_base
= buf
; /* the buffer is allocated on arch_size alignment */
424 lttng_write_mystruct(&to_base
, &to
, &from
, &len
, &test
);
426 /* Flush pending memcpy */
428 memcpy(to_base
+to
, from
, len
);
434 free(test
.mysequence
.array
);