[asterisk-commits] murf: branch murf/fast-ast2 r87642 - in /team/murf/fast-ast2: apps/ include/a...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 30 14:00:35 CDT 2007


Author: murf
Date: Tue Oct 30 14:00:34 2007
New Revision: 87642

URL: http://svn.digium.com/view/asterisk?view=rev&rev=87642
Log:
This commit introduces the speedup that's in fast-ast3; and removes the debugs I inserted in pbx.c. They eat up a significant amount of cpu cycles even when they aren't logged. Without the debugs, the code is as fast as trunk in small-dialplan situations, and from 4 to 23 times faster when the dialplan gets big (around a 1000 of something); The speedup will be exponentially higher for dialplans bigger than that, compared to current trunk. In small-dialplan situations, there is neither speedup nor slowdowns. I feel much better about it now. Now, to make it worthy of a release, I need to make sure that it behaves well in reloads, unloads, extension/priority additions, deletions, etc.

Modified:
    team/murf/fast-ast2/apps/app_dial.c
    team/murf/fast-ast2/apps/app_macro.c
    team/murf/fast-ast2/include/asterisk/pbx.h
    team/murf/fast-ast2/main/pbx.c
    team/murf/fast-ast2/pbx/pbx_loopback.c

Modified: team/murf/fast-ast2/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast2/apps/app_dial.c?view=diff&rev=87642&r1=87641&r2=87642
==============================================================================
--- team/murf/fast-ast2/apps/app_dial.c (original)
+++ team/murf/fast-ast2/apps/app_dial.c Tue Oct 30 14:00:34 2007
@@ -1791,19 +1791,19 @@
 
 		if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
 			int autoloopflag;
+			int found;
 			strcpy(peer->exten, "h");
 			peer->priority = 1;
 			autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP);	/* save value to restore at the end */
 			ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
 			
-			while (ast_exists_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num)) {
-				if ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num))) {
-					/* Something bad happened, or a hangup has been requested. */
-					ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
-					ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
-					break;
-				}
+			while ((res = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found))) {
 				peer->priority++;
+			}
+			if (found && res) {
+				/* Something bad happened, or a hangup has been requested. */
+				ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
+				ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
 			}
 			ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);  /* set it back the way it was */
 		}

Modified: team/murf/fast-ast2/apps/app_macro.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast2/apps/app_macro.c?view=diff&rev=87642&r1=87641&r2=87642
==============================================================================
--- team/murf/fast-ast2/apps/app_macro.c (original)
+++ team/murf/fast-ast2/apps/app_macro.c Tue Oct 30 14:00:34 2007
@@ -271,6 +271,7 @@
 	while(ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
 		struct ast_context *c;
 		struct ast_exten *e;
+		int foundx;
 		runningapp[0] = '\0';
 		runningdata[0] = '\0';
 
@@ -299,7 +300,7 @@
 		/* Reset the macro depth, if it was changed in the last iteration */
 		pbx_builtin_setvar_helper(chan, "MACRO_DEPTH", depthc);
 
-		if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num))) {
+		if ((res = ast_spawn_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num, &foundx))) {
 			/* Something bad happened, or a hangup has been requested. */
 			if (((res >= '0') && (res <= '9')) || ((res >= 'A') && (res <= 'F')) ||
 		    	(res == '*') || (res == '#')) {

Modified: team/murf/fast-ast2/include/asterisk/pbx.h
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast2/include/asterisk/pbx.h?view=diff&rev=87642&r1=87641&r2=87642
==============================================================================
--- team/murf/fast-ast2/include/asterisk/pbx.h (original)
+++ team/murf/fast-ast2/include/asterisk/pbx.h Tue Oct 30 14:00:34 2007
@@ -522,7 +522,7 @@
  * \retval -1 on failure.
  */
 int ast_spawn_extension(struct ast_channel *c, const char *context, 
-	const char *exten, int priority, const char *callerid);
+      const char *exten, int priority, const char *callerid, int *found);
 
 /*! 
  * \brief Add a context include

Modified: team/murf/fast-ast2/main/pbx.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast2/main/pbx.c?view=diff&rev=87642&r1=87641&r2=87642
==============================================================================
--- team/murf/fast-ast2/main/pbx.c (original)
+++ team/murf/fast-ast2/main/pbx.c Tue Oct 30 14:00:34 2007
@@ -835,6 +835,7 @@
 	}
 }
 
+#ifdef NEED_DEBUG
 static void print_match_char_tree(struct match_char *node, char *prefix)
 {
 	char my_prefix[1024];
@@ -847,6 +848,7 @@
 	if (node->alt_char)
 		print_match_char_tree(node->alt_char, prefix);
 }
+#endif
 
 struct ast_exten *get_canmatch_exten(struct match_char *node)
 {
@@ -861,7 +863,6 @@
 void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid)
 {
 	struct match_char *p; /* note minimal stack storage requirements */
-	ast_log(LOG_DEBUG,"Looking for %s in match_char tree\n", str);
 	for (p=tree; p; p=p->alt_char)
 	{
 		if (p->x[0] == 'N' && p->x[1] == 0 && *str >= '2' && *str <= '9' ) {
@@ -994,17 +995,21 @@
 	char buf[256];
 	int already;
 	int specif;
+#ifdef NEED_DEBUG
 	int biggest_bucket, resizes, numobjs, numbucks;
 	
 	ast_log(LOG_DEBUG,"Creating Extension Trie for context %s\n", con->name);
 	ast_hashtab_get_stats(con->root_tree, &biggest_bucket, &resizes, &numobjs, &numbucks);
 	ast_log(LOG_DEBUG,"This tree has %d objects in %d bucket lists, longest list=%d objects, and has resized %d times\n",
 			numobjs, numbucks, biggest_bucket, resizes);
+#endif
 	t1 = ast_hashtab_start_traversal(con->root_tree);
 	while( (e1 = ast_hashtab_next(t1)) ) {
 		int pattern = 0;
 		char *s1 = e1->exten;
+#ifdef NEED_DEBUG
 		ast_log(LOG_DEBUG,"Adding exten %s to tree\n", s1);
+#endif
 		m1 = con->pattern_tree; /* each pattern starts over at the root of the pattern tree */
 		already = 1;
 
@@ -1380,19 +1385,11 @@
 	ast_rdlock_contexts();
 	if( contexts_tree ) {
 		tmp = ast_hashtab_lookup(contexts_tree,&item);
-		if (tmp)
-			ast_log(LOG_DEBUG,"Found context %s via HASH\n", tmp->name);
-		else
-			ast_log(LOG_DEBUG,"NOT Found context %s via HASH\n", name);
     } else {
 		while ( (tmp = ast_walk_contexts(tmp)) ) {
 			if (!name || !strcasecmp(name, tmp->name))
 				break;
 		}
-		if (tmp)
-			ast_log(LOG_DEBUG,"Found context %s via LIST\n", tmp->name);
-		else
-			ast_log(LOG_DEBUG,"NOT Found context %s via LIST\n", name);
 	}
 	ast_unlock_contexts();
 	return tmp;
@@ -1477,8 +1474,10 @@
 	if (!tmp->pattern_tree)
 	{
 		create_match_char_tree(tmp);
+#ifdef NEED_DEBUG
 		ast_log(LOG_DEBUG,"Tree Created in context %s:\n", context);
 		print_match_char_tree(tmp->pattern_tree," ");
+#endif
 	}
 	
 	new_find_extension(exten, &score, tmp->pattern_tree, 0, 0, callerid);
@@ -2357,8 +2356,8 @@
  * \retval  -1 on failure.
  */
 static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con,
-	const char *context, const char *exten, int priority,
-	const char *label, const char *callerid, enum ext_match_t action)
+  const char *context, const char *exten, int priority,
+  const char *label, const char *callerid, enum ext_match_t action, int *found)
 {
 	struct ast_exten *e;
 	struct ast_app *app;
@@ -2367,10 +2366,14 @@
 	char passdata[EXT_DATA_SIZE];
 
 	int matching_action = (action == E_MATCH || action == E_CANMATCH || action == E_MATCHMORE);
-
+	
 	ast_rdlock_contexts();
+	if (found)
+		*found = 0;
 	e = pbx_find_extension(c, con, &q, context, exten, priority, label, callerid, action);
 	if (e) {
+		if (found)
+			*found = 1;
 		if (matching_action) {
 			ast_unlock_contexts();
 			return -1;	/* success, we found it */
@@ -2886,32 +2889,32 @@
 
 int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 {
-	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH);
+	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCH, 0);
 }
 
 int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
 {
-	return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL);
+	return pbx_extension_helper(c, NULL, context, exten, 0, label, callerid, E_FINDLABEL, 0);
 }
 
 int ast_findlabel_extension2(struct ast_channel *c, struct ast_context *con, const char *exten, const char *label, const char *callerid)
 {
-	return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL);
+	return pbx_extension_helper(c, con, NULL, exten, 0, label, callerid, E_FINDLABEL, 0);
 }
 
 int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 {
-	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH);
+	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_CANMATCH, 0);
 }
 
 int ast_matchmore_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
 {
-	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE);
-}
-
-int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
-{
-	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN);
+	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_MATCHMORE, 0);
+}
+
+int ast_spawn_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid, int *found)
+{
+	return pbx_extension_helper(c, NULL, context, exten, priority, NULL, callerid, E_SPAWN, found);
 }
 
 /*! helper function to set extension and priority */
@@ -3008,50 +3011,7 @@
 		int digit = 0;
 
 		/* loop on priorities in this context/exten */
-		while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
-			found = 1;
-			if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
-				/* Something bad happened, or a hangup has been requested. */
-				if (strchr("0123456789ABCDEF*#", res)) {
-					ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
-					pos = 0;
-					dst_exten[pos++] = digit = res;
-					dst_exten[pos] = '\0';
-					break;
-				}
-				if (res == AST_PBX_KEEPALIVE) {
-					ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
-					ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
-					error = 1;
-					break;
-				}
-				ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
-				ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
-
- 				if ((res == AST_PBX_ERROR) && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
- 					/* if we are already on the 'e' exten, don't jump to it again */
- 					if (!strcmp(c->exten, "e")) {
- 						if (option_verbose > 1)
- 							ast_verbose(VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
- 						error = 1;
-						break;
- 					} else {
-						pbx_builtin_raise_exception(c, "ERROR");
- 						continue;
- 					}
- 				}
-
-				if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
-					c->_softhangup = 0;
-				} else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
-					/* atimeout, nothing bad */
-				} else {
-					if (c->cdr)
-						ast_cdr_update(c);
-					error = 1;
-					break;
-				}
-			}
+		while ( !(res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found))) {
 			if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT && ast_exists_extension(c, c->context, "T", 1, c->cid.cid_num)) {
 				set_ext_pri(c, "T", 0); /* 0 will become 1 with the c->priority++; at the end */
 				/* If the AbsoluteTimeout is not reset to 0, we'll get an infinite loop */
@@ -3070,6 +3030,45 @@
 			}
 			c->priority++;
 		} /* end while  - from here on we can use 'break' to go out */
+		if (found && res) {
+			/* Something bad happened, or a hangup has been requested. */
+			if (strchr("0123456789ABCDEF*#", res)) {
+				ast_debug(1, "Oooh, got something to jump out with ('%c')!\n", res);
+				pos = 0;
+				dst_exten[pos++] = digit = res;
+				dst_exten[pos] = '\0';
+			}
+			if (res == AST_PBX_KEEPALIVE) {
+				ast_debug(1, "Spawn extension (%s,%s,%d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
+				ast_verb(2, "Spawn extension (%s, %s, %d) exited KEEPALIVE on '%s'\n", c->context, c->exten, c->priority, c->name);
+				error = 1;
+			}
+			ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
+			ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
+			
+			if ((res == AST_PBX_ERROR) && ast_exists_extension(c, c->context, "e", 1, c->cid.cid_num)) {
+				/* if we are already on the 'e' exten, don't jump to it again */
+				if (!strcmp(c->exten, "e")) {
+					if (option_verbose > 1)
+						ast_verbose(VERBOSE_PREFIX_2 "Spawn extension (%s, %s, %d) exited ERROR while already on 'e' exten on '%s'\n", c->context, c->exten, c->priority, c->name);
+					error = 1;
+				} else {
+					pbx_builtin_raise_exception(c, "ERROR");
+					continue;
+				}
+			}
+			
+			if (c->_softhangup == AST_SOFTHANGUP_ASYNCGOTO) {
+				c->_softhangup = 0;
+			} else if (c->_softhangup == AST_SOFTHANGUP_TIMEOUT) {
+				/* atimeout, nothing bad */
+			} else {
+				if (c->cdr)
+					ast_cdr_update(c);
+				error = 1;
+				break;
+			}
+		}
 		if (error)
 			break;
 
@@ -3167,14 +3166,13 @@
 		if (c->cdr && ast_opt_end_cdr_before_h_exten)
 			ast_cdr_end(c->cdr);
 		set_ext_pri(c, "h", 1);
-		while (ast_exists_extension(c, c->context, c->exten, c->priority, c->cid.cid_num)) {
-			if ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num))) {
-				/* Something bad happened, or a hangup has been requested. */
-				ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
-				ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
-				break;
-			}
+		while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found))) {
 			c->priority++;
+		}
+		if (found && res) {
+			/* Something bad happened, or a hangup has been requested. */
+			ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
+			ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", c->context, c->exten, c->priority, c->name);
 		}
 	}
 	ast_set2_flag(c, autoloopflag, AST_FLAG_IN_AUTOLOOP);
@@ -3336,10 +3334,6 @@
 	strncpy(item.name, context, 256);
 	ast_rdlock_contexts();
 	c = ast_hashtab_lookup(contexts_tree,&item);
-	if (c)
-		ast_log(LOG_DEBUG,"Found context %s\n", c->name);
-	else
-		ast_log(LOG_DEBUG,"NOT Found context %s\n", context);
 
 #ifdef NOTNOW
 
@@ -4572,7 +4566,6 @@
 	int length = sizeof(struct ast_context) + strlen(name) + 1;
 
 	if (!contexts_tree) {
-		ast_log(LOG_DEBUG,"Creating Context Hash Table...\n");
 		contexts_tree = ast_hashtab_create(17,
 										   hashtab_compare_contexts, 
 										   ast_hashtab_resize_java,
@@ -5640,7 +5633,6 @@
 			ast_hashtab_insert_safe(tmp->peer_tree, tmp);
 
 		} else {  /* this is the first exten in this context */
-			/* ast_log(LOG_DEBUG, "Creating Hash Tables for exten/priorities/labels for %s/%s\n", con->name, extension); */
 			if (!con->root_tree)
 				con->root_tree = ast_hashtab_create(27,
 													hashtab_compare_extens,
@@ -5666,7 +5658,6 @@
 			ast_hashtab_insert_safe(con->root->peer_tree, tmp);
 		}
 		ast_hashtab_insert_safe(con->root_tree, tmp);
-		ast_log(LOG_DEBUG,"Added %s to %s's root tree, tree=%x, els=%d", tmp->exten, con->name, (unsigned int)con->root_tree, ast_hashtab_size(con->root_tree));
 		ast_unlock_context(con);
 		if (tmp->priority == PRIORITY_HINT)
 			ast_add_hint(tmp);

Modified: team/murf/fast-ast2/pbx/pbx_loopback.c
URL: http://svn.digium.com/view/asterisk/team/murf/fast-ast2/pbx/pbx_loopback.c?view=diff&rev=87642&r1=87641&r2=87642
==============================================================================
--- team/murf/fast-ast2/pbx/pbx_loopback.c (original)
+++ team/murf/fast-ast2/pbx/pbx_loopback.c Tue Oct 30 14:00:34 2007
@@ -141,8 +141,9 @@
 
 static int loopback_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
 {
+	int found;
 	LOOPBACK_COMMON;
-	res = ast_spawn_extension(chan, newcontext, newexten, newpriority, callerid);
+	res = ast_spawn_extension(chan, newcontext, newexten, newpriority, callerid, &found);
 	/* XXX hmmm... res is overridden ? */
 	if (newpattern && !ast_extension_match(newpattern, exten))
 		res = -1;




More information about the asterisk-commits mailing list