lttv 0.8.13
[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 /* Assert : no varlen child. */
327 }
328
329
330 struct lttng_mystruct {
331 unsigned int irq_id;
332 enum lttng_irq_mode mode;
333 struct lttng_mystruct2 teststr;
334 lttng_array_mystruct_myarray myarray;
335 lttng_sequence_mystruct_mysequence mysequence;
336 union lttng_mystruct_myunion myunion;
337 };
338
339 #if 0
340 static inline size_t lttng_get_size_mystruct(
341 struct lttng_mystruct *obj)
342 {
343 size_t size=0, locsize, localign;
344
345 locsize = sizeof(unsigned int);
346 size += ltt_align(size, locsize) + locsize;
347
348 locsize = sizeof(enum lttng_irq_mode);
349 size += ltt_align(size, locsize) + locsize;
350
351 localign = lttng_get_alignment_mystruct2(&obj->teststr);
352 locsize = lttng_get_size_mystruct2(&obj->teststr);
353 size += ltt_align(size, localign) + locsize;
354
355 localign = lttng_get_alignment_array_mystruct_myarray(obj->myarray);
356 locsize = lttng_get_size_array_mystruct_myarray(obj->myarray);
357 size += ltt_align(size, localign) + locsize;
358
359 localign = lttng_get_alignment_sequence_mystruct_mysequence(&obj->mysequence);
360 locsize = lttng_get_size_sequence_mystruct_mysequence(&obj->mysequence);
361 size += ltt_align(size, localign) + locsize;
362
363 localign = lttng_get_alignment_mystruct_myunion(&obj->myunion);
364 locsize = lttng_get_size_mystruct_myunion(&obj->myunion);
365 size += ltt_align(size, localign) + locsize;
366
367 return size;
368 }
369 #endif //0
370
371 static inline size_t lttng_get_alignment_mystruct(
372 struct lttng_mystruct *obj)
373 {
374 size_t align=0, localign;
375
376 localign = sizeof(unsigned int);
377 align = max(align, localign);
378
379 localign = sizeof(enum lttng_irq_mode);
380 align = max(align, localign);
381
382 localign = lttng_get_alignment_mystruct2(&obj->teststr);
383 align = max(align, localign);
384
385 localign = lttng_get_alignment_array_mystruct_myarray(obj->myarray);
386 align = max(align, localign);
387
388 localign = lttng_get_alignment_sequence_mystruct_mysequence(&obj->mysequence);
389 align = max(align, localign);
390
391 localign = lttng_get_alignment_mystruct_myunion(&obj->myunion);
392 align = max(align, localign);
393
394 return align;
395 }
396
397 static inline void lttng_write_mystruct(
398 void *buffer,
399 size_t *to_base,
400 size_t *to,
401 void **from,
402 size_t *len,
403 struct lttng_mystruct *obj)
404 {
405 size_t align, size;
406
407 align = lttng_get_alignment_mystruct(obj);
408 // no need : contains variable size fields.
409 // locsize = lttng_get_size_mystruct(obj);
410
411 if(*len == 0) {
412 *to += ltt_align(*to, align); /* align output */
413 } else {
414 *len += ltt_align(*to+*len, align); /* C alignment, ok to do a memcpy of it */
415 }
416
417 /* Contains variable sized fields : must explode the structure */
418
419 size = sizeof(unsigned int);
420 size += ltt_align(*to+*len, size) + size;
421 *len += size;
422
423 size = sizeof(enum lttng_irq_mode);
424 size += ltt_align(*to+*len, size) + size;
425 *len += size;
426
427 lttng_write_mystruct2(buffer, to_base, to, from, len, &obj->teststr);
428
429 lttng_write_array_mystruct_myarray(buffer, to_base, to, from, len, obj->myarray);
430
431 /* Variable length field */
432 lttng_write_sequence_mystruct_mysequence(buffer, to_base, to, from, len, &obj->mysequence);
433 /* After this previous write, we are sure that *to is 0, *len is 0 and
434 * *to_base is aligned on the architecture size : to rest of alignment will
435 * be calculated statically. */
436
437 lttng_write_mystruct_myunion(buffer, to_base, to, from, len, &obj->myunion);
438
439 /* Don't forget to flush last write..... */
440 }
441
442
443
444
445
446
447 //void main()
448 void test()
449 {
450 struct lttng_mystruct test;
451 test.mysequence.len = 20;
452 test.mysequence.array = malloc(20);
453
454 //size_t size = lttng_get_size_mystruct(&test);
455 //size_t align = lttng_get_alignment_mystruct(&test);
456 //
457 size_t to_base = 0; /* the buffer is allocated on arch_size alignment */
458 size_t to = 0;
459 void *from = &test;
460 size_t len = 0;
461
462 /* Get size */
463 lttng_write_mystruct(NULL, &to_base, &to, &from, &len, &test);
464 /* Size = to_base + to + len */
465
466 void *buffer = malloc(to_base + to + len);
467 to_base = 0; /* the buffer is allocated on arch_size alignment */
468 to = 0;
469 from = &test;
470 len = 0;
471
472 lttng_write_mystruct(buffer, &to_base, &to, &from, &len, &test);
473 /* Final flush */
474 /* Flush pending memcpy */
475 if(len != 0) {
476 // Assert buffer != NULL */
477 memcpy(buffer+to_base+to, from, len);
478 to += len;
479 from += len;
480 len = 0;
481 }
482
483 free(test.mysequence.array);
484 free(buffer);
485 }
This page took 0.038396 seconds and 4 git commands to generate.