Commit 9bdf7ca1 authored by Brice Videau's avatar Brice Videau
Browse files

Dispatcher and callback signatures generated from ze_babeltrace_model.yaml.

parent cf590b29
Pipeline #12972 failed with stage
......@@ -24,6 +24,14 @@ EOF
when 'unsigned', 'enumeration_unsigned'
puts <<EOF
#{name} = (#{type})bt_field_integer_unsigned_get_value(_field);
EOF
when 'float'
puts <<EOF
#{name} = (#{type})bt_field_real_single_precision_get_value(_field);
EOF
when 'double'
puts <<EOF
#{name} = (#{type})bt_field_real_double_precision_get_value(_field);
EOF
when 'array_static'
scalar_type = type.gsub("const","").sub("*", "")
......@@ -113,18 +121,22 @@ static void
EOF
print_field_members_access(fields)
puts <<EOF
void **p = NULL;
while( (p = utarray_next(callbacks->callbacks, p)) ) {
((#{name.gsub(":","_")}_cb *)*p)(
void **_p = NULL;
while( (_p = utarray_next(callbacks->callbacks, _p)) ) {
((#{name.gsub(":","_")}_cb *)*_p)(
#{(["bt_evt", "bt_clock"] + decls.collect { |f| f[1] }).join(",\n ")});
}
EOF
puts <<EOF if fields.find { |f| f[:class].match('array') }
#{fields.each.collect { |f|
if f[:class].match('array')
"if (#{f[:name]}) free((void *)#{f[:name]})"
"free((void *)#{f[:name]})"
else
nil
end
}.compact.join(";\n ")};
EOF
puts <<EOF
}
EOF
......
require_relative 'gen_ze_library_base.rb'
require 'yaml'
ze_babeltrace_model = YAML::load_file("ze_babeltrace_model.yaml")
puts <<EOF
#ifndef _BABELTRACE_ZE_CALLBACKS_H
#define _BABELTRACE_ZE_CALLBACKS_H
#include <ze_api.h>
#include <ze_ddi.h>
#include <zet_api.h>
......@@ -13,119 +17,23 @@ puts <<EOF
EOF
meta_parameter_lambda = lambda { |m, dir|
if dir == :start
lttng = m.lttng_in_type
else
lttng = m.lttng_out_type
end
name = lttng.name
t = m.command[m.name].type.type
case m
when ScalarMetaParameter
if lttng.length
["size_t _#{name}_length", "#{t} *#{name}"]
else
"#{t} #{name}"
end
when ArrayMetaParameter, InString, OutString
if lttng.macro.to_s == "ctf_string"
"#{t} *#{name}"
else
["size_t _#{name}_length", "#{t} *#{name}"]
end
end
}
gen_event_callback = lambda { |provider, c, dir|
puts <<EOF
typedef void (#{provider}_#{c.name}_#{SUFFIXES[dir]}_cb)(
EOF
fields = ["const bt_event *bt_evt",
"const bt_clock_snapshot *bt_clock"]
if dir == :start
fields += ((c.parameters ? c.parameters : [] )+c.tracepoint_parameters).collect { |p|
p.to_s
}
fields += c.meta_parameters.select { |m| m.kind_of?(In) }.collect { |m|
meta_parameter_lambda.call(m, :start)
}
else
fields.push "ze_result_t #{RESULT_NAME}"
fields += c.meta_parameters.select { |m| m.kind_of?(Out) }.collect { |m|
meta_parameter_lambda.call(m, :stop)
}
end
fields.flatten!
puts <<EOF
#{fields.join(",\n ")}
EOF
ze_babeltrace_model[:event_classes].each { |klass|
name = klass[:name]
fields = klass[:payload]
decls = []
fields.each { |f|
decls.push ['size_t', "_#{f[:name]}_length"] if f[:class] == 'array_static'
decls.push [f[:cast_type], f[:name]]
}
puts <<EOF
typedef void (#{name.gsub(":","_")}_cb)(
#{(["const bt_event *bt_evt", "const bt_clock_snapshot *bt_clock"]+
decls.collect { |t, n| "#{t} #{n}" }).join(",\n ")}
);
EOF
}
gen_extra_event_callback =lambda { |provider, event|
puts <<EOF
typedef void (#{provider}_#{event["name"]}_cb)(
EOF
fields = ["const bt_event *bt_evt",
"const bt_clock_snapshot *bt_clock"]
args = event["args"].collect { |arg| arg.reverse }.to_h
event["fields"].each { |field|
lttng = LTTng::TracepointField::new(*field)
name = lttng.name
type = lttng.type
if name.match(/_val\z/)
n = name.sub(/_val\z/,"")
fields.push "size_t _#{name}_length"
type = args[n] if args[n]
else
type = args[name] if args[name]
end
fields.push "#{type} #{name}"
}
puts <<EOF
#{fields.join(",\n ")}
EOF
puts <<EOF
);
puts <<EOF
#endif
EOF
}
provider = :lttng_ust_ze
$ze_commands.each { |c|
gen_event_callback.call(provider, c, :start)
gen_event_callback.call(provider, c, :stop)
}
provider = :lttng_ust_zet
$zet_commands.each { |c|
gen_event_callback.call(provider, c, :start)
gen_event_callback.call(provider, c, :stop)
}
provider = :lttng_ust_zes
$zes_commands.each { |c|
gen_event_callback.call(provider, c, :start)
gen_event_callback.call(provider, c, :stop)
}
provider = :lttng_ust_zel
$zel_commands.each { |c|
gen_event_callback.call(provider, c, :start)
gen_event_callback.call(provider, c, :stop)
}
ze_events = YAML::load_file(File.join(SRC_DIR,"ze_events.yaml"))
ze_events.each { |provider, es|
es["events"].each { |event|
gen_extra_event_callback.call(provider, event)
}
}
require_relative 'gen_ze_library_base.rb'
require 'yaml'
ze_babeltrace_model = YAML::load_file("ze_babeltrace_model.yaml")
puts <<EOF
#include <ze_api.h>
#include <ze_ddi.h>
#include <zet_api.h>
#include <zet_ddi.h>
#include <zes_api.h>
#include <zes_ddi.h>
#include <layers/zel_tracing_api.h>
#include <layers/zel_tracing_ddi.h>
#include <babeltrace2/babeltrace.h>
#include "babeltrace_ze.h"
#include "babeltrace_ze_callbacks.h"
EOF
def print_field_member_access(lttng, type, name, i, array_type: nil)
def print_field_member_access(f, i)
klass = f[:class]
name = f[:name]
type = f[:cast_type]
puts <<EOF
{
const bt_field *_field = NULL;
_field = bt_field_structure_borrow_member_field_by_index_const(payload_field, #{i});
EOF
case lttng
when "ctf_float"
case klass
when 'signed', 'enumeration_signed'
puts <<EOF
bt_field_class_type _type = bt_field_get_class_type(_field);
if (bt_field_class_type_is(_type, BT_FIELD_CLASS_TYPE_SINGLE_PRECISION_REAL))
#{name} = (#{type})bt_field_real_single_precision_get_value(_field);
else
#{name} = (#{type})bt_field_real_double_precision_get_value(_field);
#{name} = (#{type})bt_field_integer_signed_get_value(_field);
EOF
when "ctf_integer", "ctf_integer_hex", "ctf_enum"
when 'unsigned', 'enumeration_unsigned'
puts <<EOF
bt_field_class_type _type = bt_field_get_class_type(_field);
if (bt_field_class_type_is(_type, BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER))
#{name} = (#{type})bt_field_integer_unsigned_get_value(_field);
#{name} = (#{type})bt_field_integer_unsigned_get_value(_field);
EOF
when 'float'
puts <<EOF
#{name} = (#{type})bt_field_real_single_precision_get_value(_field);
EOF
when 'double'
puts <<EOF
#{name} = (#{type})bt_field_real_double_precision_get_value(_field);
EOF
when 'array_static'
scalar_type = type.gsub("const","").sub("*", "")
voidp = false
if scalar_type.strip == "void"
voidp = true
scalar_type = "uint8_t"
end
puts <<EOF
_#{name}_length = bt_field_array_get_length(_field);
if (_#{name}_length > 0) {
#{name} = (#{type})malloc(_#{name}_length*sizeof(#{scalar_type}));
for (uint64_t _i = 0; _i < _#{name}_length; _i++) {
EOF
case f[:field][:class]
when 'unsigned'
puts <<EOF
#{voidp ? "((uint8_t *)#{name})" : name}[_i] = (#{scalar_type})bt_field_integer_unsigned_get_value(bt_field_array_borrow_element_field_by_index_const(_field, _i));
EOF
when 'signed'
puts <<EOF
#{voidp ? "((uint8_t *)#{name})" : name}[_i] = (#{scalar_type})bt_field_integer_signed_get_value(bt_field_array_borrow_element_field_by_index_const(_field, _i));
EOF
else
#{name} = (#{type})bt_field_integer_signed_get_value(_field);
raise "unsupported array element #{f[:field][:class]}"
end
puts <<EOF
}
} else
#{name} = NULL;
EOF
when "ctf_sequence", "ctf_sequence_hex", "ctf_array"
scalar_type = array_type
when 'array_dynamic'
scalar_type = type.gsub("const","").sub("*", "")
voidp = false
if scalar_type.strip == "void"
voidp = true
scalar_type = "uint8_t"
end
puts <<EOF
uint64_t _sz = bt_field_array_get_length(_field);
if (_sz > 0) {
bt_field_class_type _type = bt_field_get_class_type(bt_field_array_borrow_element_field_by_index_const(_field, 0));
#{name} = (#{type})malloc(_sz*sizeof(#{scalar_type}));
for (uint64_t _i = 0; _i < _sz; _i++) {
if (bt_field_class_type_is(_type, BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER))
((#{scalar_type} *)#{name})[_i] = (#{scalar_type})bt_field_integer_unsigned_get_value(bt_field_array_borrow_element_field_by_index_const(_field, _i));
else
((#{scalar_type} *)#{name})[_i] = (#{scalar_type})bt_field_integer_signed_get_value(bt_field_array_borrow_element_field_by_index_const(_field, _i));
EOF
case f[:field][:class]
when 'unsigned'
puts <<EOF
#{voidp ? "((uint8_t *)#{name})" : name}[_i] = (#{scalar_type})bt_field_integer_unsigned_get_value(bt_field_array_borrow_element_field_by_index_const(_field, _i));
EOF
when 'signed'
puts <<EOF
#{voidp ? "((uint8_t *)#{name})" : name}[_i] = (#{scalar_type})bt_field_integer_signed_get_value(bt_field_array_borrow_element_field_by_index_const(_field, _i));
EOF
else
raise "unsupported array element #{f[:field][:class]}"
end
puts <<EOF
}
} else
#{name} = NULL;
EOF
when "ctf_sequence_text", "ctf_string", "ctf_array_text"
when 'string'
if !type.to_s.match(/\*/)
puts <<EOF
puts <<EOF
if (bt_field_string_get_value(_field))
memcpy(&#{name}, bt_field_string_get_value(_field), sizeof(#{name}));
EOF
......@@ -65,344 +105,72 @@ EOF
EOF
end
else
raise "unsupported data type #{lttng.inspect}"
raise "unsupported babeltrace_type: #{klass}"
end
puts <<EOF
}
EOF
end
def print_field_member_free(lttng, name)
case lttng
when "ctf_sequence", "ctf_sequence_hex", "ctf_array"
puts <<EOF
free((void*)#{name});
def print_field_members_access(fields)
puts <<EOF unless fields.empty?
const bt_field *payload_field = bt_event_borrow_payload_field_const(bt_evt);
EOF
end
end
def get_lttng_type(m, dir)
if dir == :start
lttng = m.lttng_in_type
else
lttng = m.lttng_out_type
end
end
def print_meta_parameter_field_members_free(m, dir)
lttng = get_lttng_type(m, dir)
name = lttng.name
print_field_member_free(lttng.macro.to_s, name.to_s)
end
def print_field_members_free(c, dir)
if dir == :start
((c.parameters ? c.parameters : []) + c.tracepoint_parameters).each { |p|
lttng = p.lttng_type
print_field_member_free(lttng.macro.to_s, p.name)
}
c.meta_parameters.select { |m| m.kind_of?(In) }.each { |m|
print_meta_parameter_field_members_free(m, dir)
}
else
c.meta_parameters.select { |m| m.kind_of?(Out) }.each { |m|
print_meta_parameter_field_members_free(m, dir)
}
end
end
def print_meta_parameter_field_members_access(m, dir, i)
lttng = get_lttng_type(m, dir)
name = lttng.name
t = m.command[m.name].type.type
case m
when ScalarMetaParameter
if lttng.length
print_field_member_access("ctf_integer", "size_t", "_#{name}_length", i)
i += 1
print_field_member_access(lttng.macro.to_s, "#{t} *", "#{name}", i, array_type: lttng.type.to_s)
i += 1
else
print_field_member_access(lttng.macro.to_s, "#{t}", "#{name}", i)
i += 1
end
when ArrayMetaParameter, InString, OutString
unless lttng.macro.to_s == "ctf_string"
print_field_member_access("ctf_integer", "size_t", "_#{name}_length", i)
i += 1
end
print_field_member_access(lttng.macro.to_s, "#{t} *", "#{name}", i, array_type: lttng.type.to_s)
i += 1
end
return i
end
def print_field_members_access(c, dir)
if dir == :start
i = 0
((c.parameters ? c.parameters : []) + c.tracepoint_parameters).each { |p|
lttng = p.lttng_type
print_field_member_access(lttng.macro.to_s, p.type, p.name, i)
i += 1;
}
c.meta_parameters.select { |m| m.kind_of?(In) }.each { |m|
i = print_meta_parameter_field_members_access(m, dir, i)
}
else
i = 0
print_field_member_access("ctf_integer", "ze_result_t", "#{RESULT_NAME}", i)
i += 1
c.meta_parameters.select { |m| m.kind_of?(Out) }.each { |m|
i = print_meta_parameter_field_members_access(m, dir, i)
}
end
end
def meta_parameter_name(m, dir)
if dir == :start
lttng = m.lttng_in_type
else
lttng = m.lttng_out_type
end
name = lttng.name
t = m.command[m.name].type.type
case m
when ScalarMetaParameter
if lttng.length
["_#{name}_length", "#{name}"]
else
"#{name}"
end
when ArrayMetaParameter, InString, OutString
if lttng.macro.to_s == "ctf_string"
"#{name}"
else
["_#{name}_length", "#{name}"]
end
end
end
def meta_parameter_decl(m, dir)
if dir == :start
lttng = m.lttng_in_type
else
lttng = m.lttng_out_type
end
name = lttng.name
t = m.command[m.name].type.type
case m
when ScalarMetaParameter
if lttng.length
["size_t _#{name}_length;", "#{t} *#{name};"]
else
"#{t} #{name};"
end
when ArrayMetaParameter, InString, OutString
if lttng.macro.to_s == "ctf_string"
"#{t} *#{name};"
else
["size_t _#{name}_length;", "#{t} *#{name};"]
end
end
end
def get_fields_decl(c, dir)
if dir == :start
fields = ((c.parameters ? c.parameters : []) + c.tracepoint_parameters).collect { |p|
p.to_s + ";"
}
fields += c.meta_parameters.select { |m| m.kind_of?(In) }.collect { |m|
meta_parameter_decl(m, :start)
}
else
fields = ["ze_result_t #{RESULT_NAME};"]
fields += c.meta_parameters.select { |m| m.kind_of?(Out) }.collect { |m|
meta_parameter_decl(m, :stop)
}
end
fields.flatten!
fields
end
def get_fields_names(c, dir)
if dir == :start
fields = ((c.parameters ? c.parameters : []) + c.tracepoint_parameters).collect { |p|
p.name.to_s
}
fields += c.meta_parameters.select { |m| m.kind_of?(In) }.collect { |m|
meta_parameter_name(m, :start)
}
else
fields = ["#{RESULT_NAME}"]
fields += c.meta_parameters.select { |m| m.kind_of?(Out) }.collect { |m|
meta_parameter_name(m, :stop)
}
end
fields.flatten!
fields
fields.each_with_index { |f, i|
print_field_member_access(f, i)
}
end
gen_event_dispatcher = lambda { |provider, c, dir|
puts <<EOF
static void
#{provider}_#{c.name}_#{SUFFIXES[dir]}_dispatcher(
struct ze_dispatch *ze_dispatch,
struct ze_callbacks *callbacks,
const bt_event *bt_evt,
const bt_clock_snapshot *bt_clock) {
EOF
fields = get_fields_decl(c, dir)
puts <<EOF unless fields.empty?
const bt_field *payload_field = bt_event_borrow_payload_field_const(bt_evt);
#{fields.join("\n ")}
EOF
print_field_members_access(c, dir)
puts <<EOF
void **_p = NULL;
while( (_p = utarray_next(callbacks->callbacks, _p)) ) {
((#{provider}_#{c.name}_#{SUFFIXES[dir]}_cb *)*_p)(
#{(["bt_evt", "bt_clock"] + get_fields_names(c, dir)).join(",\n ")});
ze_babeltrace_model[:event_classes].each { |klass|
name = klass[:name]
fields = klass[:payload]
decls = []
fields.each { |f|
decls.push ['size_t', "_#{f[:name]}_length"] if f[:class] == 'array_static'
decls.push [f[:cast_type], f[:name]]
}
EOF
print_field_members_free(c, dir)
puts <<EOF
}
EOF
}
gen_extra_event_dispatcher = lambda { |provider, event|
args = event["args"].collect { |arg| arg.reverse }.to_h
lttng_fields = event["fields"].collect { |field|
LTTng::TracepointField::new(*field)
}
param_fields = []
lttng_fields.each { |lttng|
name = lttng.name
type = lttng.type
if name.match(/_val\z/)
n = name.sub(/_val\z/,"")
param_fields.push ["ctf_integer", "size_t", "_#{name}_length"]
type = args[n] if args[n]
else
type = args[name] if args[name]
end
param_fields.push [lttng.macro.to_s, type.to_s, name.to_s]
}
fields_decl = []
param_fields.each { |param_field|
fields_decl.push "#{param_field[1]} #{param_field[2]}"
}
puts <<EOF
static void
#{provider}_#{event["name"]}_dispatcher(
#{name.gsub(":","_")}_dispatcher(
struct ze_dispatch *ze_dispatch,
struct ze_callbacks *callbacks,
const bt_event *bt_evt,
const bt_clock_snapshot *bt_clock) {
const bt_field *payload_field = bt_event_borrow_payload_field_const(bt_evt);
#{fields_decl.join(";\n ")};
#{decls.each.collect { |f| "#{f[0]} #{f[1]}" }.join(";\n ")};
EOF
param_fields.each_with_index { |param_field, i|
print_field_member_access(param_field[0], param_field[1], param_field[2], i)
}
puts <<EOF
print_field_members_access(fields)
puts <<EOF
void **_p = NULL;
while( (_p = utarray_next(callbacks->callbacks, _p)) ) {
((#{provider}_#{event["name"]}_cb *)*_p)(
#{(["bt_evt", "bt_clock"] + param_fields.collect { |param_field| param_field[2] }).join(",\n ")});
((#{name.gsub(":","_")}_cb *)*_p)(
#{(["bt_evt", "bt_clock"] + decls.collect { |f| f[1] }).join(",\n ")});
}
EOF
puts <<EOF
}