realign after write of a variable size element
[lttv.git] / genevent-new / gentest.c
CommitLineData
6ef4987c 1
2#include <assert.h>
3#include <sys/types.h>
4#include <stdint.h>
5#include <stdlib.h>
6
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))
10
11/* Calculate the offset needed to align the type */
12static inline unsigned int ltt_align(size_t align_drift,
13 size_t size_of_type)
14{
15 size_t alignment = min(sizeof(void*), size_of_type);
16
17 return ((alignment - align_drift) & (alignment-1));
18}
19
20
21/* TEMPLATE */
22
23enum lttng_tasklet_priority {
24 LTTNG_LOW,
25 LTTNG_HIGH,
26};
27
28enum lttng_irq_mode {
29 LTTNG_user,
30 LTTNG_kernel,
31};
32
33struct lttng_mystruct2 {
34 unsigned int irq_id;
35 enum lttng_irq_mode mode;
36 //struct lttng_mystruct teststr1;
37};
38
39
257d03bc 40static inline size_t lttng_get_size_mystruct2(
41 struct lttng_mystruct2 * obj)
6ef4987c 42{
43 size_t size=0, locsize;
44
45 locsize = sizeof(unsigned int);
46 size += ltt_align(size, locsize) + locsize;
47
48 locsize = sizeof(enum lttng_irq_mode);
49 size += ltt_align(size, locsize) + locsize;
50
51 BUG_ON(sizeof(struct lttng_mystruct2) != size);
52
53 return sizeof(struct lttng_mystruct2);
54}
55
257d03bc 56static inline size_t lttng_get_alignment_mystruct2(
6ef4987c 57 struct lttng_mystruct2 *obj)
58{
59 size_t align=0, localign;
60
61 localign = sizeof(unsigned int);
62 align = max(align, localign);
63
64 localign = sizeof(enum lttng_irq_mode);
65 align = max(align, localign);
66
67 return align;
68}
69
1c341713 70static inline void lttng_write_mystruct2(
71 void **to_base,
257d03bc 72 size_t *to,
6ef4987c 73 void **from,
74 size_t *len,
75 struct lttng_mystruct2 *obj)
76{
257d03bc 77 size_t align, size, varalign;
6ef4987c 78
79 align = lttng_get_alignment_mystruct2(obj);
80 size = lttng_get_size_mystruct2(obj);
81
82 if(*len == 0) {
1c341713 83 *to += ltt_align(*to, align); /* align output */
6ef4987c 84 } else {
1c341713 85 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
6ef4987c 86 }
87
88 *len += size;
89}
90
91
92
93#define LTTNG_ARRAY_SIZE_mystruct_myarray 10
94typedef uint64_t lttng_array_mystruct_myarray[LTTNG_ARRAY_SIZE_mystruct_myarray];
95
257d03bc 96static inline size_t lttng_get_size_array_mystruct_myarray(
6ef4987c 97 lttng_array_mystruct_myarray obj)
98{
99 size_t size=0, locsize;
100
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;
106
107 BUG_ON(size != LTTNG_ARRAY_SIZE_mystruct_myarray * sizeof(uint64_t));
108
109 return size;
110}
111
257d03bc 112static inline size_t lttng_get_alignment_array_mystruct_myarray(
6ef4987c 113 lttng_array_mystruct_myarray obj)
114{
115 size_t align=0, localign;
116
117 localign = sizeof(uint64_t);
118 align = max(align, localign);
119
120 return align;
121}
122
123
1c341713 124static inline void lttng_write_array_mystruct_myarray(
125 void **to_base,
257d03bc 126 size_t *to,
6ef4987c 127 void **from,
128 size_t *len,
129 lttng_array_mystruct_myarray obj)
130{
1c341713 131 size_t align, size;
6ef4987c 132
133 align = lttng_get_alignment_array_mystruct_myarray(obj);
134 size = lttng_get_size_array_mystruct_myarray(obj);
135
136 if(*len == 0) {
1c341713 137 *to += ltt_align(*to, align); /* align output */
6ef4987c 138 } else {
1c341713 139 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
6ef4987c 140 }
141
142 *len += size;
143}
144
145
146typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence;
147struct lttng_sequence_mystruct_mysequence {
148 unsigned int len;
149 double *array;
150};
151
152
257d03bc 153static inline size_t lttng_get_size_sequence_mystruct_mysequence(
6ef4987c 154 lttng_sequence_mystruct_mysequence *obj)
155{
156 size_t size=0, locsize;
157
158 locsize = sizeof(unsigned int);
159 size += ltt_align(size, locsize) + locsize;
160
161 locsize = sizeof(double);
162 size += ltt_align(size, locsize) + (obj->len * locsize);
163
164 return size;
165}
166
257d03bc 167static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
6ef4987c 168 lttng_sequence_mystruct_mysequence *obj)
169{
170 size_t align=0, localign;
171
172 localign = sizeof(unsigned int);
173 align = max(align, localign);
174
175 localign = sizeof(double);
176 align = max(align, localign);
177
178 return align;
179}
180
181
1c341713 182static inline void lttng_write_sequence_mystruct_mysequence(
183 void **to_base,
257d03bc 184 size_t *to,
6ef4987c 185 void **from,
186 size_t *len,
187 lttng_sequence_mystruct_mysequence *obj)
188{
257d03bc 189 size_t align;
6ef4987c 190 void *varfrom;
191 size_t varlen=0;
192
193 /* Flush pending memcpy */
194 if(*len != 0) {
1c341713 195 memcpy(*to_base+*to, *from, *len);
6ef4987c 196 *to += *len;
197 *len = 0;
198 }
199
200 align = lttng_get_alignment_sequence_mystruct_mysequence(obj);
201 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
202
203 /* Align output */
1c341713 204 *to += ltt_align(*to, align); /* *len = 0 in this function */
6ef4987c 205
206 /* Copy members */
1c341713 207 *to += ltt_align(*to, sizeof(unsigned int));
6ef4987c 208 varfrom = &obj->len;
209 varlen += sizeof(unsigned int);
1c341713 210 memcpy(*to_base+*to, varfrom, varlen);
211 *to += varlen;
6ef4987c 212 varlen = 0;
213
1c341713 214 *to += ltt_align(*to, sizeof(double));
6ef4987c 215 varfrom = obj->array;
216 varlen += obj->len * sizeof(double);
1c341713 217 memcpy(*to_base+*to, varfrom, varlen);
218 *to += varlen;
6ef4987c 219 varlen = 0;
220
1c341713 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;
224 *to = 0;
225
6ef4987c 226 /* Put source *from just after the C sequence */
227 *from = obj+1;
228}
229
230
231
232union lttng_mystruct_myunion {
233 double myfloat;
234 unsigned long myulong;
235};
236
237
257d03bc 238static inline size_t lttng_get_size_mystruct_myunion(
6ef4987c 239 union lttng_mystruct_myunion *obj)
240{
241 size_t size=0, locsize;
242
243 locsize = sizeof(double);
244 size = max(size, locsize);
245
246 locsize = sizeof(unsigned long);
247 size = max(size, locsize);
248
249 BUG_ON(size != sizeof(union lttng_mystruct_myunion));
250
251 return size;
252}
253
254
257d03bc 255static inline size_t lttng_get_alignment_mystruct_myunion(
6ef4987c 256 union lttng_mystruct_myunion *obj)
257{
258 size_t align=0, localign;
259
260 localign = sizeof(double);
261 align = max(align, localign);
262
263 localign = sizeof(unsigned long);
264 align = max(align, localign);
265
266 return align;
267}
268
269
1c341713 270static inline void lttng_write_mystruct_myunion(
271 void **to_base,
257d03bc 272 size_t *to,
6ef4987c 273 void **from,
274 size_t *len,
275 union lttng_mystruct_myunion *obj)
276{
1c341713 277 size_t align, size;
6ef4987c 278
279 align = lttng_get_alignment_mystruct_myunion(obj);
280 size = lttng_get_size_mystruct_myunion(obj);
281
282 if(*len == 0) {
1c341713 283 *to += ltt_align(*to, align); /* align output */
6ef4987c 284 } else {
1c341713 285 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
6ef4987c 286 }
287
288 *len += size;
289}
290
291
292struct lttng_mystruct {
293 unsigned int irq_id;
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;
299};
300
257d03bc 301static inline size_t lttng_get_size_mystruct(
6ef4987c 302 struct lttng_mystruct *obj)
303{
304 size_t size=0, locsize, localign;
305
306 locsize = sizeof(unsigned int);
307 size += ltt_align(size, locsize) + locsize;
308
309 locsize = sizeof(enum lttng_irq_mode);
310 size += ltt_align(size, locsize) + locsize;
311
312 localign = lttng_get_alignment_mystruct2(&obj->teststr);
313 locsize = lttng_get_size_mystruct2(&obj->teststr);
314 size += ltt_align(size, localign) + locsize;
315
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;
319
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;
323
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;
327
328 return size;
329}
330
331
257d03bc 332static inline size_t lttng_get_alignment_mystruct(
6ef4987c 333 struct lttng_mystruct *obj)
334{
335 size_t align=0, localign;
336
337 localign = sizeof(unsigned int);
338 align = max(align, localign);
339
340 localign = sizeof(enum lttng_irq_mode);
341 align = max(align, localign);
342
343 localign = lttng_get_alignment_mystruct2(&obj->teststr);
344 align = max(align, localign);
345
346 localign = lttng_get_alignment_array_mystruct_myarray(obj->myarray);
347 align = max(align, localign);
348
349 localign = lttng_get_alignment_sequence_mystruct_mysequence(&obj->mysequence);
350 align = max(align, localign);
351
352 localign = lttng_get_alignment_mystruct_myunion(&obj->myunion);
353 align = max(align, localign);
354
355 return align;
356}
357
257d03bc 358static inline void lttng_write_mystruct(
1c341713 359 void **to_base,
257d03bc 360 size_t *to,
6ef4987c 361 void **from,
362 size_t *len,
363 struct lttng_mystruct *obj)
364{
1c341713 365 size_t align, size;
6ef4987c 366
367 align = lttng_get_alignment_mystruct(obj);
368 // no need : contains variable size fields.
369 // locsize = lttng_get_size_mystruct(obj);
370
371 if(*len == 0) {
257d03bc 372 *to += ltt_align(*to, align); /* align output */
6ef4987c 373 } else {
257d03bc 374 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
6ef4987c 375 }
376
377 /* Contains variable sized fields : must explode the structure */
378
1c341713 379 size = sizeof(unsigned int);
380 size += ltt_align(*to+*len, size) + size;
381 *len += size;
6ef4987c 382
1c341713 383 size = sizeof(enum lttng_irq_mode);
384 size += ltt_align(*to+*len, size) + size;
385 *len += size;
6ef4987c 386
1c341713 387 lttng_write_mystruct2(to_base, to, from, len, &obj->teststr);
6ef4987c 388
1c341713 389 lttng_write_array_mystruct_myarray(to_base, to, from, len, obj->myarray);
6ef4987c 390
391 /* Variable length field */
1c341713 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
395 * statically. */
396
397
398 lttng_write_mystruct_myunion(to_base, to, from, len, &obj->myunion);
6ef4987c 399
400 /* Don't forget to flush last write..... */
401}
402
403
404
405
406
407
257d03bc 408//void main()
409void test()
6ef4987c 410{
411 struct lttng_mystruct test;
412 test.mysequence.len = 20;
413 test.mysequence.array = malloc(20);
414
415 size_t size = lttng_get_size_mystruct(&test);
416 size_t align = lttng_get_alignment_mystruct(&test);
417
418 void *buf = malloc(align + size);
1c341713 419 void *to_base = buf; /* the buffer is allocated on arch_size alignment */
257d03bc 420 size_t to = 0;
6ef4987c 421 void *from = &test;
422 size_t len = 0;
423
1c341713 424 lttng_write_mystruct(&to_base, &to, &from, &len, &test);
6ef4987c 425 /* Final flush */
426 /* Flush pending memcpy */
427 if(len != 0) {
1c341713 428 memcpy(to_base+to, from, len);
6ef4987c 429 to += len;
430 from += len;
431 len = 0;
432 }
433
434 free(test.mysequence.array);
435 free(buf);
436}
This page took 0.039287 seconds and 4 git commands to generate.