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> | |
29 | #include <assert.h> | |
30 | #include <barectf.h> | |
31 | #include <time.h> | |
32 | ||
33 | #include "barectf-platform-linux-fs.h" | |
34 | ||
35 | struct barectf_platform_linux_fs_ctx { | |
36 | struct barectf_default_ctx ctx; | |
37 | FILE *fh; | |
38 | int simulate_full_backend; | |
39 | unsigned int full_backend_rand_lt; | |
40 | unsigned int full_backend_rand_max; | |
41 | }; | |
42 | ||
43 | static uint64_t get_clock(void* data) | |
44 | { | |
45 | struct timespec ts; | |
46 | ||
47 | clock_gettime(CLOCK_MONOTONIC, &ts); | |
48 | ||
49 | return ts.tv_sec * 1000000000ULL + ts.tv_nsec; | |
50 | } | |
51 | ||
52 | static void write_packet(struct barectf_platform_linux_fs_ctx *ctx) | |
53 | { | |
54 | size_t nmemb = fwrite(barectf_packet_buf(&ctx->ctx), | |
55 | barectf_packet_buf_size(&ctx->ctx), 1, ctx->fh); | |
56 | assert(nmemb == 1); | |
57 | } | |
58 | ||
59 | static int is_backend_full(void *data) | |
60 | { | |
61 | struct barectf_platform_linux_fs_ctx *ctx = data; | |
62 | ||
63 | if (ctx->simulate_full_backend) { | |
64 | if (rand() % ctx->full_backend_rand_max < | |
65 | ctx->full_backend_rand_lt) { | |
66 | return 1; | |
67 | } | |
68 | } | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | static void open_packet(void *data) | |
74 | { | |
75 | struct barectf_platform_linux_fs_ctx *ctx = data; | |
76 | ||
77 | barectf_default_open_packet(&ctx->ctx); | |
78 | } | |
79 | ||
80 | static void close_packet(void *data) | |
81 | { | |
82 | struct barectf_platform_linux_fs_ctx *ctx = data; | |
83 | ||
84 | /* close packet now */ | |
85 | barectf_default_close_packet(&ctx->ctx); | |
86 | ||
87 | /* write packet to file */ | |
88 | write_packet(ctx); | |
89 | } | |
90 | ||
91 | struct barectf_platform_linux_fs_ctx *barectf_platform_linux_fs_init( | |
92 | unsigned int buf_size, const char *trace_dir, int simulate_full_backend, | |
93 | unsigned int full_backend_rand_lt, unsigned int full_backend_rand_max) | |
94 | { | |
95 | char stream_path[256]; | |
96 | uint8_t *buf; | |
97 | struct barectf_platform_linux_fs_ctx *ctx; | |
98 | struct barectf_platform_callbacks cbs = { | |
99 | .default_clock_get_value = get_clock, | |
100 | .is_backend_full = is_backend_full, | |
101 | .open_packet = open_packet, | |
102 | .close_packet = close_packet, | |
103 | }; | |
104 | ||
105 | ctx = malloc(sizeof(*ctx)); | |
106 | ||
107 | if (!ctx) { | |
108 | return NULL; | |
109 | } | |
110 | ||
111 | buf = malloc(buf_size); | |
112 | ||
113 | if (!buf) { | |
114 | free(ctx); | |
115 | return NULL; | |
116 | } | |
117 | ||
118 | sprintf(stream_path, "%s/stream", trace_dir); | |
119 | ctx->fh = fopen(stream_path, "wb"); | |
120 | ||
121 | if (!ctx->fh) { | |
122 | free(ctx); | |
123 | free(buf); | |
124 | return NULL; | |
125 | } | |
126 | ||
127 | ctx->simulate_full_backend = simulate_full_backend; | |
128 | ctx->full_backend_rand_lt = full_backend_rand_lt; | |
129 | ctx->full_backend_rand_max = full_backend_rand_max; | |
130 | ||
131 | barectf_init(&ctx->ctx, buf, buf_size, cbs, ctx); | |
132 | open_packet(ctx); | |
133 | ||
134 | return ctx; | |
135 | } | |
136 | ||
137 | void barectf_platform_linux_fs_fini(struct barectf_platform_linux_fs_ctx *ctx) | |
138 | { | |
139 | if (barectf_packet_is_open(&ctx->ctx) && | |
140 | !barectf_packet_is_empty(&ctx->ctx)) { | |
141 | close_packet(ctx); | |
142 | } | |
143 | ||
144 | fclose(ctx->fh); | |
145 | free(barectf_packet_buf(&ctx->ctx)); | |
146 | free(ctx); | |
147 | } | |
148 | ||
149 | struct barectf_default_ctx *barectf_platform_linux_fs_get_barectf_ctx( | |
150 | struct barectf_platform_linux_fs_ctx *ctx) | |
151 | { | |
152 | return &ctx->ctx; | |
153 | } |