aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2009-03-25 22:02:20 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2009-03-25 22:02:20 +0000
commit7b1e6ccc4e5c0cd147273a0d29afec2fe146fd4f (patch)
tree8e01f20ee75ccf3ca9329414bb33400fff9ca5bc /include
parent493c278a28ad31a01270866ebff960fa63ab0f0a (diff)
Merged revisions 184339 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ........ r184339 | russell | 2009-03-25 16:57:19 -0500 (Wed, 25 Mar 2009) | 35 lines Improve performance of the ast_event cache functionality. This code comes from svn/asterisk/team/russell/event_performance/. Here is a summary of the changes that have been made, in order of both invasiveness and performance impact, from smallest to largest. 1) Asterisk 1.6.1 introduces some additional logic to be able to handle distributed device state. This functionality comes at a cost. One relatively minor change in this patch is that the extra processing required for distributed device state is now completely bypassed if it's not needed. 2) One of the things that I noticed when profiling this code was that a _lot_ of time was spent doing string comparisons. I changed the way strings are represented in an event to include a hash value at the front. So, before doing a string comparison, we do an integer comparison on the hash. 3) Finally, the code that handles the event cache has been re-written. I tried to do this in a such a way that it had minimal impact on the API. I did have to change one API call, though - ast_event_queue_and_cache(). However, the way it works now is nicer, IMO. Each type of event that can be cached (MWI, device state) has its own hash table and rules for hashing and comparing objects. This by far made the biggest impact on performance. For additional details regarding this code and how it was tested, please see the review request. (closes issue #14738) Reported by: russell Review: http://reviewboard.digium.com/r/205/ ........ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@184342 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'include')
-rw-r--r--include/asterisk/_private.h2
-rw-r--r--include/asterisk/devicestate.h17
-rw-r--r--include/asterisk/event.h52
-rw-r--r--include/asterisk/strings.h23
4 files changed, 61 insertions, 33 deletions
diff --git a/include/asterisk/_private.h b/include/asterisk/_private.h
index fe9aa2c04..86db938c8 100644
--- a/include/asterisk/_private.h
+++ b/include/asterisk/_private.h
@@ -28,7 +28,7 @@ int dnsmgr_init(void); /*!< Provided by dnsmgr.c */
void dnsmgr_start_refresh(void); /*!< Provided by dnsmgr.c */
int dnsmgr_reload(void); /*!< Provided by dnsmgr.c */
void threadstorage_init(void); /*!< Provided by threadstorage.c */
-void ast_event_init(void); /*!< Provided by event.c */
+int ast_event_init(void); /*!< Provided by event.c */
int ast_device_state_engine_init(void); /*!< Provided by devicestate.c */
int astobj2_init(void); /*!< Provided by astobj2.c */
int ast_file_init(void); /*!< Provided by file.c */
diff --git a/include/asterisk/devicestate.h b/include/asterisk/devicestate.h
index b0bf5bfcf..5c053d0ca 100644
--- a/include/asterisk/devicestate.h
+++ b/include/asterisk/devicestate.h
@@ -37,6 +37,8 @@
#ifndef _ASTERISK_DEVICESTATE_H
#define _ASTERISK_DEVICESTATE_H
+#include "asterisk/channel.h"
+
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
@@ -259,6 +261,21 @@ struct ast_devstate_aggregate {
unsigned int ring:1;
};
+/*!
+ * \brief Enable distributed device state processing.
+ *
+ * \details
+ * By default, Asterisk assumes that device state change events will only be
+ * originating from one instance. If a module gets loaded and configured such
+ * that multiple instances of Asterisk will be sharing device state, this
+ * function should be called to enable distributed device state processing.
+ * It is off by default to save on unnecessary processing.
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_enable_distributed_devstate(void);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
diff --git a/include/asterisk/event.h b/include/asterisk/event.h
index 96cf9bd0a..ac42e5942 100644
--- a/include/asterisk/event.h
+++ b/include/asterisk/event.h
@@ -358,42 +358,18 @@ int ast_event_queue(struct ast_event *event);
*
* \param event the event to be queued and cached
*
- * The rest of the arguments to this function specify information elements to
- * use for determining which events in the cache that this event should replace.
- * All events in the cache that match the specified criteria will be removed from
- * the cache and then this one will be added. The arguments are specified in
- * the form:
- *
- * \code
- * <enum ast_event_ie_type>, [enum ast_event_ie_pltype]
- * \endcode
- * and must end with AST_EVENT_IE_END.
- *
- * If the ie_type specified is *not* AST_EVENT_IE_END, then it must be followed
- * by a valid IE payload type. If the payload type given is EXISTS, then all
- * events that contain that information element will be removed from the cache.
- * Otherwise, all events in the cache that contain an information element with
- * the same value as the new event will be removed.
- *
- * \note If more than one IE parameter is specified, they *all* must match for
- * the event to be removed from the cache.
- *
- * Example usage:
- *
- * \code
- * ast_event_queue_and_cache(event,
- * AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR,
- * AST_EVENT_IE_END);
- * \endcode
- *
- * This example queues and caches an event. Any events in the cache that have
- * the same MAILBOX information element as this event will be removed.
- *
+ * \details
* The purpose of caching events is so that the core can retain the last known
* information for events that represent some sort of state. That way, when
* code needs to find out the current state, it can query the cache.
+ *
+ * The event API already knows which events can be cached and how to cache them.
+ *
+ * \retval 0 success
+ * \retval non-zero failure. If failure is returned, the event must be destroyed
+ * by the caller of this function.
*/
-int ast_event_queue_and_cache(struct ast_event *event, ...);
+int ast_event_queue_and_cache(struct ast_event *event);
/*!
* \brief Retrieve an event from the cache
@@ -511,6 +487,18 @@ uint32_t ast_event_get_ie_uint(const struct ast_event *event, enum ast_event_ie_
const char *ast_event_get_ie_str(const struct ast_event *event, enum ast_event_ie_type ie_type);
/*!
+ * \brief Get the hash for the string payload of an IE
+ *
+ * \param event The event to get the IE from
+ * \param ie_type the type of information element to retrieve the hash for
+ *
+ * \return This function returns the hash value as calculated by ast_str_hash()
+ * for the string payload. This is stored in the event to avoid
+ * unnecessary string comparisons.
+ */
+uint32_t ast_event_get_ie_str_hash(const struct ast_event *event, enum ast_event_ie_type ie_type);
+
+/*!
* \brief Get the value of an information element that has a raw payload
*
* \param event The event to get the IE from
diff --git a/include/asterisk/strings.h b/include/asterisk/strings.h
index f232e1ed6..bec95d79c 100644
--- a/include/asterisk/strings.h
+++ b/include/asterisk/strings.h
@@ -717,6 +717,29 @@ static force_inline int ast_str_hash(const char *str)
}
/*!
+ * \brief Compute a hash value on a string
+ *
+ * \param[in] str The string to add to the hash
+ * \param[in] hash The hash value to add to
+ *
+ * \details
+ * This version of the function is for when you need to compute a
+ * string hash of more than one string.
+ *
+ * This famous hash algorithm was written by Dan Bernstein and is
+ * commonly used.
+ *
+ * \sa http://www.cse.yorku.ca/~oz/hash.html
+ */
+static force_inline int ast_str_hash_add(const char *str, int hash)
+{
+ while (*str)
+ hash = hash * 33 ^ *str++;
+
+ return abs(hash);
+}
+
+/*!
* \brief Compute a hash value on a case-insensitive string
*
* Uses the same hash algorithm as ast_str_hash, but converts