metababel 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/metababel +62 -27
- data/lib/metababel/bt2_stream_classes_generator.rb +152 -71
- data/lib/metababel/bt2_values_generator.rb +19 -16
- data/lib/metababel/version.rb +1 -1
- data/template/component.c.erb +0 -1
- data/template/component.h.erb +3 -0
- data/template/downstream.c.erb +12 -7
- data/template/downstream.h.erb +2 -2
- data/template/filter.c.erb +44 -14
- data/template/sink.c.erb +34 -16
- data/template/source.c.erb +1 -1
- data/template/upstream.c.erb +118 -8
- data/template/upstream.h.erb +36 -6
- metadata +3 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4a06ce284438f35303ef476971d820bd7ae1c2370b58181ba36146821d4423f7
|
|
4
|
+
data.tar.gz: 534aff0d21827f367caa9295051d886be08e624a24775e9c3fbd19da7fef97dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: edac518ba0bbec6c560f1e763bbf9df96d40e9b666f6c54db2fda8c71a1f9676a880e79f97a0aeb6c311db4c2cf3f2870d1643ae2f3e17514ac9fa9123001f71
|
|
7
|
+
data.tar.gz: 484cf07cd9e6930c2a54fc562e79420ceeb7a5a6a931e90576084cb6a252af2526ac3fddb41bcc080bb6c9879c20f248094f7455b6fca93424873b92dca61828
|
data/bin/metababel
CHANGED
|
@@ -7,11 +7,22 @@ require 'metababel'
|
|
|
7
7
|
require 'fileutils'
|
|
8
8
|
|
|
9
9
|
def validate_model(yaml)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
# Stream and event classes must have a 'name' as minimum requirement.
|
|
11
|
+
raise "Missing 'name' attr in model #{yaml}" unless yaml[:stream_classes].all? do |d|
|
|
12
|
+
d.key?(:name) && d[:event_classes].all? do |d2|
|
|
13
|
+
d2.key?(:name)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Event class name must be unique
|
|
18
|
+
events = yaml[:stream_classes].flat_map { |sc| sc[:event_classes] }.map { |e| e[:name] }
|
|
19
|
+
raise "Duplicated 'event' in model #{yaml}" unless events.length == events.uniq.length
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class Array
|
|
23
|
+
def join_with_prefix(sep)
|
|
24
|
+
empty? ? '' : "#{sep}#{join(sep)}"
|
|
25
|
+
end
|
|
15
26
|
end
|
|
16
27
|
|
|
17
28
|
class Hash
|
|
@@ -33,7 +44,14 @@ class Hash
|
|
|
33
44
|
end
|
|
34
45
|
end
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
EventClassInfo = Struct.new(:name, :args, :body, :index_stream_class, :index_event_class, :default_clock_class,
|
|
48
|
+
:args_to_free) do
|
|
49
|
+
def name_sanitized
|
|
50
|
+
name.gsub(/[^0-9A-Za-z-]/, '_')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
StreamClassInfo = Struct.new(:name, :args, :body, :default_clock_class) do
|
|
37
55
|
def name_sanitized
|
|
38
56
|
name.gsub(/[^0-9A-Za-z-]/, '_')
|
|
39
57
|
end
|
|
@@ -56,7 +74,7 @@ class Babeltrace2Gen::BTTraceClass
|
|
|
56
74
|
def map_event_classes_with_index
|
|
57
75
|
@stream_classes.map.with_index do |s, index_stream_class|
|
|
58
76
|
s.event_classes.map.with_index do |e, index_event_class|
|
|
59
|
-
yield(e, index_stream_class, index_event_class)
|
|
77
|
+
yield(e, index_stream_class, index_event_class, s.default_clock_class)
|
|
60
78
|
end
|
|
61
79
|
end.flatten
|
|
62
80
|
end
|
|
@@ -71,15 +89,28 @@ end
|
|
|
71
89
|
# But we clean the white space empty line afterward \o/
|
|
72
90
|
def wrote_event_dispatchers(folder, t)
|
|
73
91
|
event_name = 'event'
|
|
74
|
-
|
|
75
|
-
arg_variables =
|
|
92
|
+
event_class_dispatchers = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
|
|
93
|
+
arg_variables = {}
|
|
76
94
|
body = Babeltrace2Gen.context(indent: 1) do
|
|
77
95
|
e.get_getter(event: event_name, arg_variables: arg_variables)
|
|
78
96
|
end
|
|
79
|
-
|
|
97
|
+
EventClassInfo.new(e.name, arg_variables.fetch('outputs', []), body, index_stream_class, index_event_class, default_clock_class,
|
|
98
|
+
arg_variables.fetch('outputs_allocated', []))
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
stream_classes_matching_dispatchers = t.stream_classes.map do |s|
|
|
102
|
+
arg_variables = {}
|
|
103
|
+
body = ''
|
|
104
|
+
if s.event_common_context_field_class
|
|
105
|
+
body = Babeltrace2Gen.context(indent: 1) do
|
|
106
|
+
s.get_getter(event: event_name, arg_variables: arg_variables)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
StreamClassInfo.new(s.name, arg_variables.fetch('outputs', []), body, s.default_clock_class)
|
|
80
110
|
end
|
|
81
111
|
|
|
82
|
-
d = {
|
|
112
|
+
d = { event_class_dispatchers: event_class_dispatchers,
|
|
113
|
+
stream_classes_matching_dispatchers: stream_classes_matching_dispatchers,
|
|
83
114
|
event_name: event_name }
|
|
84
115
|
|
|
85
116
|
erb_render_and_save(d, 'upstream.h', folder)
|
|
@@ -88,16 +119,17 @@ end
|
|
|
88
119
|
|
|
89
120
|
def wrote_creates(folder, t)
|
|
90
121
|
event_name = 'event'
|
|
91
|
-
downstream_events = t.map_event_classes_with_index do |e, index_stream_class, index_event_class|
|
|
92
|
-
arg_variables =
|
|
122
|
+
downstream_events = t.map_event_classes_with_index do |e, index_stream_class, index_event_class, default_clock_class|
|
|
123
|
+
arg_variables = {}
|
|
93
124
|
body = Babeltrace2Gen.context(indent: 1) do
|
|
94
125
|
e.get_setter(event: event_name, arg_variables: arg_variables)
|
|
95
126
|
end
|
|
96
|
-
|
|
127
|
+
EventClassInfo.new(e.name, arg_variables.fetch('outputs', []), "\n" + body, index_stream_class, index_event_class,
|
|
128
|
+
default_clock_class)
|
|
97
129
|
end
|
|
98
130
|
|
|
99
131
|
body_declarator_classes = "\n" + Babeltrace2Gen.context(indent: 1) do
|
|
100
|
-
t.get_declarator(variable: 'trace_class')
|
|
132
|
+
t.get_declarator(variable: 'trace_class', self_component: 'self_component')
|
|
101
133
|
end
|
|
102
134
|
|
|
103
135
|
d = { body_declarator_classes: body_declarator_classes,
|
|
@@ -110,18 +142,18 @@ def wrote_creates(folder, t)
|
|
|
110
142
|
end
|
|
111
143
|
|
|
112
144
|
def wrote_component(options, d, folder)
|
|
113
|
-
component_dispatchers = [
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
145
|
+
component_dispatchers = [EventClassInfo.new('initialize_usr_data',
|
|
146
|
+
[GeneratedArg.new('void **', 'usr_data_p')]),
|
|
147
|
+
EventClassInfo.new('finalize_usr_data',
|
|
148
|
+
[GeneratedArg.new('void *', 'usr_data')]),
|
|
149
|
+
EventClassInfo.new('read_params',
|
|
150
|
+
[GeneratedArg.new('void *', 'usr_data'),
|
|
151
|
+
GeneratedArg.new('btx_params_t *', 'usr_params')])]
|
|
120
152
|
|
|
121
153
|
if options[:component_type] == 'SOURCE'
|
|
122
|
-
component_dispatchers <<
|
|
123
|
-
|
|
124
|
-
|
|
154
|
+
component_dispatchers << EventClassInfo.new('push_usr_messages',
|
|
155
|
+
[GeneratedArg.new('void *', 'usr_data'),
|
|
156
|
+
GeneratedArg.new('btx_source_status_t*', 'status')])
|
|
125
157
|
end
|
|
126
158
|
|
|
127
159
|
d2 = { component_dispatchers: component_dispatchers,
|
|
@@ -183,8 +215,9 @@ OptionParser.new do |opts|
|
|
|
183
215
|
end.parse!
|
|
184
216
|
|
|
185
217
|
raise OptionParser::MissingArgument if options[:component_type].nil?
|
|
218
|
+
|
|
186
219
|
options[:plugin_name] ||= "metababel_#{options[:component_type].downcase}"
|
|
187
|
-
options[:component_name] ||=
|
|
220
|
+
options[:component_name] ||= 'btx'
|
|
188
221
|
|
|
189
222
|
# Babeltrace can be extended by plugins, which provide one or more component classes.
|
|
190
223
|
base_folder = options[:folder] || "#{options[:component_type]}.#{options[:plugin_name]}.#{options[:component_name]}"
|
|
@@ -203,9 +236,11 @@ if options.key?(:params)
|
|
|
203
236
|
end
|
|
204
237
|
d[:params_declaration] = c.get_struct_definition('params')
|
|
205
238
|
d[:params_definition] = body
|
|
239
|
+
else
|
|
240
|
+
d[:params_declaration] = 'char _dummy;'
|
|
206
241
|
end
|
|
207
242
|
|
|
208
|
-
erb_render_and_save(d, "#{options[:component_type].downcase}.c", base_folder, out_name:
|
|
243
|
+
erb_render_and_save(d, "#{options[:component_type].downcase}.c", base_folder, out_name: 'main.c')
|
|
209
244
|
erb_render_and_save({ options: options }, 'metababel.h', folder, prefix: '')
|
|
210
245
|
|
|
211
246
|
wrote_component(options, d, folder)
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
require_relative 'bt2_generator_utils'
|
|
2
2
|
|
|
3
|
+
module HashRefinements
|
|
4
|
+
refine Hash do
|
|
5
|
+
def fetch_append(key, item)
|
|
6
|
+
self[key] = fetch(key, []) << item
|
|
7
|
+
item
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
3
12
|
module Babeltrace2Gen
|
|
4
13
|
class GeneratedArg < Struct.new(:type, :name)
|
|
5
14
|
end
|
|
@@ -31,32 +40,22 @@ module Babeltrace2Gen
|
|
|
31
40
|
is_a?(Babeltrace2Gen::BTMemberClass) ? self : @parent.rec_menber_class
|
|
32
41
|
end
|
|
33
42
|
|
|
34
|
-
def
|
|
35
|
-
path.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
def resolve_path(path)
|
|
44
|
+
root, id = path.match(/^(PACKET_CONTEXT|EVENT_COMMON_CONTEXT|EVENT_SPECIFIC_CONTEXT|EVENT_PAYLOAD)\["?(.+)?"\]/).captures
|
|
45
|
+
field_class =
|
|
46
|
+
case root
|
|
47
|
+
when 'PACKET_CONTEXT'
|
|
48
|
+
rec_stream_class.packet_context_field_class
|
|
49
|
+
when 'EVENT_COMMON_CONTEXT'
|
|
50
|
+
rec_stream_class.event_common_context_field_class
|
|
51
|
+
when 'EVENT_SPECIFIC_CONTEXT'
|
|
52
|
+
rec_event_class.specific_context_field_class
|
|
53
|
+
when 'EVENT_PAYLOAD'
|
|
54
|
+
rec_event_class.payload_field_class
|
|
39
55
|
else
|
|
40
|
-
|
|
56
|
+
raise "invalid path #{path}"
|
|
41
57
|
end
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def find_field_class(path, variable)
|
|
46
|
-
m = path.match(/\A(PACKET_CONTEXT|EVENT_COMMON_CONTEXT|EVENT_SPECIFIC_CONTEXT|EVENT_PAYLOAD)(.*)/)
|
|
47
|
-
case m[1]
|
|
48
|
-
when 'PACKET_CONTEXT'
|
|
49
|
-
pr "#{variable} = #{rec_stream_class.packet_context_field_class.variable};"
|
|
50
|
-
when 'EVENT_COMMON_CONTEXT'
|
|
51
|
-
pr "#{variable} = #{rec_stream_class.event_common_context_field_class.variable};"
|
|
52
|
-
when 'EVENT_SPECIFIC_CONTEXT'
|
|
53
|
-
pr "#{variable} = #{rec_event_class.specific_context_field_class.varible};"
|
|
54
|
-
when 'EVENT_PAYLOAD'
|
|
55
|
-
pr "#{variable} = #{rec_event_class.payload_field_class.variable};"
|
|
56
|
-
else
|
|
57
|
-
raise "invalid path #{path}"
|
|
58
|
-
end
|
|
59
|
-
find_field_class_path(m[2], variable)
|
|
58
|
+
[field_class, id]
|
|
60
59
|
end
|
|
61
60
|
end
|
|
62
61
|
|
|
@@ -89,7 +88,8 @@ module Babeltrace2Gen
|
|
|
89
88
|
end
|
|
90
89
|
end
|
|
91
90
|
|
|
92
|
-
def get_declarator(variable:)
|
|
91
|
+
def get_declarator(variable:, self_component:)
|
|
92
|
+
pr "#{variable} = bt_trace_class_create(#{self_component});"
|
|
93
93
|
bt_set_conditionally(@assigns_automatic_stream_class_id) do |v|
|
|
94
94
|
pr "bt_trace_class_set_assigns_automatic_stream_class_id(#{variable}, #{v});"
|
|
95
95
|
end
|
|
@@ -98,7 +98,7 @@ module Babeltrace2Gen
|
|
|
98
98
|
stream_class_name = "#{variable}_sc_#{i}"
|
|
99
99
|
scope do
|
|
100
100
|
pr "bt_stream_class *#{stream_class_name};"
|
|
101
|
-
m.get_declarator(
|
|
101
|
+
m.get_declarator(variable: stream_class_name, self_component: self_component, trace_class: variable)
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
end
|
|
@@ -109,10 +109,15 @@ module Babeltrace2Gen
|
|
|
109
109
|
include BTPrinter
|
|
110
110
|
include BTLocator
|
|
111
111
|
extend BTFromH
|
|
112
|
-
attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :
|
|
112
|
+
attr_reader :packet_context_field_class, :event_common_context_field_class, :event_classes, :default_clock_class,
|
|
113
|
+
:id, :name, :get_getter
|
|
113
114
|
|
|
114
115
|
def initialize(parent:, name: nil, packet_context_field_class: nil, event_common_context_field_class: nil,
|
|
115
|
-
event_classes: [], id: nil, assigns_automatic_event_class_id: nil, assigns_automatic_stream_id: nil
|
|
116
|
+
event_classes: [], id: nil, assigns_automatic_event_class_id: nil, assigns_automatic_stream_id: nil,
|
|
117
|
+
default_clock_class: nil)
|
|
118
|
+
# Handle clock class property:
|
|
119
|
+
# https://babeltrace.org/docs/v2.0/libbabeltrace2/group__api-tir-clock-cls.html#gae0f705eb48cd65784da28b1906ca05a5
|
|
120
|
+
|
|
116
121
|
@parent = parent
|
|
117
122
|
@name = name
|
|
118
123
|
|
|
@@ -137,15 +142,26 @@ module Babeltrace2Gen
|
|
|
137
142
|
end
|
|
138
143
|
@assigns_automatic_stream_id = assigns_automatic_stream_id
|
|
139
144
|
@id = id
|
|
145
|
+
@default_clock_class = default_clock_class
|
|
140
146
|
end
|
|
141
147
|
|
|
142
|
-
def get_declarator(trace_class:,
|
|
148
|
+
def get_declarator(variable:, trace_class:, self_component:)
|
|
143
149
|
if @id
|
|
144
150
|
pr "#{variable} = bt_stream_class_create_with_id(#{trace_class}, #{@id});"
|
|
145
151
|
else
|
|
146
152
|
pr "#{variable} = bt_stream_class_create(#{trace_class});"
|
|
147
153
|
end
|
|
148
154
|
pr "bt_stream_class_set_name(#{variable}, \"#{name}\");" if @name
|
|
155
|
+
if @default_clock_class
|
|
156
|
+
clock_class_name = "#{variable}_dcc"
|
|
157
|
+
scope do
|
|
158
|
+
pr "bt_clock_class *#{clock_class_name};"
|
|
159
|
+
# TODO: @default_clock_class.get_declarator(variable: clock_class_name, self_component: self_component)
|
|
160
|
+
pr "#{clock_class_name} = bt_clock_class_create(#{self_component});"
|
|
161
|
+
pr "bt_stream_class_set_default_clock_class(#{variable}, #{clock_class_name});"
|
|
162
|
+
pr "bt_clock_class_put_ref(#{clock_class_name});"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
149
165
|
|
|
150
166
|
if @packet_context_field_class
|
|
151
167
|
var_pc = "#{variable}_pc_fc"
|
|
@@ -185,7 +201,21 @@ module Babeltrace2Gen
|
|
|
185
201
|
end
|
|
186
202
|
|
|
187
203
|
pr "bt_stream_class_put_ref(#{variable});"
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# The getters code generated from event_common_context_field_class do not include
|
|
207
|
+
# the event variable name used by the getters. As we do not know the variable
|
|
208
|
+
# name that should be generated, we can not put it directly in the template,
|
|
209
|
+
# since, if the code generation generates another name we must update the
|
|
210
|
+
# template in addition.
|
|
211
|
+
def get_getter(event:, arg_variables:)
|
|
212
|
+
return unless event_common_context_field_class
|
|
188
213
|
|
|
214
|
+
field = "#{event}_cc_f"
|
|
215
|
+
scope do
|
|
216
|
+
pr "const bt_field *#{field} = bt_event_borrow_common_context_field_const(#{event});"
|
|
217
|
+
event_common_context_field_class.get_getter(variable: field, arg_variables: arg_variables)
|
|
218
|
+
end
|
|
189
219
|
end
|
|
190
220
|
end
|
|
191
221
|
|
|
@@ -208,7 +238,7 @@ module Babeltrace2Gen
|
|
|
208
238
|
end
|
|
209
239
|
|
|
210
240
|
def get_declarator(trace_class:, variable:, stream_class:)
|
|
211
|
-
# Store the variable name for
|
|
241
|
+
# Store the variable name for instrospection purpose (PATH)
|
|
212
242
|
@variable = variable
|
|
213
243
|
if @id
|
|
214
244
|
pr "#{variable} = bt_event_class_create_with_id(#{stream_class}, #{@id});"
|
|
@@ -228,14 +258,14 @@ module Babeltrace2Gen
|
|
|
228
258
|
end
|
|
229
259
|
end
|
|
230
260
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
261
|
+
return unless @payload_field_class
|
|
262
|
+
|
|
263
|
+
var_name = "#{variable}_p_fc"
|
|
264
|
+
scope do
|
|
265
|
+
pr "bt_field_class *#{var_name};"
|
|
266
|
+
@payload_field_class.get_declarator(trace_class: trace_class, variable: var_name)
|
|
267
|
+
pr "bt_event_class_set_payload_field_class(#{variable}, #{var_name});"
|
|
268
|
+
pr "bt_field_class_put_ref(#{var_name});"
|
|
239
269
|
end
|
|
240
270
|
end
|
|
241
271
|
|
|
@@ -256,12 +286,12 @@ module Babeltrace2Gen
|
|
|
256
286
|
end
|
|
257
287
|
end
|
|
258
288
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
289
|
+
return unless @payload_field_class
|
|
290
|
+
|
|
291
|
+
field = "#{event}_p_f"
|
|
292
|
+
scope do
|
|
293
|
+
pr "bt_field *#{field} = bt_event_borrow_payload_field(#{event});"
|
|
294
|
+
@payload_field_class.get_setter(variable: field, arg_variables: arg_variables)
|
|
265
295
|
end
|
|
266
296
|
end
|
|
267
297
|
|
|
@@ -282,12 +312,12 @@ module Babeltrace2Gen
|
|
|
282
312
|
end
|
|
283
313
|
end
|
|
284
314
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
315
|
+
return unless @payload_field_class
|
|
316
|
+
|
|
317
|
+
field = "#{event}_p_f"
|
|
318
|
+
scope do
|
|
319
|
+
pr "const bt_field *#{field} = bt_event_borrow_payload_field_const(#{event});"
|
|
320
|
+
@payload_field_class.get_getter(variable: field, arg_variables: arg_variables)
|
|
291
321
|
end
|
|
292
322
|
end
|
|
293
323
|
end
|
|
@@ -295,6 +325,7 @@ module Babeltrace2Gen
|
|
|
295
325
|
class BTFieldClass
|
|
296
326
|
include BTLocator
|
|
297
327
|
include BTPrinter
|
|
328
|
+
using HashRefinements
|
|
298
329
|
|
|
299
330
|
attr_accessor :cast_type
|
|
300
331
|
|
|
@@ -338,27 +369,32 @@ module Babeltrace2Gen
|
|
|
338
369
|
raise NotImplementedError, self.class
|
|
339
370
|
end
|
|
340
371
|
|
|
341
|
-
def bt_get_variable(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
372
|
+
def bt_get_variable(arg_variables, is_array: false)
|
|
373
|
+
internal = arg_variables.fetch('internal', [])
|
|
374
|
+
return internal.shift unless internal.empty?
|
|
375
|
+
|
|
376
|
+
type =
|
|
377
|
+
if is_array
|
|
378
|
+
"#{element_field_class.class.instance_variable_get(:@bt_type)}*"
|
|
379
|
+
else
|
|
380
|
+
self.class.instance_variable_get(:@bt_type)
|
|
381
|
+
end
|
|
382
|
+
var = GeneratedArg.new(@cast_type || type, rec_menber_class.name)
|
|
383
|
+
|
|
384
|
+
arg_variables.fetch_append('outputs_allocated', var) if is_array
|
|
385
|
+
arg_variables.fetch_append('outputs', var)
|
|
350
386
|
end
|
|
351
387
|
|
|
352
388
|
def get_getter(field:, arg_variables:)
|
|
353
389
|
bt_func_get = self.class.instance_variable_get(:@bt_func) % 'get'
|
|
354
|
-
variable = bt_get_variable(
|
|
390
|
+
variable = bt_get_variable(arg_variables).name
|
|
355
391
|
cast_func = @cast_type ? "(#{@cast_type})" : ''
|
|
356
392
|
pr "#{variable} = #{cast_func}#{bt_func_get}(#{field});"
|
|
357
393
|
end
|
|
358
394
|
|
|
359
395
|
def get_setter(field:, arg_variables:)
|
|
360
396
|
bt_func_get = self.class.instance_variable_get(:@bt_func) % 'set'
|
|
361
|
-
variable = bt_get_variable(
|
|
397
|
+
variable = bt_get_variable(arg_variables).name
|
|
362
398
|
cast_func = @cast_type ? "(#{self.class.instance_variable_get(:@bt_type)})" : ''
|
|
363
399
|
pr "#{bt_func_get}(#{field}, #{variable});"
|
|
364
400
|
end
|
|
@@ -403,9 +439,9 @@ module Babeltrace2Gen
|
|
|
403
439
|
|
|
404
440
|
def get_declarator(variable:)
|
|
405
441
|
pr "bt_field_class_integer_set_field_value_range(#{variable}, #{@field_value_range});" if @field_value_range
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
442
|
+
return unless @preferred_display_base
|
|
443
|
+
|
|
444
|
+
pr "bt_field_class_integer_set_preferred_display_base(#{variable}, #{@preferred_display_base});"
|
|
409
445
|
end
|
|
410
446
|
end
|
|
411
447
|
|
|
@@ -531,13 +567,14 @@ module Babeltrace2Gen
|
|
|
531
567
|
module WithLengthField
|
|
532
568
|
attr_reader :length_field_path
|
|
533
569
|
end
|
|
570
|
+
using HashRefinements
|
|
534
571
|
|
|
535
572
|
def initialize(parent:, element_field_class:, length_field_path: nil)
|
|
536
573
|
super(parent: parent, element_field_class: element_field_class)
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
574
|
+
return unless length_field_path
|
|
575
|
+
|
|
576
|
+
extend(WithLengthField)
|
|
577
|
+
@length_field_path = length_field_path
|
|
541
578
|
end
|
|
542
579
|
|
|
543
580
|
def get_declarator(trace_class:, variable:)
|
|
@@ -548,13 +585,55 @@ module Babeltrace2Gen
|
|
|
548
585
|
if @length_field_path
|
|
549
586
|
element_field_class_variable_length = "#{element_field_class_variable}_length"
|
|
550
587
|
pr "bt_field_class *#{element_field_class_variable_length};"
|
|
551
|
-
|
|
588
|
+
scope do
|
|
589
|
+
element_field_class_variable_length_sm = "#{element_field_class_variable_length}_sm"
|
|
590
|
+
pr "bt_field_class_structure_member *#{element_field_class_variable_length_sm};"
|
|
591
|
+
field_class, id = resolve_path(@length_field_path)
|
|
592
|
+
id.scan(/(\w+)|(\d+)/).each do |name, index|
|
|
593
|
+
# String
|
|
594
|
+
if name
|
|
595
|
+
pr "#{element_field_class_variable_length_sm} = bt_field_class_structure_borrow_member_by_name(#{field_class.variable}, \"#{name}\");"
|
|
596
|
+
else
|
|
597
|
+
pr "#{element_field_class_variable_length_sm} = bt_field_class_structure_borrow_member_by_index(#{field_class.variable}, #{index});"
|
|
598
|
+
end
|
|
599
|
+
end
|
|
600
|
+
pr "#{element_field_class_variable_length} = bt_field_class_structure_member_borrow_field_class(#{element_field_class_variable_length_sm});"
|
|
601
|
+
end
|
|
552
602
|
pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, #{element_field_class_variable_length});"
|
|
603
|
+
pr "bt_field_class_put_ref(#{element_field_class_variable});"
|
|
553
604
|
else
|
|
554
605
|
pr "#{variable} = bt_field_class_array_dynamic_create(#{trace_class}, #{element_field_class_variable}, NULL);"
|
|
555
606
|
end
|
|
556
607
|
end
|
|
557
608
|
end
|
|
609
|
+
|
|
610
|
+
def get_setter(field:, arg_variables:)
|
|
611
|
+
field_class, id = resolve_path(@length_field_path)
|
|
612
|
+
length_field = field_class[id]
|
|
613
|
+
pr "bt_field_array_dynamic_set_length(#{field}, #{length_field.name});"
|
|
614
|
+
usr_var = bt_get_variable(arg_variables, is_array: true)
|
|
615
|
+
pr "for(uint64_t _i=0; _i < #{length_field.name} ; _i++)"
|
|
616
|
+
scope do
|
|
617
|
+
v = "#{field}_e"
|
|
618
|
+
pr "bt_field* #{v} = bt_field_array_borrow_element_field_by_index(#{field}, _i);"
|
|
619
|
+
arg_variables.fetch_append('internal', GeneratedArg.new('', "#{usr_var.name}[_i]"))
|
|
620
|
+
@element_field_class.get_setter(field: v, arg_variables: arg_variables)
|
|
621
|
+
end
|
|
622
|
+
end
|
|
623
|
+
|
|
624
|
+
def get_getter(field:, arg_variables:)
|
|
625
|
+
length = "#{field}_length"
|
|
626
|
+
pr "uint64_t #{length} = bt_field_array_get_length(#{field});"
|
|
627
|
+
usr_var = bt_get_variable(arg_variables, is_array: true)
|
|
628
|
+
pr "#{usr_var.name} = (#{usr_var.type}) malloc(#{length} * sizeof(#{usr_var.name}));"
|
|
629
|
+
pr "for(uint64_t _i=0; _i < #{length} ; _i++)"
|
|
630
|
+
scope do
|
|
631
|
+
v = "#{field}_e"
|
|
632
|
+
pr "const bt_field* #{v} = bt_field_array_borrow_element_field_by_index_const(#{field}, _i);"
|
|
633
|
+
arg_variables.fetch_append('internal', GeneratedArg.new('', "#{usr_var.name}[_i]"))
|
|
634
|
+
@element_field_class.get_getter(field: v, arg_variables: arg_variables)
|
|
635
|
+
end
|
|
636
|
+
end
|
|
558
637
|
end
|
|
559
638
|
|
|
560
639
|
class BTMemberClass
|
|
@@ -580,10 +659,12 @@ module Babeltrace2Gen
|
|
|
580
659
|
|
|
581
660
|
def [](index)
|
|
582
661
|
case index
|
|
583
|
-
when Integer
|
|
662
|
+
when ::Integer
|
|
584
663
|
@members[index]
|
|
585
|
-
when String
|
|
664
|
+
when ::String
|
|
586
665
|
@members.find { |m| m.name == index }
|
|
666
|
+
else
|
|
667
|
+
raise("Unknow Type (#{index.class}) for index: #{index}")
|
|
587
668
|
end
|
|
588
669
|
end
|
|
589
670
|
|
|
@@ -28,10 +28,10 @@ module Babeltrace2Gen
|
|
|
28
28
|
|
|
29
29
|
# Scalars are leafs, avoid recursion
|
|
30
30
|
def self.from_h(model)
|
|
31
|
-
new(model[:name],model.fetch(:default_value,nil))
|
|
31
|
+
new(model[:name], model.fetch(:default_value, nil))
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
def initialize(name,usr_default_value)
|
|
34
|
+
def initialize(name, usr_default_value)
|
|
35
35
|
@name = name
|
|
36
36
|
@usr_default_value = usr_default_value
|
|
37
37
|
end
|
|
@@ -47,12 +47,12 @@ module Babeltrace2Gen
|
|
|
47
47
|
pr "if (#{val} != NULL) {"
|
|
48
48
|
pr " if (!#{bt_type_is}(#{val})) {"
|
|
49
49
|
pr " fprintf(stderr,\"Bad value for command line argument '%s' the value must be '%s'. \\n\",\"#{@name}\",\"#{bt_type}\");"
|
|
50
|
-
pr
|
|
51
|
-
pr
|
|
50
|
+
pr ' exit(1);'
|
|
51
|
+
pr ' }'
|
|
52
52
|
pr " #{name} = #{cast_func}bt_value_#{bt_type}_get(#{val});"
|
|
53
|
-
pr
|
|
53
|
+
pr '} else {'
|
|
54
54
|
pr " #{name} = #{cast_func}#{default_value};"
|
|
55
|
-
pr
|
|
55
|
+
pr '}'
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
@@ -90,12 +90,13 @@ module Babeltrace2Gen
|
|
|
90
90
|
@bt_return_type = 'bt_bool'
|
|
91
91
|
@bt_default_value = 'BT_FALSE'
|
|
92
92
|
|
|
93
|
-
def initialize(name,usr_default_value)
|
|
93
|
+
def initialize(name, usr_default_value)
|
|
94
94
|
bt_type = self.class.instance_variable_get(:@bt_type)
|
|
95
|
-
if !usr_default_value.nil? and
|
|
95
|
+
if !usr_default_value.nil? and !%w[BT_TRUE BT_FALSE].include? usr_default_value
|
|
96
96
|
raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} (BT_TRUE or BT_FALSE) but provided '#{usr_default_value}'."
|
|
97
97
|
end
|
|
98
|
-
|
|
98
|
+
|
|
99
|
+
super(name, usr_default_value)
|
|
99
100
|
end
|
|
100
101
|
end
|
|
101
102
|
|
|
@@ -105,13 +106,14 @@ module Babeltrace2Gen
|
|
|
105
106
|
@bt_return_type = 'const char*'
|
|
106
107
|
@bt_default_value = 'NULL'
|
|
107
108
|
|
|
108
|
-
def initialize(name,usr_default_value)
|
|
109
|
+
def initialize(name, usr_default_value)
|
|
109
110
|
bt_type = self.class.instance_variable_get(:@bt_type)
|
|
110
111
|
# Every object that can be converted to string is being supported.
|
|
111
112
|
if !usr_default_value.nil? and !usr_default_value.respond_to?(:to_s)
|
|
112
|
-
|
|
113
|
+
raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} but provided '#{usr_default_value}'."
|
|
113
114
|
end
|
|
114
|
-
|
|
115
|
+
|
|
116
|
+
super(name, usr_default_value.to_s.inspect)
|
|
115
117
|
end
|
|
116
118
|
end
|
|
117
119
|
|
|
@@ -121,12 +123,13 @@ module Babeltrace2Gen
|
|
|
121
123
|
@bt_return_type = 'uint64_t'
|
|
122
124
|
@bt_default_value = '0'
|
|
123
125
|
|
|
124
|
-
def initialize(name,usr_default_value)
|
|
126
|
+
def initialize(name, usr_default_value)
|
|
125
127
|
bt_type = self.class.instance_variable_get(:@bt_type)
|
|
126
|
-
if !usr_default_value.nil? and (!usr_default_value.
|
|
127
|
-
|
|
128
|
+
if !usr_default_value.nil? and (!usr_default_value.is_a? Integer or !usr_default_value.between?(0, 2**64 - 1))
|
|
129
|
+
raise "Bad default_value for '#{name}' in params.yaml, it must be #{bt_type} and must be in [0,2^64-1], but provided '#{usr_default_value}'."
|
|
128
130
|
end
|
|
129
|
-
|
|
131
|
+
|
|
132
|
+
super(name, usr_default_value)
|
|
130
133
|
end
|
|
131
134
|
end
|
|
132
135
|
end
|
data/lib/metababel/version.rb
CHANGED
data/template/component.c.erb
CHANGED
data/template/component.h.erb
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
#include "utarray.h"
|
|
4
4
|
#include "uthash.h"
|
|
5
5
|
#include <babeltrace2/babeltrace.h>
|
|
6
|
+
#include <stdbool.h>
|
|
6
7
|
|
|
7
8
|
#ifdef __cplusplus
|
|
8
9
|
extern "C" {
|
|
@@ -83,6 +84,7 @@ typedef enum btx_source_status_e btx_source_status_t;
|
|
|
83
84
|
<% elsif options[:component_type] == 'FILTER' %>
|
|
84
85
|
struct common_data_s {
|
|
85
86
|
name_to_dispatcher_t *name_to_dispatcher;
|
|
87
|
+
name_to_dispatcher_t *name_to_matching_dispatcher;
|
|
86
88
|
void *usr_data;
|
|
87
89
|
const bt_value *params;
|
|
88
90
|
btx_params_t *btx_params;
|
|
@@ -132,6 +134,7 @@ typedef struct btx_message_iterator_s btx_message_iterator_t;
|
|
|
132
134
|
<% elsif options[:component_type] == 'SINK' %>
|
|
133
135
|
struct common_data_s {
|
|
134
136
|
name_to_dispatcher_t *name_to_dispatcher;
|
|
137
|
+
name_to_dispatcher_t *name_to_matching_dispatcher;
|
|
135
138
|
void *usr_data;
|
|
136
139
|
const bt_value *params;
|
|
137
140
|
btx_params_t *btx_params;
|
data/template/downstream.c.erb
CHANGED
|
@@ -37,7 +37,7 @@ void btx_downstream_push_message(
|
|
|
37
37
|
|
|
38
38
|
bt_trace_class *
|
|
39
39
|
btx_downstream_trace_class_create_rec(bt_self_component *self_component) {
|
|
40
|
-
bt_trace_class *trace_class
|
|
40
|
+
bt_trace_class *trace_class;
|
|
41
41
|
<%= body_declarator_classes %>
|
|
42
42
|
return trace_class;
|
|
43
43
|
}
|
|
@@ -108,14 +108,14 @@ void btx_push_messages_stream_end(
|
|
|
108
108
|
|
|
109
109
|
<% downstream_events.each do |e| %>
|
|
110
110
|
static void btx_set_message_<%= e.name_sanitized %>(
|
|
111
|
-
bt_event
|
|
112
|
-
|
|
111
|
+
bt_event *
|
|
112
|
+
<%= event_name %><%= e.args.map{ |s| "#{s.type} #{s.name}" }.join_with_prefix(", ") %>) {
|
|
113
113
|
<%= e.body %>
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
void btx_push_message_<%= e.name_sanitized %>(
|
|
117
|
-
void *
|
|
118
|
-
|
|
117
|
+
void *
|
|
118
|
+
btx_handle<%= ', int64_t _timestamp' if e.default_clock_class %><%= e.args.map{ |s| "#{s.type} #{s.name}" }.join_with_prefix(", ") %>) {
|
|
119
119
|
|
|
120
120
|
common_data_t *common_data = (common_data_t *)btx_handle;
|
|
121
121
|
|
|
@@ -124,13 +124,18 @@ void btx_push_message_<%= e.name_sanitized %>(
|
|
|
124
124
|
bt_stream_class *stream_class = bt_stream_borrow_class(stream);
|
|
125
125
|
bt_event_class *event_class = bt_stream_class_borrow_event_class_by_index(
|
|
126
126
|
stream_class, <%= e.index_event_class %>);
|
|
127
|
-
|
|
127
|
+
<% if !e.default_clock_class %>
|
|
128
128
|
bt_message *message = bt_message_event_create(
|
|
129
129
|
common_data->self_message_iterator, event_class, stream);
|
|
130
|
+
<% else %>
|
|
131
|
+
bt_message *message = bt_message_event_create_with_default_clock_snapshot(
|
|
132
|
+
common_data->self_message_iterator, event_class, stream, _timestamp);
|
|
133
|
+
<% end %>
|
|
134
|
+
|
|
130
135
|
bt_event *downstream_event = bt_message_event_borrow_event(message);
|
|
131
136
|
|
|
132
137
|
btx_set_message_<%= e.name_sanitized %>(
|
|
133
|
-
downstream_event
|
|
138
|
+
downstream_event<%= e.args.map{ |s| s.name }.join_with_prefix(", ") %>);
|
|
134
139
|
|
|
135
140
|
btx_message_iterator_t *message_iterator_private_data =
|
|
136
141
|
bt_self_message_iterator_get_data(common_data->self_message_iterator);
|
data/template/downstream.h.erb
CHANGED
|
@@ -29,8 +29,8 @@ void btx_push_messages_stream_end(
|
|
|
29
29
|
|
|
30
30
|
<% downstream_events.each do |e| %>
|
|
31
31
|
void btx_push_message_<%= e.name_sanitized %>(
|
|
32
|
-
void *
|
|
33
|
-
|
|
32
|
+
void *
|
|
33
|
+
btx_handle<%= ', int64_t _timestamp' if e.default_clock_class %><%= e.args.map{ |s| "#{s.type} #{s.name}" }.join_with_prefix(", ") %>);
|
|
34
34
|
<% end %>
|
|
35
35
|
#ifdef __cplusplus
|
|
36
36
|
}
|
data/template/filter.c.erb
CHANGED
|
@@ -24,10 +24,15 @@ static inline bt_message_iterator_class_next_method_status
|
|
|
24
24
|
filter_message_iterator_next_initializing(
|
|
25
25
|
bt_self_message_iterator *self_message_iterator,
|
|
26
26
|
bt_message_array_const messages, uint64_t capacity, uint64_t *count) {
|
|
27
|
+
|
|
27
28
|
/* Retrieve our private data from the message iterator's user data */
|
|
28
29
|
btx_message_iterator_t *message_iterator_private_data =
|
|
29
30
|
bt_self_message_iterator_get_data(self_message_iterator);
|
|
30
31
|
|
|
32
|
+
/* Begining of Stream */
|
|
33
|
+
btx_push_messages_stream_beginning(self_message_iterator,
|
|
34
|
+
message_iterator_private_data);
|
|
35
|
+
|
|
31
36
|
/* Call Initialize user callback */
|
|
32
37
|
btx_call_callbacks_initialize_usr_data(
|
|
33
38
|
message_iterator_private_data->common_data,
|
|
@@ -100,6 +105,9 @@ filter_message_iterator_next_processing_reading(
|
|
|
100
105
|
btx_call_callbacks_finalize_usr_data(
|
|
101
106
|
message_iterator_private_data->common_data,
|
|
102
107
|
message_iterator_private_data->common_data->usr_data);
|
|
108
|
+
/* End of Stream */
|
|
109
|
+
btx_push_messages_stream_end(self_message_iterator,
|
|
110
|
+
message_iterator_private_data);
|
|
103
111
|
message_iterator_private_data->state = BTX_FILTER_STATE_FINALIZING;
|
|
104
112
|
message_iterator_private_data->processing_state =
|
|
105
113
|
BTX_FILTER_PROCESSING_STATE_FINISHED;
|
|
@@ -125,10 +133,12 @@ filter_message_iterator_next_processing_reading(
|
|
|
125
133
|
upstream_i++) {
|
|
126
134
|
/* Current message */
|
|
127
135
|
const bt_message *upstream_message = upstream_messages[upstream_i];
|
|
128
|
-
/*
|
|
136
|
+
/* Forward all non event-messages downstream */
|
|
129
137
|
if (bt_message_get_type(upstream_message) != BT_MESSAGE_TYPE_EVENT) {
|
|
130
|
-
|
|
138
|
+
btx_downstream_push_message(message_iterator_private_data,
|
|
139
|
+
upstream_message);
|
|
131
140
|
continue;
|
|
141
|
+
|
|
132
142
|
}
|
|
133
143
|
/* Borrow the event message's event and its class */
|
|
134
144
|
const bt_event *event =
|
|
@@ -136,11 +146,35 @@ filter_message_iterator_next_processing_reading(
|
|
|
136
146
|
const bt_event_class *event_class = bt_event_borrow_class_const(event);
|
|
137
147
|
|
|
138
148
|
/* Call dispatcher or forward message downstream */
|
|
139
|
-
|
|
149
|
+
bool is_callback_called = false;
|
|
140
150
|
const char *class_name = bt_event_class_get_name(event_class);
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
151
|
+
|
|
152
|
+
{
|
|
153
|
+
name_to_dispatcher_t *s = NULL;
|
|
154
|
+
HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
|
|
155
|
+
if (s) {
|
|
156
|
+
(*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
|
|
157
|
+
&is_callback_called);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
const bt_stream_class *stream_class =
|
|
163
|
+
bt_event_class_borrow_stream_class_const(event_class);
|
|
164
|
+
const char *stream_class_name = bt_stream_class_get_name(stream_class);
|
|
165
|
+
|
|
166
|
+
name_to_dispatcher_t *s = NULL;
|
|
167
|
+
HASH_FIND_STR(common_data->name_to_matching_dispatcher, stream_class_name,
|
|
168
|
+
s);
|
|
169
|
+
if (s) {
|
|
170
|
+
// is_callback_called will only be modified if at least one callback is
|
|
171
|
+
// called.
|
|
172
|
+
(*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
|
|
173
|
+
&is_callback_called);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (is_callback_called) {
|
|
144
178
|
/* The message have been consumed, we can discard it */
|
|
145
179
|
bt_message_put_ref(upstream_message);
|
|
146
180
|
} else {
|
|
@@ -241,7 +275,7 @@ filter_initialize(bt_self_component_filter *self_component_filter,
|
|
|
241
275
|
|
|
242
276
|
/* Allocate a private data structure */
|
|
243
277
|
common_data_t *common_data = calloc(1, sizeof(common_data_t));
|
|
244
|
-
common_data->btx_params = calloc(1,sizeof(btx_params_t));
|
|
278
|
+
common_data->btx_params = calloc(1, sizeof(btx_params_t));
|
|
245
279
|
common_data->params = params;
|
|
246
280
|
// Read parameters
|
|
247
281
|
btx_populate_params(common_data);
|
|
@@ -379,13 +413,9 @@ static void filter_finalize(bt_self_component_filter *self_component_filter) {
|
|
|
379
413
|
// We allocate it, we need to put ref
|
|
380
414
|
bt_trace_put_ref(common_data->downstream_trace);
|
|
381
415
|
|
|
382
|
-
// Delete
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
HASH_DEL(common_data->name_to_dispatcher, current);
|
|
386
|
-
utarray_free(current->callbacks);
|
|
387
|
-
free(current);
|
|
388
|
-
}
|
|
416
|
+
// Delete name_to_dispatchers
|
|
417
|
+
btx_delete_dispatchers(common_data);
|
|
418
|
+
btx_delete_matching_dispatchers(common_data);
|
|
389
419
|
|
|
390
420
|
// We allocate it, we need to free it
|
|
391
421
|
free(common_data->btx_params);
|
data/template/sink.c.erb
CHANGED
|
@@ -48,24 +48,46 @@ sink_consume(bt_self_component_sink *self_component_sink) {
|
|
|
48
48
|
}
|
|
49
49
|
/* For each consumed message */
|
|
50
50
|
for (uint64_t i = 0; i < message_count; i++) {
|
|
51
|
-
const bt_message *
|
|
52
|
-
if (bt_message_get_type(
|
|
53
|
-
bt_message_put_ref(
|
|
51
|
+
const bt_message *upstream_message = messages[i];
|
|
52
|
+
if (bt_message_get_type(upstream_message) != BT_MESSAGE_TYPE_EVENT) {
|
|
53
|
+
bt_message_put_ref(upstream_message);
|
|
54
54
|
continue;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/* Borrow the event message's event and its class */
|
|
58
|
-
const bt_event *event = bt_message_event_borrow_event_const(
|
|
58
|
+
const bt_event *event = bt_message_event_borrow_event_const(upstream_message);
|
|
59
59
|
const bt_event_class *event_class = bt_event_borrow_class_const(event);
|
|
60
60
|
|
|
61
61
|
/* Call dispatcher */
|
|
62
|
-
|
|
62
|
+
bool is_callback_called = false;
|
|
63
63
|
const char *class_name = bt_event_class_get_name(event_class);
|
|
64
|
-
HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
|
|
65
|
-
if (s)
|
|
66
|
-
(*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, event);
|
|
67
64
|
|
|
68
|
-
|
|
65
|
+
{
|
|
66
|
+
name_to_dispatcher_t *s = NULL;
|
|
67
|
+
HASH_FIND_STR(common_data->name_to_dispatcher, class_name, s);
|
|
68
|
+
if (s) {
|
|
69
|
+
(*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
|
|
70
|
+
&is_callback_called);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
const bt_stream_class *stream_class =
|
|
76
|
+
bt_event_class_borrow_stream_class_const(event_class);
|
|
77
|
+
const char *stream_class_name = bt_stream_class_get_name(stream_class);
|
|
78
|
+
|
|
79
|
+
name_to_dispatcher_t *s = NULL;
|
|
80
|
+
HASH_FIND_STR(common_data->name_to_matching_dispatcher, stream_class_name,
|
|
81
|
+
s);
|
|
82
|
+
if (s) {
|
|
83
|
+
// is_callback_called will only be modified if at least one callback is
|
|
84
|
+
// called.
|
|
85
|
+
(*((dispatcher_t(*))(s->dispatcher)))(s->callbacks, common_data, upstream_message,
|
|
86
|
+
&is_callback_called);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
bt_message_put_ref(upstream_message);
|
|
69
91
|
}
|
|
70
92
|
end:
|
|
71
93
|
return status;
|
|
@@ -80,7 +102,7 @@ sink_initialize(bt_self_component_sink *self_component_sink,
|
|
|
80
102
|
const bt_value *params, void *initialize_method_data) {
|
|
81
103
|
/* Allocate a private data structure */
|
|
82
104
|
common_data_t *common_data = calloc(1, sizeof(common_data_t));
|
|
83
|
-
common_data->btx_params = calloc(1,sizeof(btx_params_t));
|
|
105
|
+
common_data->btx_params = calloc(1, sizeof(btx_params_t));
|
|
84
106
|
common_data->params = params;
|
|
85
107
|
// Read parameters
|
|
86
108
|
btx_populate_params(common_data);
|
|
@@ -122,12 +144,8 @@ static void sink_finalize(bt_self_component_sink *self_component_sink) {
|
|
|
122
144
|
btx_call_callbacks_finalize_usr_data(common_data, common_data->usr_data);
|
|
123
145
|
|
|
124
146
|
// Delete name_to_dispatcher
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
HASH_DEL(common_data->name_to_dispatcher, current);
|
|
128
|
-
utarray_free(current->callbacks);
|
|
129
|
-
free(current);
|
|
130
|
-
}
|
|
147
|
+
btx_delete_dispatchers(common_data);
|
|
148
|
+
btx_delete_matching_dispatchers(common_data);
|
|
131
149
|
|
|
132
150
|
// We allocate it, we need to free it
|
|
133
151
|
free(common_data->btx_params);
|
data/template/source.c.erb
CHANGED
|
@@ -93,7 +93,7 @@ source_initialize(bt_self_component_source *self_component_source,
|
|
|
93
93
|
const bt_value *params, void *initialize_method_data) {
|
|
94
94
|
/* Allocate a private data structure */
|
|
95
95
|
common_data_t *common_data = calloc(1, sizeof(common_data_t));
|
|
96
|
-
common_data->btx_params = calloc(1,sizeof(btx_params_t));
|
|
96
|
+
common_data->btx_params = calloc(1, sizeof(btx_params_t));
|
|
97
97
|
common_data->params = params;
|
|
98
98
|
// Read parameters
|
|
99
99
|
btx_populate_params(common_data);
|
data/template/upstream.c.erb
CHANGED
|
@@ -4,24 +4,44 @@
|
|
|
4
4
|
#include <babeltrace2/babeltrace.h>
|
|
5
5
|
#include <metababel/btx_component.h>
|
|
6
6
|
#include <metababel/btx_upstream.h>
|
|
7
|
+
#include <stdbool.h>
|
|
8
|
+
#include <stdlib.h>
|
|
7
9
|
|
|
8
|
-
<%
|
|
9
|
-
static void
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const bt_event *<%= event_name %>) {
|
|
10
|
+
<% event_class_dispatchers.each do |e| %>
|
|
11
|
+
static void btx_dispatch_<%= e.name_sanitized %>(
|
|
12
|
+
UT_array *callbacks, common_data_t *common_data,
|
|
13
|
+
const bt_message *upstream_message, bool *is_callback_called) {
|
|
13
14
|
|
|
14
15
|
<% e.args.each do |s| %>
|
|
15
16
|
<%= s.type %> <%= s.name %>;
|
|
16
17
|
<% end %>
|
|
17
|
-
|
|
18
|
+
|
|
19
|
+
<%# Since now event is a variable, we need to check if the body will render variables that accesses it. %>
|
|
20
|
+
<% if not e.body.empty? %>
|
|
21
|
+
const bt_event *<%= event_name %> = bt_message_event_borrow_event_const(upstream_message);
|
|
22
|
+
<%= "\n" + e.body %>
|
|
23
|
+
<% end %>
|
|
24
|
+
|
|
25
|
+
<% if e.default_clock_class %>
|
|
26
|
+
int64_t _timestamp;
|
|
27
|
+
const bt_clock_snapshot *clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(upstream_message);
|
|
28
|
+
bt_clock_snapshot_get_ns_from_origin(clock_snapshot, &_timestamp);
|
|
29
|
+
<% end %>
|
|
18
30
|
// Call all the callbacks who where registered
|
|
19
31
|
// Their type are declared in 'upstream.h'
|
|
20
32
|
<%= e.name_sanitized %>_callback_f **p = NULL;
|
|
21
33
|
while ((p = utarray_next(callbacks, p))) {
|
|
22
|
-
(*p)((void *)common_data,
|
|
23
|
-
|
|
34
|
+
(*p)((void *)common_data,
|
|
35
|
+
common_data
|
|
36
|
+
->usr_data<%= ', _timestamp' if e.default_clock_class %><%= e.args.map{ |s| s.name }.join_with_prefix(", ") %>);
|
|
24
37
|
}
|
|
38
|
+
|
|
39
|
+
<% e.args_to_free.each do |s| %>
|
|
40
|
+
<%= "free(#{s.name});" %>
|
|
41
|
+
<% end %>
|
|
42
|
+
|
|
43
|
+
if (callbacks)
|
|
44
|
+
*is_callback_called = true;
|
|
25
45
|
}
|
|
26
46
|
|
|
27
47
|
void btx_register_callbacks_<%= e.name_sanitized %>(
|
|
@@ -45,3 +65,93 @@ void btx_register_callbacks_<%= e.name_sanitized %>(
|
|
|
45
65
|
utarray_push_back(s->callbacks, &callback);
|
|
46
66
|
}
|
|
47
67
|
<% end %>
|
|
68
|
+
|
|
69
|
+
<% stream_classes_matching_dispatchers.each do |s| %>
|
|
70
|
+
void btx_matching_dispatch_<%= s.name_sanitized %>(UT_array *callbacks,
|
|
71
|
+
common_data_t *common_data,
|
|
72
|
+
const bt_message *upstream_message,
|
|
73
|
+
bool *is_callback_called) {
|
|
74
|
+
|
|
75
|
+
<% s.args.each do |a| %>
|
|
76
|
+
<%= a.type %> <%= a.name %>;
|
|
77
|
+
<% end %>
|
|
78
|
+
const bt_event *<%= event_name %> = bt_message_event_borrow_event_const(upstream_message);
|
|
79
|
+
<%= s.body %>
|
|
80
|
+
const bt_event_class *event_class = bt_event_borrow_class_const(<%= event_name %>);
|
|
81
|
+
const char *event_class_name = bt_event_class_get_name(event_class);
|
|
82
|
+
|
|
83
|
+
condition_to_callback_t **p = NULL;
|
|
84
|
+
while ((p = utarray_next(callbacks, p))) {
|
|
85
|
+
<%= s.name_sanitized %>_callback_condition_f *condition =
|
|
86
|
+
(<%= s.name_sanitized %>_callback_condition_f *)((*p)->condition);
|
|
87
|
+
<%= s.name_sanitized %>_conditioned_callback_f *callback =
|
|
88
|
+
(<%= s.name_sanitized %>_conditioned_callback_f *)((*p)->callback);
|
|
89
|
+
<% if s.default_clock_class %>
|
|
90
|
+
int64_t _timestamp;
|
|
91
|
+
const bt_clock_snapshot *clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(upstream_message);
|
|
92
|
+
bt_clock_snapshot_get_ns_from_origin(clock_snapshot, &_timestamp);
|
|
93
|
+
<% end %>
|
|
94
|
+
bool is_condition_met = false;
|
|
95
|
+
condition(
|
|
96
|
+
(void *)common_data, common_data->usr_data, event_class_name,
|
|
97
|
+
&is_condition_met<%= ', _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.name }.join_with_prefix(", ") %>);
|
|
98
|
+
if (is_condition_met) {
|
|
99
|
+
callback(
|
|
100
|
+
(void *)common_data, common_data->usr_data,
|
|
101
|
+
event_class_name<%= ', _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.name }.join_with_prefix(", ") %>);
|
|
102
|
+
*is_callback_called = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void btx_register_matching_callback_<%= s.name_sanitized %>(
|
|
108
|
+
void *btx_handle, <%= s.name_sanitized %>_callback_condition_f *condition,
|
|
109
|
+
<%= s.name_sanitized %>_conditioned_callback_f *callback) {
|
|
110
|
+
// Look-up our dispatcher
|
|
111
|
+
name_to_dispatcher_t *s = NULL;
|
|
112
|
+
name_to_dispatcher_t **name_to_matching_dispatcher =
|
|
113
|
+
&((common_data_t *)btx_handle)->name_to_matching_dispatcher;
|
|
114
|
+
HASH_FIND_STR(*name_to_matching_dispatcher, "<%= s.name_sanitized %>", s);
|
|
115
|
+
if (!s) {
|
|
116
|
+
// We didn't find the dispatcher, so we need to:
|
|
117
|
+
// 1. Create it
|
|
118
|
+
s = (name_to_dispatcher_t *)malloc(sizeof(name_to_dispatcher_t));
|
|
119
|
+
s->name = "<%= s.name_sanitized %>";
|
|
120
|
+
s->dispatcher = (void *)&btx_matching_dispatch_<%= s.name_sanitized %>;
|
|
121
|
+
utarray_new(s->callbacks, &ut_ptr_icd);
|
|
122
|
+
// 2. Register it
|
|
123
|
+
HASH_ADD_KEYPTR(hh, *name_to_matching_dispatcher, s->name, strlen(s->name),
|
|
124
|
+
s);
|
|
125
|
+
}
|
|
126
|
+
// Add the callbacks to the array
|
|
127
|
+
condition_to_callback_t *m =
|
|
128
|
+
(condition_to_callback_t *)malloc(sizeof(condition_to_callback_t));
|
|
129
|
+
m->condition = (void *)condition;
|
|
130
|
+
m->callback = (void *)callback;
|
|
131
|
+
utarray_push_back(s->callbacks, &m);
|
|
132
|
+
}
|
|
133
|
+
<% end %>
|
|
134
|
+
|
|
135
|
+
void btx_delete_dispatchers(common_data_t *common_data) {
|
|
136
|
+
name_to_dispatcher_t *current, *tmp;
|
|
137
|
+
HASH_ITER(hh, common_data->name_to_dispatcher, current, tmp) {
|
|
138
|
+
HASH_DEL(common_data->name_to_dispatcher, current);
|
|
139
|
+
utarray_free(current->callbacks);
|
|
140
|
+
free(current);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
void btx_delete_matching_dispatchers(common_data_t *common_data) {
|
|
145
|
+
name_to_dispatcher_t *current, *tmp;
|
|
146
|
+
HASH_ITER(hh, common_data->name_to_matching_dispatcher, current, tmp) {
|
|
147
|
+
// Removes the item from the hash table.
|
|
148
|
+
HASH_DEL(common_data->name_to_matching_dispatcher, current);
|
|
149
|
+
// Deletes every condition, callback pair.
|
|
150
|
+
condition_to_callback_t **p = NULL;
|
|
151
|
+
while ((p = utarray_next(current->callbacks, p))) {
|
|
152
|
+
free(*p);
|
|
153
|
+
}
|
|
154
|
+
utarray_free(current->callbacks);
|
|
155
|
+
free(current);
|
|
156
|
+
}
|
|
157
|
+
}
|
data/template/upstream.h.erb
CHANGED
|
@@ -6,17 +6,47 @@ extern "C" {
|
|
|
6
6
|
|
|
7
7
|
// Dispatcher
|
|
8
8
|
typedef void(dispatcher_t)(UT_array *callbacks, common_data_t *common_data,
|
|
9
|
-
const
|
|
9
|
+
const bt_message *upstream_message, bool *is_callback_called);
|
|
10
10
|
|
|
11
|
-
<%
|
|
11
|
+
<% event_class_dispatchers.each do |e| %>
|
|
12
12
|
<%# The signature type of callbacks %>
|
|
13
|
-
typedef void
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
typedef void <%= e.name_sanitized %>_callback_f(
|
|
14
|
+
void *btx_handle,
|
|
15
|
+
void *usr_data<%= ', int64_t _timestamp' if e.default_clock_class %><%= e.args.map{ |s| s.type }.join_with_prefix(", ") %>);
|
|
16
16
|
<%# The Function who register the callbacks to the dispatcher %>
|
|
17
|
-
|
|
17
|
+
void btx_register_callbacks_<%= e.name_sanitized %>(
|
|
18
18
|
void *btx_handle, <%= e.name_sanitized %>_callback_f *callback);
|
|
19
19
|
<% end %>
|
|
20
|
+
|
|
21
|
+
void btx_delete_dispatchers(common_data_t *common_data);
|
|
22
|
+
|
|
23
|
+
// Matching dispatcher
|
|
24
|
+
|
|
25
|
+
struct condition_to_callback_s {
|
|
26
|
+
void *condition;
|
|
27
|
+
void *callback;
|
|
28
|
+
};
|
|
29
|
+
typedef struct condition_to_callback_s condition_to_callback_t;
|
|
30
|
+
|
|
31
|
+
<% stream_classes_matching_dispatchers.each do |s| %>
|
|
32
|
+
<%# The signature type of condition callbacks %>
|
|
33
|
+
typedef void <%= s.name_sanitized %>_callback_condition_f(
|
|
34
|
+
void *btx_handle, void *usr_data, const char *event_class_name,
|
|
35
|
+
bool *matched<%= ', int64_t _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.type }.join_with_prefix(", ") %>);
|
|
36
|
+
|
|
37
|
+
<%# The signature type of callbacks to be called if the condition is met %>
|
|
38
|
+
typedef void <%= s.name_sanitized %>_conditioned_callback_f(
|
|
39
|
+
void *btx_handle, void *usr_data,
|
|
40
|
+
const char *
|
|
41
|
+
event_class_name<%= ', int64_t _timestamp' if s.default_clock_class %><%= s.args.map{ |a| a.type }.join_with_prefix(", ") %>);
|
|
42
|
+
|
|
43
|
+
void btx_register_matching_callback_<%= s.name_sanitized %>(
|
|
44
|
+
void *btx_handle, <%= s.name_sanitized %>_callback_condition_f *condition,
|
|
45
|
+
<%= s.name_sanitized %>_conditioned_callback_f *callback);
|
|
46
|
+
<% end %>
|
|
47
|
+
|
|
48
|
+
void btx_delete_matching_dispatchers(common_data_t *common_data);
|
|
49
|
+
|
|
20
50
|
#ifdef __cplusplus
|
|
21
51
|
}
|
|
22
52
|
#endif
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metababel
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas Applencourt
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2023-
|
|
13
|
+
date: 2023-06-26 00:00:00.000000000 Z
|
|
14
14
|
dependencies: []
|
|
15
15
|
description:
|
|
16
16
|
email:
|
|
@@ -55,8 +55,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
55
55
|
- !ruby/object:Gem::Version
|
|
56
56
|
version: '0'
|
|
57
57
|
requirements: []
|
|
58
|
-
|
|
59
|
-
rubygems_version: 2.7.6.3
|
|
58
|
+
rubygems_version: 3.3.3
|
|
60
59
|
signing_key:
|
|
61
60
|
specification_version: 4
|
|
62
61
|
summary: Helper for creation Babeltrace plugins
|