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