Commit | Line | Data |
---|---|---|
e5aa0be3 PP |
1 | /* |
2 | * barectf linux-fs platform | |
3 | * | |
4 | * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation | |
5 | * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com> | |
6 | * | |
7 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 | * of this software and associated documentation files (the "Software"), to deal | |
9 | * in the Software without restriction, including without limitation the rights | |
10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | * copies of the Software, and to permit persons to whom the Software is | |
12 | * furnished to do so, subject to the following conditions: | |
13 | * | |
14 | * The above copyright notice and this permission notice shall be included in | |
15 | * all copies or substantial portions of the Software. | |
16 | * | |
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 | * SOFTWARE. | |
24 | */ | |
25 | ||
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | #include <stdint.h> | |
864a5cd4 | 29 | #include <string.h> |
e5aa0be3 PP |
30 | #include <assert.h> |
31 | #include <barectf.h> | |
32 | #include <time.h> | |
33 | ||
34 | #include "barectf-platform-linux-fs.h" | |
35 | ||
f66be07f PP |
36 | #ifdef __cplusplus |
37 | # define TO_VOID_PTR(_value) static_cast<void *>(_value) | |
38 | # define FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value) | |
39 | #else | |
40 | # define TO_VOID_PTR(_value) ((void *) (_value)) | |
41 | # define FROM_VOID_PTR(_type, _value) ((_type *) (_value)) | |
42 | #endif | |
43 | ||
e5aa0be3 PP |
44 | struct barectf_platform_linux_fs_ctx { |
45 | struct barectf_default_ctx ctx; | |
46 | FILE *fh; | |
47 | int simulate_full_backend; | |
48 | unsigned int full_backend_rand_lt; | |
49 | unsigned int full_backend_rand_max; | |
50 | }; | |
51 | ||
52 | static uint64_t get_clock(void* data) | |
53 | { | |
54 | struct timespec ts; | |
55 | ||
56 | clock_gettime(CLOCK_MONOTONIC, &ts); | |
57 | ||
58 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; | |
59 | } | |
60 | ||
61 | static void write_packet(struct barectf_platform_linux_fs_ctx *ctx) | |
62 | { | |
63 | size_t nmemb = fwrite(barectf_packet_buf(&ctx->ctx), | |
64 | barectf_packet_buf_size(&ctx->ctx), 1, ctx->fh); | |
65 | assert(nmemb == 1); | |
66 | } | |
67 | ||
68 | static int is_backend_full(void *data) | |
69 | { | |
f66be07f PP |
70 | struct barectf_platform_linux_fs_ctx *ctx = |
71 | FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx, data); | |
e5aa0be3 PP |
72 | |
73 | if (ctx->simulate_full_backend) { | |
74 | if (rand() % ctx->full_backend_rand_max < | |
75 | ctx->full_backend_rand_lt) { | |
76 | return 1; | |
77 | } | |
78 | } | |
79 | ||
80 | return 0; | |
81 | } | |
82 | ||
83 | static void open_packet(void *data) | |
84 | { | |
f66be07f PP |
85 | struct barectf_platform_linux_fs_ctx *ctx = |
86 | FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx, data); | |
e5aa0be3 PP |
87 | |
88 | barectf_default_open_packet(&ctx->ctx); | |
89 | } | |
90 | ||
91 | static void close_packet(void *data) | |
92 | { | |
f66be07f PP |
93 | struct barectf_platform_linux_fs_ctx *ctx = |
94 | FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx, data); | |
e5aa0be3 PP |
95 | |
96 | /* close packet now */ | |
97 | barectf_default_close_packet(&ctx->ctx); | |
98 | ||
99 | /* write packet to file */ | |
100 | write_packet(ctx); | |
101 | } | |
102 | ||
103 | struct barectf_platform_linux_fs_ctx *barectf_platform_linux_fs_init( | |
104 | unsigned int buf_size, const char *trace_dir, int simulate_full_backend, | |
105 | unsigned int full_backend_rand_lt, unsigned int full_backend_rand_max) | |
106 | { | |
107 | char stream_path[256]; | |
108 | uint8_t *buf; | |
109 | struct barectf_platform_linux_fs_ctx *ctx; | |
f66be07f | 110 | struct barectf_platform_callbacks cbs; |
e5aa0be3 | 111 | |
f66be07f PP |
112 | cbs.default_clock_get_value = get_clock; |
113 | cbs.is_backend_full = is_backend_full; | |
114 | cbs.open_packet = open_packet; | |
115 | cbs.close_packet = close_packet; | |
116 | ctx = FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx, malloc(sizeof(*ctx))); | |
e5aa0be3 PP |
117 | |
118 | if (!ctx) { | |
119 | return NULL; | |
120 | } | |
121 | ||
f66be07f | 122 | buf = FROM_VOID_PTR(uint8_t, malloc(buf_size)); |
e5aa0be3 PP |
123 | |
124 | if (!buf) { | |
125 | free(ctx); | |
126 | return NULL; | |
127 | } | |
128 | ||
864a5cd4 PP |
129 | memset(buf, 0, buf_size); |
130 | ||
e5aa0be3 PP |
131 | sprintf(stream_path, "%s/stream", trace_dir); |
132 | ctx->fh = fopen(stream_path, "wb"); | |
133 | ||
134 | if (!ctx->fh) { | |
135 | free(ctx); | |
136 | free(buf); | |
137 | return NULL; | |
138 | } | |
139 | ||
140 | ctx->simulate_full_backend = simulate_full_backend; | |
141 | ctx->full_backend_rand_lt = full_backend_rand_lt; | |
142 | ctx->full_backend_rand_max = full_backend_rand_max; | |
143 | ||
144 | barectf_init(&ctx->ctx, buf, buf_size, cbs, ctx); | |
145 | open_packet(ctx); | |
146 | ||
147 | return ctx; | |
148 | } | |
149 | ||
150 | void barectf_platform_linux_fs_fini(struct barectf_platform_linux_fs_ctx *ctx) | |
151 | { | |
152 | if (barectf_packet_is_open(&ctx->ctx) && | |
153 | !barectf_packet_is_empty(&ctx->ctx)) { | |
154 | close_packet(ctx); | |
155 | } | |
156 | ||
157 | fclose(ctx->fh); | |
158 | free(barectf_packet_buf(&ctx->ctx)); | |
159 | free(ctx); | |
160 | } | |
161 | ||
162 | struct barectf_default_ctx *barectf_platform_linux_fs_get_barectf_ctx( | |
163 | struct barectf_platform_linux_fs_ctx *ctx) | |
164 | { | |
165 | return &ctx->ctx; | |
166 | } |