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