summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
8812e92)
A common use-case for sequences is to use the field located immediately
prior to the sequence as sequence length.
The fact that the sequence type needs to explicitly contain its length
name ties the sequence type to where it is placed within the structure
fields, preventing re-use of the sequence type.
In order to reduce the memory footprint of the field descriptions and
allow re-use of common field types, special-case the NULL length_name to
use the field prior to the sequence as length.
This allows more efficient type descriptions without reducing the
overall flexibility of sequence layout.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I5f2ae22ecc4d872d56f9302751990452fc34cb15
struct lttng_ust_type_sequence {
struct lttng_ust_type_common parent;
uint32_t struct_size;
struct lttng_ust_type_sequence {
struct lttng_ust_type_common parent;
uint32_t struct_size;
- const char *length_name; /* Length field name. */
+ const char *length_name; /* Length field name. If NULL, use previous field. */
const struct lttng_ust_type_common *elem_type;
unsigned int alignment; /* Minimum alignment before elements. */
enum lttng_ust_string_encoding encoding;
const struct lttng_ust_type_common *elem_type;
unsigned int alignment; /* Minimum alignment before elements. */
enum lttng_ust_string_encoding encoding;
.type = lttng_ust_type_sequence, \
}, \
.struct_size = sizeof(struct lttng_ust_type_sequence), \
.type = lttng_ust_type_sequence, \
}, \
.struct_size = sizeof(struct lttng_ust_type_sequence), \
- .length_name = "_" #_item "_length", \
+ .length_name = NULL, /* Use previous field. */ \
.elem_type = lttng_ust_type_integer_define(_type, _byte_order, _elem_type_base), \
.alignment = 0, \
.encoding = lttng_ust_string_encoding_##_encoding, \
.elem_type = lttng_ust_type_integer_define(_type, _byte_order, _elem_type_base), \
.alignment = 0, \
.encoding = lttng_ust_string_encoding_##_encoding, \
static
int serialize_one_field(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *fields, size_t *iter_output,
static
int serialize_one_field(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *fields, size_t *iter_output,
- const struct lttng_ust_event_field *lf);
+ const struct lttng_ust_event_field *lf,
+ const char **prev_field_name);
static
int serialize_fields(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *lttng_ust_ctl_fields,
static
int serialize_fields(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *lttng_ust_ctl_fields,
LTTNG_UST_ABI_SYM_NAME_LEN - strlen(tag_field_name) - 1);
tag_field.type = tag_type;
ret = serialize_one_field(session, fields, iter_output,
LTTNG_UST_ABI_SYM_NAME_LEN - strlen(tag_field_name) - 1);
tag_field.type = tag_type;
ret = serialize_one_field(session, fields, iter_output,
/* Serialize choice fields after variant. */
for (i = 0; i < nr_choices; i++) {
ret = serialize_one_field(session, fields,
/* Serialize choice fields after variant. */
for (i = 0; i < nr_choices; i++) {
ret = serialize_one_field(session, fields,
- iter_output, choices[i]);
+ iter_output, choices[i], NULL);
int serialize_one_type(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *fields, size_t *iter_output,
const char *field_name, const struct lttng_ust_type_common *lt,
int serialize_one_type(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *fields, size_t *iter_output,
const char *field_name, const struct lttng_ust_type_common *lt,
- enum lttng_ust_string_encoding parent_encoding)
+ enum lttng_ust_string_encoding parent_encoding,
+ const char *prev_field_name)
ret = serialize_one_type(session, fields, iter_output, NULL,
lttng_ust_get_type_array(lt)->elem_type,
ret = serialize_one_type(session, fields, iter_output, NULL,
lttng_ust_get_type_array(lt)->elem_type,
- lttng_ust_get_type_array(lt)->encoding);
+ lttng_ust_get_type_array(lt)->encoding, NULL);
if (ret)
return -EINVAL;
break;
if (ret)
return -EINVAL;
break;
{
struct lttng_ust_ctl_field *uf = &fields[*iter_output];
struct lttng_ust_ctl_type *ut = &uf->type;
{
struct lttng_ust_ctl_field *uf = &fields[*iter_output];
struct lttng_ust_ctl_type *ut = &uf->type;
+ const char *length_name = lttng_ust_get_type_sequence(lt)->length_name;
if (field_name) {
strncpy(uf->name, field_name, LTTNG_UST_ABI_SYM_NAME_LEN);
if (field_name) {
strncpy(uf->name, field_name, LTTNG_UST_ABI_SYM_NAME_LEN);
uf->name[0] = '\0';
}
ut->atype = lttng_ust_ctl_atype_sequence_nestable;
uf->name[0] = '\0';
}
ut->atype = lttng_ust_ctl_atype_sequence_nestable;
+ /*
+ * If length_name field is NULL, use the previous field
+ * as length.
+ */
+ if (!length_name)
+ length_name = prev_field_name;
+ if (!length_name)
+ return -EINVAL;
strncpy(ut->u.sequence_nestable.length_name,
strncpy(ut->u.sequence_nestable.length_name,
- lttng_ust_get_type_sequence(lt)->length_name,
- LTTNG_UST_ABI_SYM_NAME_LEN);
+ length_name, LTTNG_UST_ABI_SYM_NAME_LEN);
ut->u.sequence_nestable.length_name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
ut->u.sequence_nestable.alignment = lttng_ust_get_type_sequence(lt)->alignment;
(*iter_output)++;
ret = serialize_one_type(session, fields, iter_output, NULL,
lttng_ust_get_type_sequence(lt)->elem_type,
ut->u.sequence_nestable.length_name[LTTNG_UST_ABI_SYM_NAME_LEN - 1] = '\0';
ut->u.sequence_nestable.alignment = lttng_ust_get_type_sequence(lt)->alignment;
(*iter_output)++;
ret = serialize_one_type(session, fields, iter_output, NULL,
lttng_ust_get_type_sequence(lt)->elem_type,
- lttng_ust_get_type_sequence(lt)->encoding);
+ lttng_ust_get_type_sequence(lt)->encoding, NULL);
if (ret)
return -EINVAL;
break;
if (ret)
return -EINVAL;
break;
ret = serialize_one_type(session, fields, iter_output, NULL,
lttng_ust_get_type_enum(lt)->container_type,
ret = serialize_one_type(session, fields, iter_output, NULL,
lttng_ust_get_type_enum(lt)->container_type,
- lttng_ust_string_encoding_none);
+ lttng_ust_string_encoding_none, NULL);
if (ret)
return -EINVAL;
if (session) {
if (ret)
return -EINVAL;
if (session) {
static
int serialize_one_field(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *fields, size_t *iter_output,
static
int serialize_one_field(struct lttng_ust_session *session,
struct lttng_ust_ctl_field *fields, size_t *iter_output,
- const struct lttng_ust_event_field *lf)
+ const struct lttng_ust_event_field *lf,
+ const char **prev_field_name_p)
+ const char *prev_field_name = NULL;
+ int ret;
+
/* skip 'nowrite' fields */
if (lf->nowrite)
return 0;
/* skip 'nowrite' fields */
if (lf->nowrite)
return 0;
- return serialize_one_type(session, fields, iter_output, lf->name, lf->type, lttng_ust_string_encoding_none);
+ if (prev_field_name_p)
+ prev_field_name = *prev_field_name_p;
+ ret = serialize_one_type(session, fields, iter_output, lf->name, lf->type,
+ lttng_ust_string_encoding_none, prev_field_name);
+ if (prev_field_name_p)
+ *prev_field_name_p = lf->name;
+ return ret;
size_t *iter_output, size_t nr_lttng_fields,
const struct lttng_ust_event_field * const *lttng_fields)
{
size_t *iter_output, size_t nr_lttng_fields,
const struct lttng_ust_event_field * const *lttng_fields)
{
+ const char *prev_field_name = NULL;
int ret;
size_t i;
for (i = 0; i < nr_lttng_fields; i++) {
ret = serialize_one_field(session, lttng_ust_ctl_fields,
int ret;
size_t i;
for (i = 0; i < nr_lttng_fields; i++) {
ret = serialize_one_field(session, lttng_ust_ctl_fields,
- iter_output, lttng_fields[i]);
+ iter_output, lttng_fields[i],
+ &prev_field_name);
struct lttng_ust_ctx_field *lttng_fields)
{
struct lttng_ust_ctl_field *fields;
struct lttng_ust_ctx_field *lttng_fields)
{
struct lttng_ust_ctl_field *fields;
+ const char *prev_field_name = NULL;
size_t i, iter_output = 0;
ssize_t nr_write_fields;
size_t i, iter_output = 0;
ssize_t nr_write_fields;
nr_write_fields = count_ctx_fields_recursive(nr_fields,
lttng_fields);
nr_write_fields = count_ctx_fields_recursive(nr_fields,
lttng_fields);
for (i = 0; i < nr_fields; i++) {
ret = serialize_one_field(session, fields, &iter_output,
for (i = 0; i < nr_fields; i++) {
ret = serialize_one_field(session, fields, &iter_output,
- lttng_fields[i].event_field);
+ lttng_fields[i].event_field, &prev_field_name);
if (ret)
goto error_type;
}
if (ret)
goto error_type;
}