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