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