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
);
64 static inline size_t lttng_get_alignment_mystruct2(
65 struct lttng_mystruct2
*obj
)
67 size_t align
=0, localign
;
69 localign
= sizeof(unsigned int);
70 align
= max(align
, localign
);
72 localign
= sizeof(enum lttng_irq_mode
);
73 align
= max(align
, localign
);
78 static inline void lttng_write_mystruct2(
83 struct lttng_mystruct2
*obj
)
87 align
= lttng_get_alignment_mystruct2(obj
);
88 size
= lttng_get_size_mystruct2(obj
);
91 *to
+= ltt_align(*to
, align
); /* align output */
93 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
101 #define LTTNG_ARRAY_SIZE_mystruct_myarray 10
102 typedef uint64_t lttng_array_mystruct_myarray
[LTTNG_ARRAY_SIZE_mystruct_myarray
];
104 static inline size_t lttng_get_size_array_mystruct_myarray(
105 lttng_array_mystruct_myarray obj
)
107 size_t size
=0, locsize
;
109 locsize
= sizeof(uint64_t);
110 /* ltt_align == 0 always*/
111 //size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize);
112 BUG_ON(ltt_align(size
, locsize
) != 0);
113 size
+= LTTNG_ARRAY_SIZE_mystruct_myarray
* locsize
;
115 BUG_ON(size
!= LTTNG_ARRAY_SIZE_mystruct_myarray
* sizeof(uint64_t));
120 static inline size_t lttng_get_alignment_array_mystruct_myarray(
121 lttng_array_mystruct_myarray obj
)
123 size_t align
=0, localign
;
125 localign
= sizeof(uint64_t);
126 align
= max(align
, localign
);
132 static inline void lttng_write_array_mystruct_myarray(
137 lttng_array_mystruct_myarray obj
)
141 align
= lttng_get_alignment_array_mystruct_myarray(obj
);
142 size
= lttng_get_size_array_mystruct_myarray(obj
);
145 *to
+= ltt_align(*to
, align
); /* align output */
147 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
154 typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence
;
155 struct lttng_sequence_mystruct_mysequence
{
161 static inline size_t lttng_get_size_sequence_mystruct_mysequence(
162 lttng_sequence_mystruct_mysequence
*obj
)
164 size_t size
=0, locsize
;
166 locsize
= sizeof(unsigned int);
167 size
+= ltt_align(size
, locsize
) + locsize
;
169 locsize
= sizeof(double);
170 size
+= ltt_align(size
, locsize
) + (obj
->len
* locsize
);
172 /* Realign on arch size */
173 locsize
= sizeof(void *);
174 size
+= ltt_align(size
, locsize
);
179 static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
180 lttng_sequence_mystruct_mysequence
*obj
)
182 size_t align
=0, localign
;
184 localign
= sizeof(unsigned int);
185 align
= max(align
, localign
);
187 localign
= sizeof(double);
188 align
= max(align
, localign
);
194 static inline void lttng_write_sequence_mystruct_mysequence(
199 lttng_sequence_mystruct_mysequence
*obj
)
205 /* Flush pending memcpy */
207 memcpy(*to_base
+*to
, *from
, *len
);
212 align
= lttng_get_alignment_sequence_mystruct_mysequence(obj
);
213 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
216 *to
+= ltt_align(*to
, align
); /* *len = 0 in this function */
219 *to
+= ltt_align(*to
, sizeof(unsigned int));
221 varlen
+= sizeof(unsigned int);
222 memcpy(*to_base
+*to
, varfrom
, varlen
);
226 *to
+= ltt_align(*to
, sizeof(double));
227 varfrom
= obj
->array
;
228 varlen
+= obj
->len
* sizeof(double);
229 memcpy(*to_base
+*to
, varfrom
, varlen
);
233 /* Realign the *to_base on arch size, set *to to 0 */
234 *to
= ltt_align(*to
, sizeof(void *));
235 *to_base
= *to_base
+*to
;
238 /* Put source *from just after the C sequence */
244 union lttng_mystruct_myunion
{
246 unsigned long myulong
;
250 static inline size_t lttng_get_size_mystruct_myunion(
251 union lttng_mystruct_myunion
*obj
)
253 size_t size
=0, locsize
;
255 locsize
= sizeof(double);
256 size
= max(size
, locsize
);
258 locsize
= sizeof(unsigned long);
259 size
= max(size
, locsize
);
261 BUG_ON(size
!= sizeof(union lttng_mystruct_myunion
));
267 static inline size_t lttng_get_alignment_mystruct_myunion(
268 union lttng_mystruct_myunion
*obj
)
270 size_t align
=0, localign
;
272 localign
= sizeof(double);
273 align
= max(align
, localign
);
275 localign
= sizeof(unsigned long);
276 align
= max(align
, localign
);
282 static inline void lttng_write_mystruct_myunion(
287 union lttng_mystruct_myunion
*obj
)
291 align
= lttng_get_alignment_mystruct_myunion(obj
);
292 size
= lttng_get_size_mystruct_myunion(obj
);
295 *to
+= ltt_align(*to
, align
); /* align output */
297 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
304 struct lttng_mystruct
{
306 enum lttng_irq_mode mode
;
307 struct lttng_mystruct2 teststr
;
308 lttng_array_mystruct_myarray myarray
;
309 lttng_sequence_mystruct_mysequence mysequence
;
310 union lttng_mystruct_myunion myunion
;
313 static inline size_t lttng_get_size_mystruct(
314 struct lttng_mystruct
*obj
)
316 size_t size
=0, locsize
, localign
;
318 locsize
= sizeof(unsigned int);
319 size
+= ltt_align(size
, locsize
) + locsize
;
321 locsize
= sizeof(enum lttng_irq_mode
);
322 size
+= ltt_align(size
, locsize
) + locsize
;
324 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
325 locsize
= lttng_get_size_mystruct2(&obj
->teststr
);
326 size
+= ltt_align(size
, localign
) + locsize
;
328 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
329 locsize
= lttng_get_size_array_mystruct_myarray(obj
->myarray
);
330 size
+= ltt_align(size
, localign
) + locsize
;
332 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
333 locsize
= lttng_get_size_sequence_mystruct_mysequence(&obj
->mysequence
);
334 size
+= ltt_align(size
, localign
) + locsize
;
336 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
337 locsize
= lttng_get_size_mystruct_myunion(&obj
->myunion
);
338 size
+= ltt_align(size
, localign
) + locsize
;
344 static inline size_t lttng_get_alignment_mystruct(
345 struct lttng_mystruct
*obj
)
347 size_t align
=0, localign
;
349 localign
= sizeof(unsigned int);
350 align
= max(align
, localign
);
352 localign
= sizeof(enum lttng_irq_mode
);
353 align
= max(align
, localign
);
355 localign
= lttng_get_alignment_mystruct2(&obj
->teststr
);
356 align
= max(align
, localign
);
358 localign
= lttng_get_alignment_array_mystruct_myarray(obj
->myarray
);
359 align
= max(align
, localign
);
361 localign
= lttng_get_alignment_sequence_mystruct_mysequence(&obj
->mysequence
);
362 align
= max(align
, localign
);
364 localign
= lttng_get_alignment_mystruct_myunion(&obj
->myunion
);
365 align
= max(align
, localign
);
370 static inline void lttng_write_mystruct(
375 struct lttng_mystruct
*obj
)
379 align
= lttng_get_alignment_mystruct(obj
);
380 // no need : contains variable size fields.
381 // locsize = lttng_get_size_mystruct(obj);
384 *to
+= ltt_align(*to
, align
); /* align output */
386 *len
+= ltt_align(*to
+*len
, align
); /* C alignment, ok to do a memcpy of it */
389 /* Contains variable sized fields : must explode the structure */
391 size
= sizeof(unsigned int);
392 size
+= ltt_align(*to
+*len
, size
) + size
;
395 size
= sizeof(enum lttng_irq_mode
);
396 size
+= ltt_align(*to
+*len
, size
) + size
;
399 lttng_write_mystruct2(to_base
, to
, from
, len
, &obj
->teststr
);
401 lttng_write_array_mystruct_myarray(to_base
, to
, from
, len
, obj
->myarray
);
403 /* Variable length field */
404 lttng_write_sequence_mystruct_mysequence(to_base
, to
, from
, len
, &obj
->mysequence
);
405 //*to = 0; /* Force the compiler to know it's 0 */
406 /* After this previous write, we are sure that *to is 0, and *to_base is
407 * aligned on the architecture size : to rest of alignment will be calculated
410 lttng_write_mystruct_myunion(to_base
, to
, from
, len
, &obj
->myunion
);
412 /* Don't forget to flush last write..... */
423 struct lttng_mystruct test
;
424 test
.mysequence
.len
= 20;
425 test
.mysequence
.array
= malloc(20);
427 size_t size
= lttng_get_size_mystruct(&test
);
428 size_t align
= lttng_get_alignment_mystruct(&test
);
430 void *buf
= malloc(align
+ size
);
431 void *to_base
= buf
; /* the buffer is allocated on arch_size alignment */
436 lttng_write_mystruct(&to_base
, &to
, &from
, &len
, &test
);
438 /* Flush pending memcpy */
440 memcpy(to_base
+to
, from
, len
);
446 free(test
.mysequence
.array
);