Merge into master from pull request #283:
remove dead code and speed up match deserialization (https://github.com/floodlight/loxigen/pull/283)
diff --git a/c_gen/c_code_gen.py b/c_gen/c_code_gen.py
index e4e2403..ee87d0d 100644
--- a/c_gen/c_code_gen.py
+++ b/c_gen/c_code_gen.py
@@ -1453,19 +1453,14 @@
elif m_type == "of_match_t":
out.write("""
LOCI_ASSERT(cur_len + abs_offset <= WBUF_CURRENT_BYTES(wbuf));
- match_octets.bytes = cur_len;
- match_octets.data = OF_OBJECT_BUFFER_INDEX(obj, offset);
- OF_TRY(of_match_deserialize(ver, %(m_name)s, &match_octets));
+ OF_TRY(of_match_deserialize(ver, %(m_name)s, obj, offset, cur_len));
""" % dict(m_name=m_name))
elif m_type == "of_oxm_header_t":
out.write("""
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
/* Attach to parent */
- %(m_name)s->parent = (of_object_t *)obj;
- %(m_name)s->wbuf = obj->wbuf;
- %(m_name)s->obj_offset = abs_offset;
- %(m_name)s->length = cur_len;
+ of_object_attach(obj, %(m_name)s, offset, cur_len);
of_object_wire_init(%(m_name)s, OF_OXM, 0);
""" % dict(m_type=m_type[:-2], m_name=m_name))
elif m_type == "of_bsn_vport_header_t":
@@ -1473,10 +1468,7 @@
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
/* Attach to parent */
- %(m_name)s->parent = (of_object_t *)obj;
- %(m_name)s->wbuf = obj->wbuf;
- %(m_name)s->obj_offset = abs_offset;
- %(m_name)s->length = cur_len;
+ of_object_attach(obj, %(m_name)s, offset, cur_len);
of_object_wire_init(%(m_name)s, OF_BSN_VPORT, 0);
""" % dict(m_type=m_type[:-2], m_name=m_name))
else:
@@ -1484,10 +1476,7 @@
/* Initialize child */
%(m_type)s_init(%(m_name)s, obj->version, 0, 1);
/* Attach to parent */
- %(m_name)s->parent = (of_object_t *)obj;
- %(m_name)s->wbuf = obj->wbuf;
- %(m_name)s->obj_offset = abs_offset;
- %(m_name)s->length = cur_len;
+ of_object_attach(obj, %(m_name)s, offset, cur_len);
""" % dict(m_type=m_type[:-2], m_name=m_name))
@@ -1513,13 +1502,16 @@
elif m_type == "of_match_t":
out.write("""
- /* Match object */
- OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
- new_len = match_octets.bytes;
- of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
- match_octets.data, new_len);
- /* Free match serialized octets */
- FREE(match_octets.data);
+ {
+ /* Match object */
+ of_octets_t match_octets;
+ OF_TRY(of_match_serialize(ver, %(m_name)s, &match_octets));
+ new_len = match_octets.bytes;
+ of_wire_buffer_replace_data(wbuf, abs_offset, cur_len,
+ match_octets.data, new_len);
+ /* Free match serialized octets */
+ FREE(match_octets.data);
+ }
""" % dict(m_name=m_name))
else: # Other object type
@@ -1639,12 +1631,6 @@
int new_len, delta; /* For set, need new length and delta */
""")
- # For match, need octet string for set/get
- if m_type == "of_match_t":
- out.write("""\
- of_octets_t match_octets; /* Serialized string for match */
-""")
-
out.write("""
LOCI_ASSERT(%(assert_str)s);
ver = obj->version;
@@ -1951,9 +1937,6 @@
* Initializes the new object with it's default fixed length associating
* a new underlying wire buffer.
*
- * Use new_from_message to bind an existing message to a message object,
- * or a _get function for non-message objects.
- *
* \\ingroup %(cls)s
*/
@@ -1995,55 +1978,6 @@
""" % dict(cls=cls))
-def gen_from_message_fn_body(cls, out):
- """
- Generate function body for from_message function
- @param cls The class name for the function
- @param out The file to which to write
- """
- out.write("""
-/**
- * Create a new %(cls)s object and bind it to an existing message
- *
- * @param msg The message to bind the new object to
- * @return Pointer to the newly create object or NULL on error
- *
- * \ingroup %(cls)s
- */
-
-%(cls)s_t *
-%(cls)s_new_from_message(of_message_t msg)
-{
- %(cls)s_t *obj = NULL;
- of_version_t version;
- int length;
-
- if (msg == NULL) return NULL;
-
- version = of_message_version_get(msg);
- if (!OF_VERSION_OKAY(version)) return NULL;
-
- length = of_message_length_get(msg);
-
- if ((obj = (%(cls)s_t *)of_object_new(-1)) == NULL) {
- return NULL;
- }
-
- %(cls)s_init(obj, version, 0, 0);
-
- if ((of_object_buffer_bind((of_object_t *)obj, OF_MESSAGE_TO_BUFFER(msg),
- length, OF_MESSAGE_FREE_FUNCTION)) < 0) {
- FREE(obj);
- return NULL;
- }
- obj->length = length;
- obj->version = version;
-
- return obj;
-}
-""" % dict(cls=cls))
-
-
################################################################
# Now the top level generator functions
################################################################
@@ -2060,13 +1994,10 @@
* New operator declarations
*
* _new: Create a new object for writing; includes init
- * _new_from_message: Create a new instance of the object and bind the
- * message data to the object
* _init: Initialize and optionally allocate buffer space for an
* automatic instance
*
- * _new and _from_message require a delete operation to be called
- * on the object.
+ * _new and requires a delete operation to be called on the object.
*
****************************************************************/
""")
@@ -2076,10 +2007,6 @@
extern %(cls)s_t *
%(cls)s_new(of_version_t version);
""" % dict(cls=cls))
- if loxi_utils.class_is_message(cls):
- out.write("""extern %(cls)s_t *
- %(cls)s_new_from_message(of_message_t msg);
-""" % dict(cls=cls))
out.write("""extern void %(cls)s_init(
%(cls)s_t *obj, of_version_t version, int bytes, int clean_wire);
""" % dict(cls=cls))
@@ -2132,8 +2059,6 @@
gen_new_fn_body(cls, out)
gen_init_fn_body(cls, out)
- if loxi_utils.class_is_message(cls):
- gen_from_message_fn_body(cls, out)
"""
Document generation functions
diff --git a/c_gen/c_match.py b/c_gen/c_match.py
index bc05747..3afc99c 100644
--- a/c_gen/c_match.py
+++ b/c_gen/c_match.py
@@ -77,7 +77,7 @@
extern int of_match_serialize(of_version_t version, of_match_t *match,
of_octets_t *octets);
extern int of_match_deserialize(of_version_t version, of_match_t *match,
- of_octets_t *octets);
+ of_object_t *parent, int offset, int length);
extern int of_match_v1_to_match(of_match_v1_t *src, of_match_t *dst);
extern int of_match_v2_to_match(of_match_v2_t *src, of_match_t *dst);
extern int of_match_v3_to_match(of_match_v3_t *src, of_match_t *dst);
@@ -738,33 +738,18 @@
int
of_match_deserialize(of_version_t version, of_match_t *match,
- of_octets_t *octets)
+ of_object_t *parent, int offset, int length)
{
- if (octets->bytes == 0) { /* No match specified means all wildcards */
- MEMSET(match, 0, sizeof(*match));
- match->version = version;
-
- return OF_ERROR_NONE;
- }
+ of_object_t obj;
switch (version) {
""")
for version in of_g.of_version_range:
out.write("""
case %(ver_name)s:
- { /* FIXME: check init bytes */
- uint8_t *tmp;
- of_match_v%(version)d_t wire_match;
- of_match_v%(version)d_init(&wire_match,
- %(ver_name)s, -1, 1);
- of_object_buffer_bind((of_object_t *)&wire_match,
- octets->data, octets->bytes, NULL);
- OF_TRY(of_match_v%(version)d_to_match(&wire_match, match));
-
- /* Free the wire buffer control block without freeing
- * octets->bytes. */
- of_wire_buffer_steal(wire_match.wbuf, &tmp);
- }
+ of_match_v%(version)d_init(&obj, %(ver_name)s, length, 1);
+ of_object_attach(parent, &obj, offset, length);
+ OF_TRY(of_match_v%(version)d_to_match(&obj, match));
break;
""" % dict(version=version, ver_name=of_g.of_version_wire2name[version]))
diff --git a/c_gen/c_test_gen.py b/c_gen/c_test_gen.py
index aff1ca6..71615e6 100644
--- a/c_gen/c_test_gen.py
+++ b/c_gen/c_test_gen.py
@@ -1027,6 +1027,9 @@
of_match_t match2;
int value = 1;
of_octets_t octets;
+ of_object_storage_t storage;
+ memset(&storage, 0, sizeof(storage));
+ storage.obj.wbuf = &storage.wbuf;
""")
for version in of_g.of_version_range:
out.write("""
@@ -1034,7 +1037,10 @@
TEST_ASSERT((value = of_match_populate(&match1, %(v_name)s, value)) > 0);
TEST_ASSERT(of_match_serialize(%(v_name)s, &match1, &octets) ==
OF_ERROR_NONE);
- TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &octets) ==
+ storage.obj.wbuf->buf = octets.data;
+ storage.obj.wbuf->alloc_bytes = octets.bytes;
+ storage.obj.wbuf->current_bytes = octets.bytes;
+ TEST_ASSERT(of_match_deserialize(%(v_name)s, &match2, &storage.obj, 0, octets.bytes) ==
OF_ERROR_NONE);
TEST_ASSERT(memcmp(&match1, &match2, sizeof(match1)) == 0);
FREE(octets.data);
@@ -1084,6 +1090,7 @@
uint8_t *msg_buf;
int value;
of_object_id_t object_id;
+ int len;
obj = %(cls)s_new(%(v_name)s);
TEST_ASSERT(obj != NULL);
@@ -1099,11 +1106,13 @@
value = %(cls)s_%(v_name)s_populate_scalars(obj, 1);
TEST_ASSERT(value != 0);
+ len = obj->length;
+
/* Grab the underlying buffer from the message */
of_object_wire_buffer_steal((of_object_t *)obj, &msg_buf);
TEST_ASSERT(msg_buf != NULL);
%(cls)s_delete(obj);
- obj = %(cls)s_new_from_message(OF_BUFFER_TO_MESSAGE(msg_buf));
+ obj = of_object_new_from_message(OF_BUFFER_TO_MESSAGE(msg_buf), len);
TEST_ASSERT(obj != NULL);
diff --git a/c_gen/templates/locitest/test_ext.c b/c_gen/templates/locitest/test_ext.c
index 7bd0998..8d28e87 100644
--- a/c_gen/templates/locitest/test_ext.c
+++ b/c_gen/templates/locitest/test_ext.c
@@ -46,5 +46,7 @@
TEST_ASSERT(obj != NULL);
TEST_ASSERT(obj->object_id == OF_ACTION_BSN_MIRROR);
+ of_object_delete(obj);
+
return TEST_PASS;
}
diff --git a/c_gen/templates/of_object.c b/c_gen/templates/of_object.c
index 39a6790..b0d3e14 100644
--- a/c_gen/templates/of_object.c
+++ b/c_gen/templates/of_object.c
@@ -254,7 +254,6 @@
* @param offset The offset at which to attach the child RELATIVE
* TO THE PARENT in the buffer
* @param bytes The amount of the buffer dedicated to the child; see below
- * @param inc_ref_count Should the ref count of the parent be incremented
*
* This is used for 'get' accessors for composite types as well as
* iterator functions for lists, both read (first/next) and write
@@ -276,14 +275,7 @@
object_child_attach(of_object_t *parent, of_object_t *child,
int offset, int bytes)
{
- of_wire_buffer_t *wbuf; /* Pointer to common wire buffer manager */
-
- child->parent = parent;
- wbuf = parent->wbuf;
-
- /* Set up the child's wire buf to point to same as parent */
- child->wbuf = wbuf;
- child->obj_offset = parent->obj_offset + offset;
+ of_object_attach(parent, child, offset, bytes);
/*
* bytes determines if this is a read or write setup.
@@ -296,8 +288,7 @@
/* Set up space for the child in the parent's buffer */
tot_bytes = parent->obj_offset + offset + bytes;
- of_wire_buffer_grow(wbuf, tot_bytes);
- child->length = bytes;
+ of_wire_buffer_grow(parent->wbuf, tot_bytes);
}
/* if bytes == 0 don't do anything */
}
diff --git a/c_gen/templates/of_object.h b/c_gen/templates/of_object.h
index d299537..0ca415b 100644
--- a/c_gen/templates/of_object.h
+++ b/c_gen/templates/of_object.h
@@ -132,4 +132,22 @@
of_wire_buffer_t wbuf;
};
+/**
+ * Connect a child to a parent at the wire buffer level
+ *
+ * @param parent The top level object to bind to
+ * @param child The sub-object connecting to the parent
+ * @param offset The offset at which to attach the child RELATIVE
+ * TO THE PARENT in the buffer
+ * @param bytes The amount of the buffer dedicated to the child
+ */
+static inline void
+of_object_attach(of_object_t *parent, of_object_t *child, int offset, int length)
+{
+ child->parent = parent;
+ child->wbuf = parent->wbuf;
+ child->obj_offset = parent->obj_offset + offset;
+ child->length = length;
+}
+
#endif /* _OF_OBJECT_H_ */