]> code.delx.au - pulseaudio/commitdiff
object: speed up type verification by not relying on strcmp()
authorLennart Poettering <lennart@poettering.net>
Fri, 21 Aug 2009 19:27:44 +0000 (21:27 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 21 Aug 2009 19:27:44 +0000 (21:27 +0200)
Instead of using string contents for type identification use the address
of a constant string array. This should speed up type verifications a
little sind we only need to compare one machine word instead of a full
string. Also, this saves a few strings.

To make clear that types must be compared via address and not string
contents 'type_name' is now called 'type_id'.

This also simplifies the macros for declaring and defining public and
private subclasses.

19 files changed:
src/pulsecore/core.c
src/pulsecore/core.h
src/pulsecore/msgobject.c
src/pulsecore/msgobject.h
src/pulsecore/object.c
src/pulsecore/object.h
src/pulsecore/play-memblockq.c
src/pulsecore/protocol-esound.c
src/pulsecore/protocol-native.c
src/pulsecore/protocol-simple.c
src/pulsecore/sink-input.c
src/pulsecore/sink-input.h
src/pulsecore/sink.c
src/pulsecore/sink.h
src/pulsecore/sound-file-stream.c
src/pulsecore/source-output.c
src/pulsecore/source-output.h
src/pulsecore/source.c
src/pulsecore/source.h

index f5eb8352ae554d38814a311e727111a8bd46cffe..f072645304b2e85dfaf200a002d3fb0d910c453a 100644 (file)
@@ -47,7 +47,7 @@
 
 #include "core.h"
 
-static PA_DEFINE_CHECK_TYPE(pa_core, pa_msgobject);
+PA_DEFINE_PUBLIC_CLASS(pa_core, pa_msgobject);
 
 static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk) {
     pa_core *c = PA_CORE(o);
index f6ec7122f86694728d3f80fc993c82686fe64dca..c1002f93e8311d085d8cb3df2b3d2c954904fa6d 100644 (file)
@@ -165,7 +165,7 @@ struct pa_core {
     pa_hook hooks[PA_CORE_HOOK_MAX];
 };
 
-PA_DECLARE_CLASS(pa_core);
+PA_DECLARE_PUBLIC_CLASS(pa_core);
 #define PA_CORE(o) pa_core_cast(o)
 
 enum {
index 6a2a612d1230cdb57032dba0a968f2f9aeaa534c..075a28c5984a81187d6753ee3e9c578d1fa84a94 100644 (file)
 
 #include "msgobject.h"
 
-PA_DEFINE_CHECK_TYPE(pa_msgobject, pa_object);
+PA_DEFINE_PUBLIC_CLASS(pa_msgobject, pa_object);
 
-pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name)) {
+pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_id, pa_bool_t (*check_type)(const char *type_name)) {
     pa_msgobject *o;
 
     pa_assert(size > sizeof(pa_msgobject));
-    pa_assert(type_name);
+    pa_assert(type_id);
 
     if (!check_type)
         check_type = pa_msgobject_check_type;
 
-    pa_assert(check_type(type_name));
-    pa_assert(check_type("pa_object"));
-    pa_assert(check_type("pa_msgobject"));
+    pa_assert(check_type(type_id));
+    pa_assert(check_type(pa_object_type_id));
+    pa_assert(check_type(pa_msgobject_type_id));
 
-    o = PA_MSGOBJECT(pa_object_new_internal(size, type_name, check_type));
+    o = PA_MSGOBJECT(pa_object_new_internal(size, type_id, check_type));
     o->process_msg = NULL;
     return o;
 }
index a35a23b57581869cf2de197b2a8dc34b541a8fcd..ee0ec1ed1ea02a39528ee531834a8aff8fe5b3a5 100644 (file)
@@ -38,15 +38,13 @@ struct pa_msgobject {
     int (*process_msg)(pa_msgobject *o, int code, void *userdata, int64_t offset, pa_memchunk *chunk);
 };
 
-pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name));
+pa_msgobject *pa_msgobject_new_internal(size_t size, const char *type_id, pa_bool_t (*check_type)(const char *type_name));
 
-int pa_msgobject_check_type(const char *type);
-
-#define pa_msgobject_new(type) ((type*) pa_msgobject_new_internal(sizeof(type), #type, type##_check_type))
+#define pa_msgobject_new(type) ((type*) pa_msgobject_new_internal(sizeof(type), type##_type_id, type##_check_type))
 #define pa_msgobject_free ((void (*) (pa_msgobject* o)) pa_object_free)
 
 #define PA_MSGOBJECT(o) pa_msgobject_cast(o)
 
-PA_DECLARE_CLASS(pa_msgobject);
+PA_DECLARE_PUBLIC_CLASS(pa_msgobject);
 
 #endif
index f3ead9c50e2e7a8a2fa5da843d6ef986e762c062..099d50d9c4bd91a0205d8c3ee2c95de8fd7dc7dd 100644 (file)
 
 #include "object.h"
 
-pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name)) {
+const char pa_object_type_id[] = "pa_object";
+
+pa_object *pa_object_new_internal(size_t size, const char *type_id, pa_bool_t (*check_type)(const char *type_id)) {
     pa_object *o;
 
     pa_assert(size > sizeof(pa_object));
-    pa_assert(type_name);
+    pa_assert(type_id);
 
     if (!check_type)
         check_type = pa_object_check_type;
 
-    pa_assert(check_type(type_name));
-    pa_assert(check_type("pa_object"));
+    pa_assert(check_type(type_id));
+    pa_assert(check_type(pa_object_type_id));
 
     o = pa_xmalloc(size);
     PA_REFCNT_INIT(o);
-    o->type_name = type_name;
+    o->type_id = type_id;
     o->free = pa_object_free;
     o->check_type = check_type;
 
@@ -65,8 +67,8 @@ void pa_object_unref(pa_object *o) {
     }
 }
 
-int pa_object_check_type(const char *type_name) {
-    pa_assert(type_name);
+pa_bool_t pa_object_check_type(const char *type_id) {
+    pa_assert(type_id);
 
-    return pa_streq(type_name, "pa_object");
+    return type_id == pa_object_type_id;
 }
index 43e79327da1f52733b7de33ce9273278b827be6d..4c120cd57ade679f9053d6ca883a47d96dca44ad 100644 (file)
@@ -34,21 +34,23 @@ typedef struct pa_object pa_object;
 
 struct pa_object {
     PA_REFCNT_DECLARE;
-    const char *type_name;
+    const char *type_id;
     void (*free)(pa_object *o);
-    int (*check_type)(const char *type_name);
+    pa_bool_t (*check_type)(const char *type_name);
 };
 
-pa_object *pa_object_new_internal(size_t size, const char *type_name, int (*check_type)(const char *type_name));
-#define pa_object_new(type) ((type*) pa_object_new_internal(sizeof(type), #type, type##_check_type)
+pa_object *pa_object_new_internal(size_t size, const char *type_id, pa_bool_t (*check_type)(const char *type_id));
+#define pa_object_new(type) ((type*) pa_object_new_internal(sizeof(type), type##_type_id, type##_check_type)
 
 #define pa_object_free ((void (*) (pa_object* _obj)) pa_xfree)
 
-int pa_object_check_type(const char *type);
+pa_bool_t pa_object_check_type(const char *type_id);
 
-static inline int pa_object_isinstance(void *o) {
+extern const char pa_object_type_id[];
+
+static inline pa_bool_t pa_object_isinstance(void *o) {
     pa_object *obj = (pa_object*) o;
-    return obj ? obj->check_type("pa_object") : 0;
+    return obj ? obj->check_type(pa_object_type_id) : TRUE;
 }
 
 pa_object *pa_object_ref(pa_object *o);
@@ -60,7 +62,7 @@ static inline int pa_object_refcnt(pa_object *o) {
 
 static inline pa_object* pa_object_cast(void *o) {
     pa_object *obj = (pa_object*) o;
-    pa_assert(!obj || obj->check_type("pa_object"));
+    pa_assert(!obj || obj->check_type(pa_object_type_id));
     return obj;
 }
 
@@ -68,10 +70,10 @@ static inline pa_object* pa_object_cast(void *o) {
 
 #define PA_OBJECT(o) pa_object_cast(o)
 
-#define PA_DECLARE_CLASS(c)                                             \
-    static inline int c##_isinstance(void *o) {                         \
+#define PA_DECLARE_CLASS_COMMON(c)                                      \
+    static inline pa_bool_t c##_isinstance(void *o) {                   \
         pa_object *obj = (pa_object*) o;                                \
-        return obj ? obj->check_type(#c) : 1;                           \
+        return obj ? obj->check_type(c##_type_id) : TRUE;               \
     }                                                                   \
     static inline c* c##_cast(void *o) {                                \
         pa_assert(c##_isinstance(o));                                   \
@@ -91,12 +93,27 @@ static inline pa_object* pa_object_cast(void *o) {
     }                                                                   \
     struct __stupid_useless_struct_to_allow_trailing_semicolon
 
-#define PA_DEFINE_CHECK_TYPE(c, parent)                                 \
-    int c##_check_type(const char *type) {                              \
-        pa_assert(type);                                                \
-        if (strcmp(type, #c) == 0)                                      \
-            return 1;                                                   \
-        return parent##_check_type(type);                               \
+#define PA_DECLARE_PUBLIC_CLASS(c)                                      \
+    extern const char c##_type_id[];                                    \
+    PA_DECLARE_CLASS_COMMON(c);                                         \
+    pa_bool_t c##_check_type(const char *type_id)
+
+#define PA_DEFINE_PUBLIC_CLASS(c, parent)                               \
+    const char c##_type_id[] = #c;                                      \
+    pa_bool_t c##_check_type(const char *type_id) {                     \
+        if (type_id == c##_type_id)                                     \
+            return TRUE;                                                \
+        return parent##_check_type(type_id);                            \
+    }                                                                   \
+    struct __stupid_useless_struct_to_allow_trailing_semicolon
+
+#define PA_DEFINE_PRIVATE_CLASS(c, parent)                              \
+    static const char c##_type_id[] = #c;                               \
+    PA_DECLARE_CLASS_COMMON(c);                                         \
+    static pa_bool_t c##_check_type(const char *type_id) {              \
+        if (type_id == c##_type_id)                                     \
+            return TRUE;                                                \
+        return parent##_check_type(type_id);                            \
     }                                                                   \
     struct __stupid_useless_struct_to_allow_trailing_semicolon
 
index fceb2ca146cbc102c7e9e99715e75a11facb54f0..b0d76993d873c01e18a8472d4bdf0c9298aa0e72 100644 (file)
@@ -47,9 +47,8 @@ enum {
     MEMBLOCKQ_STREAM_MESSAGE_UNLINK,
 };
 
-PA_DECLARE_CLASS(memblockq_stream);
+PA_DEFINE_PRIVATE_CLASS(memblockq_stream, pa_msgobject);
 #define MEMBLOCKQ_STREAM(o) (memblockq_stream_cast(o))
-static PA_DEFINE_CHECK_TYPE(memblockq_stream, pa_msgobject);
 
 static void memblockq_stream_unlink(memblockq_stream *u) {
     pa_assert(u);
index f64552aa49fff48eb7c09e04eb287f27ab8d3fe5..cfbaee6f4fabffa234b79a122d44c98077c669c8 100644 (file)
@@ -120,9 +120,8 @@ typedef struct connection {
     pa_time_event *auth_timeout_event;
 } connection;
 
-PA_DECLARE_CLASS(connection);
+PA_DEFINE_PRIVATE_CLASS(connection, pa_msgobject);
 #define CONNECTION(o) (connection_cast(o))
-static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject);
 
 struct pa_esound_protocol {
     PA_REFCNT_DECLARE;
index b1285e1551f6458835f2611b978d88279bf20511..6678d84711aba47fffb3d2468a675ce33b1cf064 100644 (file)
@@ -98,17 +98,15 @@ typedef struct record_stream {
     pa_usec_t current_source_latency;
 } record_stream;
 
-PA_DECLARE_CLASS(record_stream);
 #define RECORD_STREAM(o) (record_stream_cast(o))
-static PA_DEFINE_CHECK_TYPE(record_stream, pa_msgobject);
+PA_DEFINE_PRIVATE_CLASS(record_stream, pa_msgobject);
 
 typedef struct output_stream {
     pa_msgobject parent;
 } output_stream;
 
-PA_DECLARE_CLASS(output_stream);
 #define OUTPUT_STREAM(o) (output_stream_cast(o))
-static PA_DEFINE_CHECK_TYPE(output_stream, pa_msgobject);
+PA_DEFINE_PRIVATE_CLASS(output_stream, pa_msgobject);
 
 typedef struct playback_stream {
     output_stream parent;
@@ -138,9 +136,8 @@ typedef struct playback_stream {
     uint64_t playing_for, underrun_for;
 } playback_stream;
 
-PA_DECLARE_CLASS(playback_stream);
 #define PLAYBACK_STREAM(o) (playback_stream_cast(o))
-static PA_DEFINE_CHECK_TYPE(playback_stream, output_stream);
+PA_DEFINE_PRIVATE_CLASS(playback_stream, output_stream);
 
 typedef struct upload_stream {
     output_stream parent;
@@ -156,9 +153,8 @@ typedef struct upload_stream {
     pa_proplist *proplist;
 } upload_stream;
 
-PA_DECLARE_CLASS(upload_stream);
 #define UPLOAD_STREAM(o) (upload_stream_cast(o))
-static PA_DEFINE_CHECK_TYPE(upload_stream, output_stream);
+PA_DEFINE_PRIVATE_CLASS(upload_stream, output_stream);
 
 struct pa_native_connection {
     pa_msgobject parent;
@@ -176,9 +172,8 @@ struct pa_native_connection {
     pa_time_event *auth_timeout_event;
 };
 
-PA_DECLARE_CLASS(pa_native_connection);
 #define PA_NATIVE_CONNECTION(o) (pa_native_connection_cast(o))
-static PA_DEFINE_CHECK_TYPE(pa_native_connection, pa_msgobject);
+PA_DEFINE_PRIVATE_CLASS(pa_native_connection, pa_msgobject);
 
 struct pa_native_protocol {
     PA_REFCNT_DECLARE;
index 776d74b632a5ce84ea16f0858fc7ad217f8a9261..95ec6ac8e41848ffc7ba7ad4f626b6fbebab1482 100644 (file)
@@ -69,9 +69,8 @@ typedef struct connection {
     } playback;
 } connection;
 
-PA_DECLARE_CLASS(connection);
+PA_DEFINE_PRIVATE_CLASS(connection, pa_msgobject);
 #define CONNECTION(o) (connection_cast(o))
-static PA_DEFINE_CHECK_TYPE(connection, pa_msgobject);
 
 struct pa_simple_protocol {
     PA_REFCNT_DECLARE;
index 975fda01e4fc3e7899b2dfe30228c52f5b046976..4137a425cec77c0657516b772f0c4e399e70d1ce 100644 (file)
@@ -44,7 +44,7 @@
 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
 #define CONVERT_BUFFER_LENGTH (PA_PAGE_SIZE)
 
-static PA_DEFINE_CHECK_TYPE(pa_sink_input, pa_msgobject);
+PA_DEFINE_PUBLIC_CLASS(pa_sink_input, pa_msgobject);
 
 static void sink_input_free(pa_object *o);
 static void set_real_ratio(pa_sink_input *i, const pa_cvolume *v);
index 5285e61843171144118328eb84cbe538f328a03e..fe6cf75c0e6e1b132d6e42f9129f15b1bb9958ec 100644 (file)
@@ -235,7 +235,7 @@ struct pa_sink_input {
     void *userdata;
 };
 
-PA_DECLARE_CLASS(pa_sink_input);
+PA_DECLARE_PUBLIC_CLASS(pa_sink_input);
 #define PA_SINK_INPUT(o) pa_sink_input_cast(o)
 
 enum {
index fab8875505d05c0dbe287892ed14ccc13467cedb..5cec77473f3489f514b3a152b68f1659779f9dce 100644 (file)
@@ -52,7 +52,7 @@
 #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC)
 #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC)
 
-static PA_DEFINE_CHECK_TYPE(pa_sink, pa_msgobject);
+PA_DEFINE_PUBLIC_CLASS(pa_sink, pa_msgobject);
 
 static void sink_free(pa_object *s);
 
index 936d1c2a1db4fc97b2bdfd4fb8ad607bb480796e..b5284b713294c03419d9b340b7db48be54985020 100644 (file)
@@ -191,7 +191,7 @@ struct pa_sink {
     void *userdata;
 };
 
-PA_DECLARE_CLASS(pa_sink);
+PA_DECLARE_PUBLIC_CLASS(pa_sink);
 #define PA_SINK(s) (pa_sink_cast(s))
 
 typedef enum pa_sink_message {
index 502e5c69513618da8fde8c483763fac8a7c9393d..f41c53f3c8f86f7bc463ae24ba3874af034f674d 100644 (file)
@@ -64,9 +64,8 @@ enum {
     FILE_STREAM_MESSAGE_UNLINK
 };
 
-PA_DECLARE_CLASS(file_stream);
+PA_DEFINE_PRIVATE_CLASS(file_stream, pa_msgobject);
 #define FILE_STREAM(o) (file_stream_cast(o))
-static PA_DEFINE_CHECK_TYPE(file_stream, pa_msgobject);
 
 /* Called from main context */
 static void file_stream_unlink(file_stream *u) {
index 3803a6cc502b23b76a7c041cb7a99b7052703496..b0298616b036b940d5150cf5107b4c52889821b5 100644 (file)
@@ -41,7 +41,7 @@
 
 #define MEMBLOCKQ_MAXLENGTH (32*1024*1024)
 
-static PA_DEFINE_CHECK_TYPE(pa_source_output, pa_msgobject);
+PA_DEFINE_PUBLIC_CLASS(pa_source_output, pa_msgobject);
 
 static void source_output_free(pa_object* mo);
 
index a70a3fdbc29379669235311b1e07f75a5514d08a..aca9ddf28d03303d34a022664e73b81ae73966d1 100644 (file)
@@ -182,7 +182,7 @@ struct pa_source_output {
     void *userdata;
 };
 
-PA_DECLARE_CLASS(pa_source_output);
+PA_DECLARE_PUBLIC_CLASS(pa_source_output);
 #define PA_SOURCE_OUTPUT(o) pa_source_output_cast(o)
 
 enum {
index 8aa07f5e58c805873aa9bb1efc865a90975a0b30..3026654e3291c1e9967be965f1e49416450fe6ac 100644 (file)
@@ -46,7 +46,7 @@
 #define ABSOLUTE_MAX_LATENCY (10*PA_USEC_PER_SEC)
 #define DEFAULT_FIXED_LATENCY (250*PA_USEC_PER_MSEC)
 
-static PA_DEFINE_CHECK_TYPE(pa_source, pa_msgobject);
+PA_DEFINE_PUBLIC_CLASS(pa_source, pa_msgobject);
 
 static void source_free(pa_object *o);
 
index 7b3e4953561bbdacfc289c4731cdddb979dd74a8..df3f99df6909636d66d24e8cef219ec21043ddf1 100644 (file)
@@ -158,7 +158,7 @@ struct pa_source {
     void *userdata;
 };
 
-PA_DECLARE_CLASS(pa_source);
+PA_DECLARE_PUBLIC_CLASS(pa_source);
 #define PA_SOURCE(s) pa_source_cast(s)
 
 typedef enum pa_source_message {