67556797628c5f91476c439420bbd2016e480e27
[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 outside __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 #if 0
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 #endif //0
64
65 static inline size_t lttng_get_alignment_mystruct2(
66 struct lttng_mystruct2 *obj)
67 {
68 size_t align=0, localign;
69
70 localign = sizeof(unsigned int);
71 align = max(align, localign);
72
73 localign = sizeof(enum lttng_irq_mode);
74 align = max(align, localign);
75
76 return align;
77 }
78
79 static inline void lttng_write_mystruct2(
80 void *buffer,
81 size_t *to_base,
82 size_t *to,
83 void **from,
84 size_t *len,
85 struct lttng_mystruct2 *obj)
86 {
87 size_t align, size;
88
89 align = lttng_get_alignment_mystruct2(obj);
90 //size = lttng_get_size_mystruct2(obj);
91 size = sizeof(struct lttng_mystruct2);
92
93 if(*len == 0) {
94 *to += ltt_align(*to, align); /* align output */
95 } else {
96 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
97 }
98
99 *len += size;
100 }
101
102
103
104 #define LTTNG_ARRAY_SIZE_mystruct_myarray 10
105 typedef uint64_t lttng_array_mystruct_myarray[LTTNG_ARRAY_SIZE_mystruct_myarray];
106
107 #if 0
108 static inline size_t lttng_get_size_array_mystruct_myarray(
109 lttng_array_mystruct_myarray obj)
110 {
111 size_t size=0, locsize;
112
113 locsize = sizeof(uint64_t);
114 /* ltt_align == 0 always*/
115 //size += ltt_align(size, locsize) + (LTTNG_ARRAY_SIZE_mystruct_myarray * locsize);
116 BUG_ON(ltt_align(size, locsize) != 0);
117 size += LTTNG_ARRAY_SIZE_mystruct_myarray * locsize;
118
119 BUG_ON(sizeof(lttng_array_mystruct_myarray) != size);
120
121 return sizeof(lttng_array_mystruct_myarray);
122 }
123 #endif //0
124
125 static inline size_t lttng_get_alignment_array_mystruct_myarray(
126 lttng_array_mystruct_myarray obj)
127 {
128 size_t align=0, localign;
129
130 localign = sizeof(uint64_t);
131 align = max(align, localign);
132
133 return align;
134 }
135
136
137 static inline void lttng_write_array_mystruct_myarray(
138 void *buffer,
139 size_t *to_base,
140 size_t *to,
141 void **from,
142 size_t *len,
143 lttng_array_mystruct_myarray obj)
144 {
145 size_t align, size;
146
147 align = lttng_get_alignment_array_mystruct_myarray(obj);
148 //size = lttng_get_size_array_mystruct_myarray(obj);
149 size = sizeof(lttng_array_mystruct_myarray);
150
151 if(*len == 0) {
152 *to += ltt_align(*to, align); /* align output */
153 } else {
154 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
155 }
156
157 *len += size;
158 #if 0
159 /* For varlen child : let the child align itself. */
160 for(unsigned int i=0; i<LTTNG_ARRAY_SIZE_mystruct_myarray; i++) {
161 lttng_write_child(buffer, to_base, to, from, len, obj[i]);
162 }
163 #endif //0
164
165 }
166
167
168 typedef struct lttng_sequence_mystruct_mysequence lttng_sequence_mystruct_mysequence;
169 struct lttng_sequence_mystruct_mysequence {
170 unsigned int len;
171 double *array;
172 };
173
174 #if 0
175 static inline size_t lttng_get_size_sequence_mystruct_mysequence(
176 lttng_sequence_mystruct_mysequence *obj)
177 {
178 size_t size=0, locsize;
179
180 locsize = sizeof(unsigned int);
181 size += ltt_align(size, locsize) + locsize;
182
183 locsize = sizeof(double);
184 size += ltt_align(size, locsize) + (obj->len * locsize);
185
186 /* Realign on arch size */
187 locsize = sizeof(void *);
188 size += ltt_align(size, locsize);
189
190 return size;
191 }
192 #endif //0
193
194 static inline size_t lttng_get_alignment_sequence_mystruct_mysequence(
195 lttng_sequence_mystruct_mysequence *obj)
196 {
197 size_t align=0, localign;
198
199 localign = sizeof(unsigned int);
200 align = max(align, localign);
201
202 localign = sizeof(double);
203 align = max(align, localign);
204
205 return align;
206 }
207
208
209 static inline void lttng_write_sequence_mystruct_mysequence(
210 void *buffer,
211 size_t *to_base,
212 size_t *to,
213 void **from,
214 size_t *len,
215 lttng_sequence_mystruct_mysequence *obj)
216 {
217 size_t align;
218 size_t size;
219
220 /* Flush pending memcpy */
221 if(*len != 0) {
222 if(buffer != NULL)
223 memcpy(buffer+*to_base+*to, *from, *len);
224 }
225 *to += *len;
226 *len = 0;
227
228 align = lttng_get_alignment_sequence_mystruct_mysequence(obj);
229 //no need size = lttng_get_size_sequence_mystruct_mysequence(obj);
230
231 /* Align output */
232 *to += ltt_align(*to, align); /* *len = 0 in this function */
233
234 /* Copy members */
235 size = sizeof(unsigned int);
236 *to += ltt_align(*to, size);
237 if(buffer != NULL)
238 memcpy(buffer+*to_base+*to, &obj->len, size);
239 *to += size;
240
241 size = sizeof(double);
242 *to += ltt_align(*to, size);
243 size = obj->len * sizeof(double);
244 if(buffer != NULL)
245 memcpy(buffer+*to_base+*to, obj->array, size);
246 *to += size;
247 #if 0
248 /* If varlen child : let child align itself */
249 for(unsigned int i=0; i<obj->len; i++) {
250 lttng_write_child(buffer, to_base, to, from, len, obj->array[i]);
251 }
252 #endif //0
253
254
255 /* Realign the *to_base on arch size, set *to to 0 */
256 *to = ltt_align(*to, sizeof(void *));
257 *to_base = *to_base+*to;
258 *to = 0;
259
260 /* Put source *from just after the C sequence */
261 *from = obj+1;
262 }
263
264
265
266 union lttng_mystruct_myunion {
267 double myfloat;
268 unsigned long myulong;
269 };
270
271 #if 0
272 static inline size_t lttng_get_size_mystruct_myunion(
273 union lttng_mystruct_myunion *obj)
274 {
275 size_t size=0, locsize;
276
277 locsize = sizeof(double);
278 size = max(size, locsize);
279
280 locsize = sizeof(unsigned long);
281 size = max(size, locsize);
282
283 BUG_ON(size != sizeof(union lttng_mystruct_myunion));
284
285 return sizeof(union lttng_mystruct_myunion);
286 }
287 #endif //0
288
289 static inline size_t lttng_get_alignment_mystruct_myunion(
290 union lttng_mystruct_myunion *obj)
291 {
292 size_t align=0, localign;
293
294 localign = sizeof(double);
295 align = max(align, localign);
296
297 localign = sizeof(unsigned long);
298 align = max(align, localign);
299
300 return align;
301 }
302
303
304 static inline void lttng_write_mystruct_myunion(
305 void *buffer,
306 size_t *to_base,
307 size_t *to,
308 void **from,
309 size_t *len,
310 union lttng_mystruct_myunion *obj)
311 {
312 size_t align, size;
313
314 align = lttng_get_alignment_mystruct_myunion(obj);
315 //size = lttng_get_size_mystruct_myunion(obj);
316 size = sizeof(union lttng_mystruct_myunion);
317
318 if(*len == 0) {
319 *to += ltt_align(*to, align); /* align output */
320 } else {
321 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
322 }
323
324 *len += size;
325 }
326
327
328 struct lttng_mystruct {
329 unsigned int irq_id;
330 enum lttng_irq_mode mode;
331 struct lttng_mystruct2 teststr;
332 lttng_array_mystruct_myarray myarray;
333 lttng_sequence_mystruct_mysequence mysequence;
334 union lttng_mystruct_myunion myunion;
335 };
336
337 #if 0
338 static inline size_t lttng_get_size_mystruct(
339 struct lttng_mystruct *obj)
340 {
341 size_t size=0, locsize, localign;
342
343 locsize = sizeof(unsigned int);
344 size += ltt_align(size, locsize) + locsize;
345
346 locsize = sizeof(enum lttng_irq_mode);
347 size += ltt_align(size, locsize) + locsize;
348
349 localign = lttng_get_alignment_mystruct2(&obj->teststr);
350 locsize = lttng_get_size_mystruct2(&obj->teststr);
351 size += ltt_align(size, localign) + locsize;
352
353 localign = lttng_get_alignment_array_mystruct_myarray(obj->myarray);
354 locsize = lttng_get_size_array_mystruct_myarray(obj->myarray);
355 size += ltt_align(size, localign) + locsize;
356
357 localign = lttng_get_alignment_sequence_mystruct_mysequence(&obj->mysequence);
358 locsize = lttng_get_size_sequence_mystruct_mysequence(&obj->mysequence);
359 size += ltt_align(size, localign) + locsize;
360
361 localign = lttng_get_alignment_mystruct_myunion(&obj->myunion);
362 locsize = lttng_get_size_mystruct_myunion(&obj->myunion);
363 size += ltt_align(size, localign) + locsize;
364
365 return size;
366 }
367 #endif //0
368
369 static inline size_t lttng_get_alignment_mystruct(
370 struct lttng_mystruct *obj)
371 {
372 size_t align=0, localign;
373
374 localign = sizeof(unsigned int);
375 align = max(align, localign);
376
377 localign = sizeof(enum lttng_irq_mode);
378 align = max(align, localign);
379
380 localign = lttng_get_alignment_mystruct2(&obj->teststr);
381 align = max(align, localign);
382
383 localign = lttng_get_alignment_array_mystruct_myarray(obj->myarray);
384 align = max(align, localign);
385
386 localign = lttng_get_alignment_sequence_mystruct_mysequence(&obj->mysequence);
387 align = max(align, localign);
388
389 localign = lttng_get_alignment_mystruct_myunion(&obj->myunion);
390 align = max(align, localign);
391
392 return align;
393 }
394
395 static inline void lttng_write_mystruct(
396 void *buffer,
397 size_t *to_base,
398 size_t *to,
399 void **from,
400 size_t *len,
401 struct lttng_mystruct *obj)
402 {
403 size_t align, size;
404
405 align = lttng_get_alignment_mystruct(obj);
406 // no need : contains variable size fields.
407 // locsize = lttng_get_size_mystruct(obj);
408
409 if(*len == 0) {
410 *to += ltt_align(*to, align); /* align output */
411 } else {
412 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
413 }
414
415 /* Contains variable sized fields : must explode the structure */
416
417 size = sizeof(unsigned int);
418 size += ltt_align(*to+*len, size) + size;
419 *len += size;
420
421 size = sizeof(enum lttng_irq_mode);
422 size += ltt_align(*to+*len, size) + size;
423 *len += size;
424
425 lttng_write_mystruct2(buffer, to_base, to, from, len, &obj->teststr);
426
427 lttng_write_array_mystruct_myarray(buffer, to_base, to, from, len, obj->myarray);
428
429 /* Variable length field */
430 lttng_write_sequence_mystruct_mysequence(buffer, to_base, to, from, len, &obj->mysequence);
431 /* After this previous write, we are sure that *to is 0, and *to_base is
432 * aligned on the architecture size : to rest of alignment will be calculated
433 * statically. */
434
435 lttng_write_mystruct_myunion(buffer, to_base, to, from, len, &obj->myunion);
436
437 /* Don't forget to flush last write..... */
438 }
439
440
441
442
443
444
445 //void main()
446 void test()
447 {
448 struct lttng_mystruct test;
449 test.mysequence.len = 20;
450 test.mysequence.array = malloc(20);
451
452 //size_t size = lttng_get_size_mystruct(&test);
453 //size_t align = lttng_get_alignment_mystruct(&test);
454 //
455 size_t to_base = 0; /* the buffer is allocated on arch_size alignment */
456 size_t to = 0;
457 void *from = &test;
458 size_t len = 0;
459
460 /* Get size */
461 lttng_write_mystruct(NULL, &to_base, &to, &from, &len, &test);
462 /* Size = to_base + to + len */
463
464 void *buffer = malloc(to_base + to + len);
465 to_base = 0; /* the buffer is allocated on arch_size alignment */
466 to = 0;
467 from = &test;
468 len = 0;
469
470 lttng_write_mystruct(buffer, &to_base, &to, &from, &len, &test);
471 /* Final flush */
472 /* Flush pending memcpy */
473 if(len != 0) {
474 // Assert buffer != NULL */
475 memcpy(buffer+to_base+to, from, len);
476 to += len;
477 from += len;
478 len = 0;
479 }
480
481 free(test.mysequence.array);
482 free(buffer);
483 }
This page took 0.038394 seconds and 4 git commands to generate.