2 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
3 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
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:
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
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
32 #include "barectf-platform-linux-fs.h"
36 # define _FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value)
38 # define _FROM_VOID_PTR(_type, _value) ((_type *) (_value))
41 struct barectf_platform_linux_fs_ctx
{
42 struct barectf_default_ctx ctx
;
44 int simulate_full_backend
;
45 unsigned int full_backend_rand_lt
;
46 unsigned int full_backend_rand_max
;
49 static uint64_t get_clock(void * const data
)
53 clock_gettime(CLOCK_REALTIME
, &ts
);
54 return ts
.tv_sec
* 1000000000ULL + ts
.tv_nsec
;
57 static void write_packet(const struct barectf_platform_linux_fs_ctx
* const platform_ctx
)
59 const size_t nmemb
= fwrite(barectf_packet_buf(&platform_ctx
->ctx
),
60 barectf_packet_buf_size(&platform_ctx
->ctx
), 1, platform_ctx
->fh
);
65 static int is_backend_full(void * const data
)
67 int is_backend_full
= 0;
68 const struct barectf_platform_linux_fs_ctx
* const platform_ctx
=
69 _FROM_VOID_PTR(const struct barectf_platform_linux_fs_ctx
, data
);
71 if (platform_ctx
->simulate_full_backend
) {
72 if (rand() % platform_ctx
->full_backend_rand_max
<
73 platform_ctx
->full_backend_rand_lt
) {
80 return is_backend_full
;
83 static void open_packet(void * const data
)
85 struct barectf_platform_linux_fs_ctx
* const platform_ctx
=
86 _FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx
, data
);
88 barectf_default_open_packet(&platform_ctx
->ctx
);
91 static void close_packet(void * const data
)
93 struct barectf_platform_linux_fs_ctx
* const platform_ctx
=
94 _FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx
, data
);
96 /* Close packet now */
97 barectf_default_close_packet(&platform_ctx
->ctx
);
99 /* Write packet to file */
100 write_packet(platform_ctx
);
103 struct barectf_platform_linux_fs_ctx
*barectf_platform_linux_fs_init(
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
)
109 char stream_path
[256];
111 struct barectf_platform_linux_fs_ctx
*platform_ctx
;
112 struct barectf_platform_callbacks cbs
;
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
;
118 platform_ctx
= _FROM_VOID_PTR(struct barectf_platform_linux_fs_ctx
,
119 malloc(sizeof(*platform_ctx
)));
125 buf
= _FROM_VOID_PTR(uint8_t, malloc(buf_size
));
131 sprintf(stream_path
, "%s/stream", trace_dir
);
132 platform_ctx
->fh
= fopen(stream_path
, "wb");
134 if (!platform_ctx
->fh
) {
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
);
153 void barectf_platform_linux_fs_fini(struct barectf_platform_linux_fs_ctx
* const platform_ctx
)
155 if (barectf_packet_is_open(&platform_ctx
->ctx
) &&
156 !barectf_packet_is_empty(&platform_ctx
->ctx
)) {
157 close_packet(platform_ctx
);
160 fclose(platform_ctx
->fh
);
161 free(barectf_packet_buf(&platform_ctx
->ctx
));
165 struct barectf_default_ctx
*barectf_platform_linux_fs_get_barectf_ctx(
166 struct barectf_platform_linux_fs_ctx
* const platform_ctx
)
168 return &platform_ctx
->ctx
;