Use statically known types, use hash for formats
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 30 Sep 2010 01:02:13 +0000 (21:02 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 30 Sep 2010 01:02:13 +0000 (21:02 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
formats/ctf/ctf.c [new file with mode: 0644]
formats/ctf/types/bitfield.c [new file with mode: 0644]
formats/ctf/types/float.c
formats/ctf/types/integer.c
formats/registry.c [new file with mode: 0644]
include/babeltrace/compiler.h
include/babeltrace/ctf/types.h
include/babeltrace/format.h [new file with mode: 0644]
include/babeltrace/types.h
types/integer.c [new file with mode: 0644]
types/types.c

diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c
new file mode 100644 (file)
index 0000000..d128b9a
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * BabelTrace - Common Trace Format (CTF)
+ *
+ * Format registration.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <babeltrace/format.h>
+#include <babeltrace/ctf/types.h>
+
+void __attribute__((constructor)) ctf_init(void);
+
+static const struct format ctf_format = {
+       .uint_read = ctf_uint_read,
+       .int_read = ctf_int_read,
+       .uint_write = ctf_uint_write,
+       .int_write = ctf_int_write,
+       .bitfield_unsigned_read = ctf_bitfield_unsigned_read,
+       .bitfield_signed_read = ctf_bitfield_signed_read,
+       .bitfield_unsigned_write = ctf_bitfield_unsigned_write,
+       .bitfield_signed_write = ctf_bitfield_signed_write,
+       .float_copy = ctf_float_copy,
+       .string_copy = ctf_string_copy,
+       .enum_uint_to_quark = ctf_enum_uint_to_quark,
+       .enum_int_to_quark = ctf_enum_int_to_quark,
+       .enum_quark_to_uint = ctf_enum_quark_to_uint,
+       .enum_quark_to_int = ctf_enum_quark_to_int,
+};
+
+void ctf_init(void)
+{
+       int ret;
+
+       ctf_format->name = g_quark_from_static_string("ctf");
+       ret = bt_register_format(&ctf_format);
+       assert(!ret);
+}
diff --git a/formats/ctf/types/bitfield.c b/formats/ctf/types/bitfield.c
new file mode 100644 (file)
index 0000000..38c8b88
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Common Trace Format
+ *
+ * Bitfields read/write functions.
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <ctf/bitfield.h>
+#include <endian.h>
+
+uint64_t ctf_bitfield_unsigned_read(const unsigned char *ptr,
+                                   unsigned long start, unsigned long len,
+                                   int byte_order)
+{
+       uint64_t v;
+
+       if (byte_order == LITTLE_ENDIAN)
+               ctf_bitfield_read_le(ptr, start, len, &v);
+       else
+               ctf_bitfield_read_be(ptr, start, len, &v);
+       return v;
+}
+
+int64_t ctf_bitfield_signed_read(const unsigned char *ptr,
+                                unsigned long start, unsigned long len,
+                                int byte_order)
+{
+       int64_t v;
+
+       if (byte_order == LITTLE_ENDIAN)
+               ctf_bitfield_read_le(ptr, start, len, &v);
+       else
+               ctf_bitfield_read_be(ptr, start, len, &v);
+       return v;
+}
+
+size_t ctf_bitfield_unsigned_write(unsigned char *ptr,
+                                  unsigned long start, unsigned long len,
+                                  int byte_order, uint64_t v)
+{
+       if (!ptr)
+               goto end;
+       if (byte_order == LITTLE_ENDIAN)
+               ctf_bitfield_write_le(ptr, start, len, v);
+       else
+               ctf_bitfield_write_be(ptr, start, len, v);
+end:
+       return len;
+}
+
+size_t ctf_bitfield_signed_write(unsigned char *ptr,
+                                unsigned long start, unsigned long len,
+                                int byte_order, int64_t v)
+{
+       if (!ptr)
+               goto end;
+       if (byte_order == LITTLE_ENDIAN)
+               ctf_bitfield_write_le(ptr, start, len, v);
+       else
+               ctf_bitfield_write_be(ptr, start, len, v);
+end:
+       return len;
+}
index ce094747113f762c3f8785a9af913d7128de0882..db753dfbea86cf914b859f489e817878abba69b8 100644 (file)
@@ -72,8 +72,8 @@ struct pos_len {
        size_t sign_start, exp_start, mantissa_start, len;
 };
 
-void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
-                   const unsigned char *src, const struct ctf_float *src)
+void ctf_float_copy(unsigned char *destp, const struct type_class_float *dest,
+                   const unsigned char *src, const struct type_class_float *src)
 {
        struct pos_len destpos, srcpos;
        union {
@@ -81,8 +81,8 @@ void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
                long long s;
        } tmp;
 
-       destpos.len = dest.exp_len + dest.mantissa_len;
-       if (dest.byte_order == LITTLE_ENDIAN) {
+       destpos.len = dest->exp_len + dest->mantissa_len;
+       if (dest->byte_order == LITTLE_ENDIAN) {
                destpos.sign_start = destpos.len - 1;
                destpos.exp_start = destpos.sign_start - dest->exp_len;
                destpos.mantissa_start = 0;
@@ -92,8 +92,8 @@ void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
                destpos.mantissa_start = destpos.exp_start + dest->exp_len;
        }
 
-       srcpos.len = src.exp_len + src.mantissa_len;
-       if (src.byte_order == LITTLE_ENDIAN) {
+       srcpos.len = src->exp_len + src->mantissa_len;
+       if (src->byte_order == LITTLE_ENDIAN) {
                srcpos.sign_start = srcpos.len - 1;
                srcpos.exp_start = srcpos.sign_start - src->exp_len;
                srcpos.mantissa_start = 0;
@@ -124,7 +124,7 @@ void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
                                  dest->byte_order, tmp.s);
 }
 
-double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src)
+double ctf_double_read(const unsigned char *ptr, const struct type_class_float *src)
 {
        union doubleIEEE754 u;
        struct ctf_float dest = {
@@ -137,7 +137,7 @@ double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src)
        return u.v;
 }
 
-size_t ctf_double_write(unsigned char *ptr, const struct ctf_float *dest,
+size_t ctf_double_write(unsigned char *ptr, const struct type_class_float *dest,
                        double v)
 {
        union doubleIEEE754 u;
@@ -156,7 +156,7 @@ end:
 }
 
 long double ctf_ldouble_read(const unsigned char *ptr,
-                            const struct ctf_float *src)
+                            const struct type_class_float *src)
 {
        union ldoubleIEEE754 u;
        struct ctf_float dest = {
@@ -169,7 +169,7 @@ long double ctf_ldouble_read(const unsigned char *ptr,
        return u.v;
 }
 
-size_t ctf_ldouble_write(unsigned char *ptr, const struct ctf_float *dest,
+size_t ctf_ldouble_write(unsigned char *ptr, const struct type_class_float *dest,
                         long double v)
 {
        union ldoubleIEEE754 u;
index cd81b17aa0d47d29f98334e0f798f1e7fd625119..316a088873a79a428518b4eaf888e2553b4b7eef 100644 (file)
@@ -25,7 +25,7 @@
 #include <glib.h>
 #include <endian.h>
 
-uint64_t uint_read(const uint8_t *ptr, size_t len, int byte_order)
+uint64_t ctf_uint_read(const uint8_t *ptr, size_t len, int byte_order)
 {
        int rbo = (byte_order != BYTE_ORDER);   /* reverse byte order */
 
@@ -63,7 +63,7 @@ uint64_t uint_read(const uint8_t *ptr, size_t len, int byte_order)
        }
 }
 
-int64_t int_read(const uint8_t *ptr, size_t len, int byte_order)
+int64_t ctf_int_read(const uint8_t *ptr, size_t len, int byte_order)
 {
        int rbo = (byte_order != BYTE_ORDER);   /* reverse byte order */
 
@@ -101,7 +101,7 @@ int64_t int_read(const uint8_t *ptr, size_t len, int byte_order)
        }
 }
 
-size_t uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v)
+size_t ctf_uint_write(uint8_t *ptr, size_t len, int byte_order, uint64_t v)
 {
        int rbo = (byte_order != BYTE_ORDER);   /* reverse byte order */
 
@@ -129,7 +129,7 @@ end:
        return len;
 }
 
-size_t int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v)
+size_t ctf_int_write(uint8_t *ptr, size_t len, int byte_order, int64_t v)
 {
        int rbo = (byte_order != BYTE_ORDER);   /* reverse byte order */
 
diff --git a/formats/registry.c b/formats/registry.c
new file mode 100644 (file)
index 0000000..83e0aa0
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * BabelTrace
+ *
+ * Format Registry
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <glib.h>
+#include <errno.h>
+
+static int init_done;
+void __attribute__((constructor)) format_init(void);
+void __attribute__((destructor)) format_finalize(void);
+
+/*
+ * Format registry hash table contains the registered formats. Format
+ * registration is typically performed by a format plugin.
+ * TODO: support plugin unload (unregistration of formats).
+ */
+GHashTable *format_registry;
+
+struct format *bt_lookup_format(GQuark qname)
+{
+       if (!init_done)
+               return NULL;
+       return g_hash_table_lookup(format_registry,
+                                  (gconstpointer) (unsigned long) qname)
+}
+
+int bt_register_format(const struct format *format)
+{
+       if (!init_done)
+               format_init();
+
+       if (bt_lookup_format(qname))
+               return -EEXIST;
+
+       g_hash_table_insert(format_registry,
+                           (gconstpointer) (unsigned long) format->name,
+                           format);
+       return 0;
+}
+
+void format_init(void)
+{
+       format_registry = g_hash_table_new(g_direct_hash, g_direct_equal);
+       assert(format_registry);
+       init_done = 1;
+}
+
+int format_finalize(void)
+{
+       g_hash_table_destroy(format_registry);
+}
index 7850ded675a3bb75ce892e2f74d75fcb915561ab..c8bb4db5b8cd38d61be56aa06da8f892d3e13969 100644 (file)
@@ -3,4 +3,12 @@
 
 #define MAYBE_BUILD_BUG_ON(cond) ((void)sizeof(char[1 - 2 * !!(cond)]))
 
+#ifndef container_of
+#define container_of(ptr, type, member)                                        \
+       ({                                                              \
+               const typeof(((type *)NULL)->member) * __ptr = (ptr);   \
+               (type *)((char *)__ptr - offsetof(type, member));       \
+       })
+#endif
+
 #endif /* _BABELTRACE_COMPILER_H */
index 276152dbc67ffd358fbb8fba208fad5a76729947..894dda24bdd479882d4546777c5b45bfb533675f 100644 (file)
@@ -40,30 +40,28 @@ int64_t ctf_int_read(const unsigned char *ptr, int byte_order, size_t len);
 size_t ctf_uint_write(unsigned char *ptr, int byte_order, size_t len, uint64_t v);
 size_t ctf_int_write(unsigned char *ptr, int byte_order, size_t len, int64_t v);
 
-/*
- * ctf-types-bitfield.h declares:
- *
- * ctf_bitfield_unsigned_read
- * ctf_bitfield_signed_read
- * ctf_bitfield_unsigned_write
- * ctf_bitfield_signed_write
- */
-#include <ctf/ctf-types-bitfield.h>
+uint64_t ctf_bitfield_unsigned_read(const unsigned char *ptr,
+                                   unsigned long start, unsigned long len,
+                                   int byte_order);
+int64_t ctf_bitfield_signed_read(const unsigned char *ptr,
+                                unsigned long start, unsigned long len,
+                                int byte_order);
+size_t ctf_bitfield_unsigned_write(unsigned char *ptr,
+                                  unsigned long start, unsigned long len,
+                                  int byte_order, uint64_t v);
+size_t ctf_bitfield_signed_write(unsigned char *ptr,
+                                unsigned long start, unsigned long len,
+                                int byte_order, int64_t v);
 
-double ctf_double_read(const unsigned char *ptr, const struct ctf_float *src)
-size_t ctf_double_write(unsigned char *ptr, const struct ctf_float *dest,
+double ctf_double_read(const unsigned char *ptr, const struct type_class_float *src)
+size_t ctf_double_write(unsigned char *ptr, const struct type_class_float *dest,
                        double v);
 long double ctf_ldouble_read(const unsigned char *ptr,
-                            const struct ctf_float *src)
-size_t ctf_ldouble_write(unsigned char *ptr, const struct ctf_float *dest,
+                            const struct type_class_float *src)
+size_t ctf_ldouble_write(unsigned char *ptr, const struct type_class_float *dest,
                         long double v);
-struct ctf_float {
-       size_t exp_len;
-       size_t mantissa_len;    /* Including sign bit */
-       int byte_order;
-};
-void ctf_float_copy(unsigned char *destp, const struct ctf_float *dest,
-                   const unsigned char *srcp, const struct ctf_float *src);
+void ctf_float_copy(unsigned char *destp, const struct type_class_float *dest,
+                   const unsigned char *srcp, const struct type_class_float *src);
 
 size_t ctf_string_copy(unsigned char *dest, const unsigned char *src);
 
diff --git a/include/babeltrace/format.h b/include/babeltrace/format.h
new file mode 100644 (file)
index 0000000..4981f12
--- /dev/null
@@ -0,0 +1,67 @@
+#ifndef _BABELTRACE_FORMAT_H
+#define _BABELTRACE_FORMAT_H
+
+/*
+ * BabelTrace
+ *
+ * Trace Format Header
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <glib.h>
+
+struct format {
+       GQuark name;
+
+       uint64_t (*uint_read)(const uint8_t *ptr, size_t len, int byte_order);
+       int64_t (*int_read)(const uint8_t *ptr, size_t len, int byte_order);
+       size_t (*uint_write)(uint8_t *ptr, size_t len, int byte_order, uint64_t v);
+       size_t (*int_write)(uint8_t *ptr, size_t len, int byte_order, int64_t v);
+
+       uint64_t (*bitfield_unsigned_read)(const unsigned char *ptr,
+                                           unsigned long start, unsigned long len,
+                                           int byte_order);
+       int64_t (*bitfield_signed_read)(const unsigned char *ptr,
+                                        unsigned long start, unsigned long len,
+                                        int byte_order);
+       size_t (*bitfield_unsigned_write)(unsigned char *ptr,
+                                          unsigned long start, unsigned long len,
+                                          int byte_order, uint64_t v);
+       size_t (*bitfield_signed_write)(unsigned char *ptr,
+                                        unsigned long start, unsigned long len,
+                                        int byte_order, int64_t v);
+
+
+       void (*float_copy)(unsigned char *destp, const struct type_class_float *dest,
+                   const unsigned char *srcp, const struct type_class_float *src);
+
+       size_t (*string_copy)(unsigned char *dest, const unsigned char *src);
+
+       GQuark (*enum_uint_to_quark)(const struct enum_table *table, uint64_t v);
+       GQuark (*enum_int_to_quark)(const struct enum_table *table, uint64_t v);
+       uint64_t (*enum_quark_to_uint)(size_t len, int byte_order, GQuark q);
+       int64_t (*enum_quark_to_int)(size_t len, int byte_order, GQuark q);
+};
+
+struct format *bt_lookup_format(GQuark qname);
+int bt_register_format(const struct format *format);
+
+/* TBD: format unregistration */
+
+#endif /* _BABELTRACE_FORMAT_H */
index 23fec0fcfcba89c48fd2715b30b55e0daa389b7a..f8c3c8aa1de80d2a362392c9aa964387432b9ecf 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * BabelTrace
  *
- * Type header
+ * Type Header
  *
  * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <babeltrace/format.h>
+
+struct type_class {
+       GQuark name;            /* type name */
+       size_t alignment;       /* type alignment, in bits */
+       /*
+        * Type copy function. Knows how to find the child type_class from the
+        * parent type_class.
+        */
+       size_t (*copy)(unsigned char *dest, const struct format *fdest, 
+                      const unsigned char *src, const struct format *fsrc,
+                      const struct type_class *type_class);
+};
+
+struct type_class_integer {
+       struct type_class p;
+       size_t len;             /* length, in bits. */
+       int byte_order;         /* byte order */
+       int signedness;
+};
+
+struct type_class_bitfield {
+       struct type_class_integer p;
+       size_t start_offset;    /* offset from base address, in bits */
+};
+
+struct type_class_float {
+       struct type_class p;
+       size_t mantissa_len;
+       size_t exp_len;
+       int byte_order;
+};
+
+struct type_class_enum {
+       struct type_class_bitfield;     /* inherit from bitfield */
+       struct enum_table *table;
+};
+
+struct type_class_struct {
+       struct type_class p;
+       /* TODO */
+};
+
 #endif /* _BABELTRACE_TYPES_H */
diff --git a/types/integer.c b/types/integer.c
new file mode 100644 (file)
index 0000000..9b92ce3
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * BabelTrace - Integer Type Converter
+ *
+ * Copyright (c) 2010 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <babeltrace/compiler.h>
+#include <stdint.h>
+
+size_t copy_integer(unsigned char *dest, const struct format *fdest, 
+                   const unsigned char *src, const struct format *fsrc,
+                   const struct type_class *type_class)
+{
+       struct type_class_integer *int_class =
+               container_of(type_class, struct type_class_integer, p);
+
+       if (!int_class->signedness) {
+               uint64_t v;
+
+               v = fsrc->uint_read(src, int_class->byte_order, int_class->len);
+               return fdest->uint_write(dest, int_class->byte_order,
+                                        int_class->len, v);
+       } else {
+               int64_t v;
+
+               v = fsrc->int_read(src, int_class->byte_order, int_class->len);
+               return fdest->int_write(dest, int_class->byte_order,
+                                       int_class->len, v);
+       }
+}
index 28242d23c323201106dc49d93775b572b65f0372..7aeb74aa002956e03f82203fc07e4f4edb6557d3 100644 (file)
 #include <glib.h>
 #include <errno.h>
 
-struct type_class {
-       GQuark qname;
-       void (*read)();
-       size_t (*write)();
-};
-
-struct type {
-       struct type_class *class;
-       size_t alignment;       /* type alignment, in bits */
-       ssize_t len;            /* type length, in bits. -1 for dynamic size. */
-};
-
 /*
  * Type class hash table contains the registered type classes. Type class
  * registration is typically performed by a plugin.
This page took 0.061427 seconds and 4 git commands to generate.