[asterisk-commits] tilghman: branch tilghman/malloc_hold-1.6.0 r244067 - in /team/tilghman/mallo...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Feb 1 11:15:40 CST 2010


Author: tilghman
Date: Mon Feb  1 11:15:38 2010
New Revision: 244067

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=244067
Log:
Merged changes, fixed conflicts, tested runtime

Modified:
    team/tilghman/malloc_hold-1.6.0/Makefile
    team/tilghman/malloc_hold-1.6.0/configure
    team/tilghman/malloc_hold-1.6.0/include/asterisk/astmm.h
    team/tilghman/malloc_hold-1.6.0/main/ast_expr2f.c
    team/tilghman/malloc_hold-1.6.0/main/astmm.c
    team/tilghman/malloc_hold-1.6.0/main/rtp.c

Modified: team/tilghman/malloc_hold-1.6.0/Makefile
URL: http://svnview.digium.com/svn/asterisk/team/tilghman/malloc_hold-1.6.0/Makefile?view=diff&rev=244067&r1=244066&r2=244067
==============================================================================
--- team/tilghman/malloc_hold-1.6.0/Makefile (original)
+++ team/tilghman/malloc_hold-1.6.0/Makefile Mon Feb  1 11:15:38 2010
@@ -288,7 +288,7 @@
 
 MOD_SUBDIRS:=channels pbx apps codecs formats cdr funcs tests main res $(LOCAL_MOD_SUBDIRS)
 OTHER_SUBDIRS:=utils agi
-SUBDIRS:=$(OTHER_SUBDIRS) $(MOD_SUBDIRS)
+SUBDIRS:=$(MOD_SUBDIRS) $(OTHER_SUBDIRS)
 SUBDIRS_INSTALL:=$(SUBDIRS:%=%-install)
 SUBDIRS_CLEAN:=$(SUBDIRS:%=%-clean)
 SUBDIRS_DIST_CLEAN:=$(SUBDIRS:%=%-dist-clean)

Modified: team/tilghman/malloc_hold-1.6.0/include/asterisk/astmm.h
URL: http://svnview.digium.com/svn/asterisk/team/tilghman/malloc_hold-1.6.0/include/asterisk/astmm.h?view=diff&rev=244067&r1=244066&r2=244067
==============================================================================
--- team/tilghman/malloc_hold-1.6.0/include/asterisk/astmm.h (original)
+++ team/tilghman/malloc_hold-1.6.0/include/asterisk/astmm.h Mon Feb  1 11:15:38 2010
@@ -54,6 +54,7 @@
 void *__ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
 void *__ast_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
 void *__ast_malloc(size_t size, const char *file, int lineno, const char *func);
+void *__ast_malloc_cache(size_t size, const char *file, int lineno, const char *func);
 void __ast_free(void *ptr, const char *file, int lineno, const char *func);
 void *__ast_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func);
 char *__ast_strdup(const char *s, const char *file, int lineno, const char *func);
@@ -62,10 +63,78 @@
 	__attribute__((format(printf, 5, 6)));
 int __ast_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func)
 	__attribute__((format(printf, 2, 0)));
+void *__ast_hold_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
+void *__ast_hold_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func);
+void *__ast_hold_malloc(size_t size, const char *file, int lineno, const char *func);
+void *__ast_hold_malloc_cache(size_t size, const char *file, int lineno, const char *func);
+void *__ast_hold_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func);
+char *__ast_hold_strdup(const char *s, const char *file, int lineno, const char *func);
+char *__ast_hold_strndup(const char *s, size_t n, const char *file, int lineno, const char *func);
+int __ast_hold_asprintf(const char *file, int lineno, const char *func, char **strp, const char *format, ...) __attribute__((format(printf, 5, 6)));
+int __ast_hold_vasprintf(char **strp, const char *format, va_list ap, const char *file, int lineno, const char *func) __attribute__((format(printf, 2, 0)));
+
 void __ast_mm_init(void);
 
 
 /* Provide our own definitions */
+#ifdef MALLOC_HOLD
+
+#define calloc(a,b) \
+	__ast_hold_calloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_calloc(a,b) \
+	__ast_hold_calloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_calloc_cache(a,b) \
+	__ast_hold_calloc_cache(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define malloc(a) \
+	__ast_hold_malloc(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_malloc(a) \
+	__ast_hold_malloc(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_malloc_cache(a) \
+	__ast_hold_malloc_cache(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define free(a) \
+	__ast_free(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_free(a) \
+	__ast_free(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define realloc(a,b) \
+	__ast_hold_realloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_realloc(a,b) \
+	__ast_hold_realloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define strdup(a) \
+	__ast_hold_strdup(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_strdup(a) \
+	__ast_hold_strdup(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define strndup(a,b) \
+	__ast_hold_strndup(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_strndup(a,b) \
+	__ast_hold_strndup(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define asprintf(a, b, c...) \
+	__ast_hold_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, b, c)
+
+#define ast_asprintf(a, b, c...) \
+	__ast_hold_asprintf(__FILE__, __LINE__, __PRETTY_FUNCTION__, a, b, c)
+
+#define vasprintf(a,b,c) \
+	__ast_hold_vasprintf(a,b,c,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#define ast_vasprintf(a,b,c) \
+	__ast_hold_vasprintf(a,b,c,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#else /* !defined(MALLOC_HOLD) */
+
 #define calloc(a,b) \
 	__ast_calloc(a,b,__FILE__, __LINE__, __PRETTY_FUNCTION__)
 
@@ -81,6 +150,9 @@
 #define ast_malloc(a) \
 	__ast_malloc(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
 
+#define ast_malloc_cache(a) \
+	__ast_malloc_cache(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
+
 #define free(a) \
 	__ast_free(a,__FILE__, __LINE__, __PRETTY_FUNCTION__)
 
@@ -117,6 +189,7 @@
 #define ast_vasprintf(a,b,c) \
 	__ast_vasprintf(a,b,c,__FILE__, __LINE__, __PRETTY_FUNCTION__)
 
+#endif /* defined(MALLOC_HOLD) */
 #endif /* !STANDALONE */
 
 #else

Modified: team/tilghman/malloc_hold-1.6.0/main/ast_expr2f.c
URL: http://svnview.digium.com/svn/asterisk/team/tilghman/malloc_hold-1.6.0/main/ast_expr2f.c?view=diff&rev=244067&r1=244066&r2=244067
==============================================================================
--- team/tilghman/malloc_hold-1.6.0/main/ast_expr2f.c (original)
+++ team/tilghman/malloc_hold-1.6.0/main/ast_expr2f.c Mon Feb  1 11:15:38 2010
@@ -11,7 +11,7 @@
 #define FLEX_SCANNER
 #define YY_FLEX_MAJOR_VERSION 2
 #define YY_FLEX_MINOR_VERSION 5
-#define YY_FLEX_SUBMINOR_VERSION 33
+#define YY_FLEX_SUBMINOR_VERSION 35
 #if YY_FLEX_SUBMINOR_VERSION > 0
 #define FLEX_BETA
 #endif
@@ -33,7 +33,7 @@
 
 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
 
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ >= 199901L
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 
 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
  * if you want the limit (max/min) macros for int types. 
@@ -96,11 +96,12 @@
 
 #else	/* ! __cplusplus */
 
-#if __STDC__
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
 
 #define YY_USE_CONST
 
-#endif	/* __STDC__ */
+#endif	/* defined (__STDC__) */
 #endif	/* ! __cplusplus */
 
 #ifdef YY_USE_CONST
@@ -135,8 +136,6 @@
 #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
 #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
 #define yy_flex_debug yyg->yy_flex_debug_r
-
-int ast_yylex_init (yyscan_t* scanner);
 
 /* Enter a start condition.  This macro really ought to take a parameter,
  * but we do it the disgusting crufty way forced on us by the ()-less
@@ -195,14 +194,9 @@
 
 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
 
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-
 #ifndef YY_TYPEDEF_YY_SIZE_T
 #define YY_TYPEDEF_YY_SIZE_T
-typedef unsigned int yy_size_t;
+typedef size_t yy_size_t;
 #endif
 
 #ifndef YY_STRUCT_YY_BUFFER_STATE
@@ -555,6 +549,11 @@
 #include "asterisk/channel.h"
 #endif
 
+/*!\note The latest Flex uses fwrite without checking its return value, which
+ * is a warning on some compilers.  Therefore, we use this workaround, to trick
+ * the compiler into suppressing this warning. */
+#define fwrite(a,b,c,d)	do { int __res = fwrite(a,b,c,d); (__res); } while (0)
+
 enum valtype {
 	AST_EXPR_number, AST_EXPR_numeric_string, AST_EXPR_string
 } ;
@@ -600,7 +599,7 @@
 static int curlycount = 0;
 static char *expr2_token_subst(const char *mess);
 
-#line 602 "ast_expr2f.c"
+#line 601 "ast_expr2f.c"
 
 #define INITIAL 0
 #define var 1
@@ -664,6 +663,10 @@
     
     #    define yylloc yyg->yylloc_r
     
+int ast_yylex_init (yyscan_t* scanner);
+
+int ast_yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
 /* Accessor methods to globals.
    These are made visible to non-reentrant scanners for convenience. */
 
@@ -743,7 +746,7 @@
 /* This used to be an fputs(), but since the string might contain NUL's,
  * we now use fwrite().
  */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
 #endif
 
 /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
@@ -754,7 +757,7 @@
 	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
 		{ \
 		int c = '*'; \
-		size_t n; \
+		int n; \
 		for ( n = 0; n < max_size && \
 			     (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
 			buf[n] = (char) c; \
@@ -808,9 +811,11 @@
 #ifndef YY_DECL
 #define YY_DECL_IS_OURS 1
 
-extern int ast_yylex (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
-
-#define YY_DECL int ast_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+extern int ast_yylex \
+               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int ast_yylex \
+               (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
 #endif /* !YY_DECL */
 
 /* Code executed at the beginning of each rule, after yytext and yyleng
@@ -837,10 +842,10 @@
 	register int yy_act;
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
 
-#line 125 "ast_expr2.fl"
-
-
-#line 842 "ast_expr2f.c"
+#line 130 "ast_expr2.fl"
+
+
+#line 847 "ast_expr2f.c"
 
     yylval = yylval_param;
 
@@ -931,127 +936,127 @@
 
 case 1:
 YY_RULE_SETUP
-#line 127 "ast_expr2.fl"
+#line 132 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_OR;}
 	YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 128 "ast_expr2.fl"
+#line 133 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_AND;}
 	YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 129 "ast_expr2.fl"
+#line 134 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_EQ;}
 	YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 130 "ast_expr2.fl"
+#line 135 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_OR;}
 	YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 131 "ast_expr2.fl"
+#line 136 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_AND;}
 	YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 132 "ast_expr2.fl"
+#line 137 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_EQ;}
 	YY_BREAK
 case 7:
 YY_RULE_SETUP
-#line 133 "ast_expr2.fl"
+#line 138 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
 	YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 134 "ast_expr2.fl"
+#line 139 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_GT;}
 	YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 135 "ast_expr2.fl"
+#line 140 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_LT;}
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 136 "ast_expr2.fl"
+#line 141 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_GE;}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 137 "ast_expr2.fl"
+#line 142 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_LE;}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 138 "ast_expr2.fl"
+#line 143 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_NE;}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 139 "ast_expr2.fl"
+#line 144 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_PLUS;}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 140 "ast_expr2.fl"
+#line 145 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_COMMA;}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 141 "ast_expr2.fl"
+#line 146 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_MINUS;}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 142 "ast_expr2.fl"
+#line 147 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_MULT;}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 143 "ast_expr2.fl"
+#line 148 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_DIV;}
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 144 "ast_expr2.fl"
+#line 149 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_MOD;}
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 145 "ast_expr2.fl"
+#line 150 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_COND;}
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 146 "ast_expr2.fl"
+#line 151 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_COMPL;}
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 147 "ast_expr2.fl"
+#line 152 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_COLON;}
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 148 "ast_expr2.fl"
+#line 153 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 149 "ast_expr2.fl"
+#line 154 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_LP;}
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 150 "ast_expr2.fl"
+#line 155 "ast_expr2.fl"
 { SET_COLUMNS; SET_STRING; return TOK_RP;}
 	YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 151 "ast_expr2.fl"
+#line 156 "ast_expr2.fl"
 {
 		/* gather the contents of ${} expressions, with trailing stuff,
 		 * into a single TOKEN.
@@ -1064,24 +1069,24 @@
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 161 "ast_expr2.fl"
+#line 166 "ast_expr2.fl"
 {}
 	YY_BREAK
 case 27:
 /* rule 27 can match eol */
 YY_RULE_SETUP
-#line 162 "ast_expr2.fl"
+#line 167 "ast_expr2.fl"
 {SET_COLUMNS; SET_STRING; return TOKEN;}
 	YY_BREAK
 case 28:
 /* rule 28 can match eol */
 YY_RULE_SETUP
-#line 164 "ast_expr2.fl"
+#line 169 "ast_expr2.fl"
 {/* what to do with eol */}
 	YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 165 "ast_expr2.fl"
+#line 170 "ast_expr2.fl"
 {
 		SET_COLUMNS;
 		/* the original behavior of the expression parser was
@@ -1094,7 +1099,7 @@
 case 30:
 /* rule 30 can match eol */
 YY_RULE_SETUP
-#line 174 "ast_expr2.fl"
+#line 179 "ast_expr2.fl"
 {
 		SET_COLUMNS;
 		SET_STRING;
@@ -1104,7 +1109,7 @@
 case 31:
 /* rule 31 can match eol */
 YY_RULE_SETUP
-#line 180 "ast_expr2.fl"
+#line 185 "ast_expr2.fl"
 {
 		curlycount = 0;
 		BEGIN(var);
@@ -1114,7 +1119,7 @@
 case 32:
 /* rule 32 can match eol */
 YY_RULE_SETUP
-#line 186 "ast_expr2.fl"
+#line 191 "ast_expr2.fl"
 {
 		curlycount--;
 		if (curlycount < 0) {
@@ -1128,7 +1133,7 @@
 case 33:
 /* rule 33 can match eol */
 YY_RULE_SETUP
-#line 196 "ast_expr2.fl"
+#line 201 "ast_expr2.fl"
 {
 		curlycount++;
 		yymore();
@@ -1136,7 +1141,7 @@
 	YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 202 "ast_expr2.fl"
+#line 207 "ast_expr2.fl"
 {
 		BEGIN(0);
 		SET_COLUMNS;
@@ -1146,7 +1151,7 @@
 	YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 209 "ast_expr2.fl"
+#line 214 "ast_expr2.fl"
 {
 		curlycount = 0;
 		BEGIN(var);
@@ -1156,7 +1161,7 @@
 case 36:
 /* rule 36 can match eol */
 YY_RULE_SETUP
-#line 215 "ast_expr2.fl"
+#line 220 "ast_expr2.fl"
 {
 		char c = yytext[yyleng-1];
 		BEGIN(0);
@@ -1167,7 +1172,7 @@
 	}
 	YY_BREAK
 case YY_STATE_EOF(trail):
-#line 224 "ast_expr2.fl"
+#line 229 "ast_expr2.fl"
 {
 		BEGIN(0);
 		SET_COLUMNS;
@@ -1178,10 +1183,10 @@
 	YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 232 "ast_expr2.fl"
+#line 237 "ast_expr2.fl"
 ECHO;
 	YY_BREAK
-#line 1183 "ast_expr2f.c"
+#line 1188 "ast_expr2f.c"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(var):
 	yyterminate();
@@ -1415,7 +1420,7 @@
 
 		/* Read in more data. */
 		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
-			yyg->yy_n_chars, num_to_read );
+			yyg->yy_n_chars, (size_t) num_to_read );
 
 		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
 		}
@@ -1438,6 +1443,14 @@
 
 	else
 		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+		/* Extend the array by 50%, plus the number we really need. */
+		yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+		YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) ast_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+		if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+	}
 
 	yyg->yy_n_chars += number_to_move;
 	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
@@ -1867,7 +1880,9 @@
 		yyg->yy_buffer_stack = (struct yy_buffer_state**)ast_yyalloc
 								(num_to_alloc * sizeof(struct yy_buffer_state*)
 								, yyscanner);
-		
+		if ( ! yyg->yy_buffer_stack )
+			YY_FATAL_ERROR( "out of dynamic memory in ast_yyensure_buffer_stack()" );
+								  
 		memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
 				
 		yyg->yy_buffer_stack_max = num_to_alloc;
@@ -1885,6 +1900,8 @@
 								(yyg->yy_buffer_stack,
 								num_to_alloc * sizeof(struct yy_buffer_state*)
 								, yyscanner);
+		if ( ! yyg->yy_buffer_stack )
+			YY_FATAL_ERROR( "out of dynamic memory in ast_yyensure_buffer_stack()" );
 
 		/* zero only the new slots.*/
 		memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
@@ -1929,7 +1946,7 @@
 
 /** Setup the input buffer state to scan a string. The next call to ast_yylex() will
  * scan from a @e copy of @a str.
- * @param str a NUL-terminated string to scan
+ * @param yystr a NUL-terminated string to scan
  * @param yyscanner The scanner object.
  * @return the newly allocated buffer state object.
  * @note If you want to scan bytes that may contain NUL values, then use
@@ -2203,6 +2220,42 @@
     return yy_init_globals ( *ptr_yy_globals );
 }
 
+/* ast_yylex_init_extra has the same functionality as ast_yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to ast_yyalloc in
+ * the yyextra field.
+ */
+
+int ast_yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+    struct yyguts_t dummy_yyguts;
+
+    ast_yyset_extra (yy_user_defined, &dummy_yyguts);
+
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+	
+    *ptr_yy_globals = (yyscan_t) ast_yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+	
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+    
+    /* By setting to 0xAA, we expose bugs in
+    yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+    
+    ast_yyset_extra (yy_user_defined, *ptr_yy_globals);
+    
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
 static int yy_init_globals (yyscan_t yyscanner)
 {
     struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
@@ -2309,7 +2362,7 @@
 
 #define YYTABLES_NAME "yytables"
 
-#line 232 "ast_expr2.fl"
+#line 237 "ast_expr2.fl"
 
 
 

Modified: team/tilghman/malloc_hold-1.6.0/main/astmm.c
URL: http://svnview.digium.com/svn/asterisk/team/tilghman/malloc_hold-1.6.0/main/astmm.c?view=diff&rev=244067&r1=244066&r2=244067
==============================================================================
--- team/tilghman/malloc_hold-1.6.0/main/astmm.c (original)
+++ team/tilghman/malloc_hold-1.6.0/main/astmm.c Mon Feb  1 11:15:38 2010
@@ -32,6 +32,12 @@
 #include "asterisk/paths.h"	/* use ast_config_AST_LOG_DIR */
 #include <stddef.h>
 #include <time.h>
+#include <sys/mman.h>
+#include <signal.h>
+#if !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__Darwin__)
+#include <malloc.h>
+#endif
+#include <errno.h>
 
 #include "asterisk/cli.h"
 #include "asterisk/lock.h"
@@ -39,6 +45,30 @@
 #include "asterisk/unaligned.h"
 
 #define SOME_PRIME 563
+
+#define FREE_LIST SOME_PRIME
+#define POLLUTED_LIST SOME_PRIME + 1
+#define AVAILABLE_LIST SOME_PRIME + 2
+
+#define HOLD_LENGTH 90
+
+/* Cannot include utils.h, as it defines things that this file implements,
+ * but could eventually put these defines in a separate header file. */
+int ast_pthread_create_stack(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *),
+			     void *data, size_t stacksize, const char *file, const char *caller,
+			     int line, const char *start_fn);
+#define AST_STACKSIZE (((sizeof(void *) * 8 * 8) - 16) * 1024)
+
+#if defined(LOW_MEMORY)
+#define AST_BACKGROUND_STACKSIZE (((sizeof(void *) * 8 * 2) - 16) * 1024)
+#else
+#define AST_BACKGROUND_STACKSIZE AST_STACKSIZE
+#endif
+
+#define ast_pthread_create_background(a, b, c, d) ast_pthread_create_stack(a, b, c, d,			\
+									   AST_BACKGROUND_STACKSIZE,	\
+									   __FILE__, __FUNCTION__,	\
+									   __LINE__, #c)
 
 enum func_type {
 	FUNC_CALLOC = 1,
@@ -62,7 +92,19 @@
 
 #define FENCE_MAGIC 0xdeadbeef
 
-static FILE *mmlog;
+static FILE *mmlog = NULL;
+
+static ssize_t pagesize = -1;
+static struct sigaction default_sigsegv;
+
+static struct violations {
+	void *base_addr;
+	void *violation;
+	int error;
+	time_t when;
+} violations[100] = { { NULL, } };
+
+static int last_violation = -1;
 
 /* NOTE: Be EXTREMELY careful with modifying this structure; the total size of this structure
    must result in 'automatic' alignment so that the 'fence' field lands exactly at the end of
@@ -79,14 +121,24 @@
 static struct ast_region {
 	struct ast_region *next;
 	size_t len;
-	char file[64];
-	char func[40];
-	unsigned int lineno;
+	size_t fullsize;
+	char free_file[64];
+	char free_func[40];
+	unsigned int free_lineno;
+	unsigned int freetime;
+	int mperm;
+	int operation;
+	void *vlocation;
+	char alloc_file[64];
+	char alloc_func[40];
+	unsigned int alloc_lineno;
 	enum func_type which;
 	unsigned int cache;		/* region was allocated as part of a cache pool */
 	unsigned int fence;
 	unsigned char data[0];
-} *regions[SOME_PRIME];
+} *regions[SOME_PRIME + 3];
+
+static struct ast_region *lastfree = NULL;
 
 #define HASH(a) \
 	(((unsigned long)(a)) % SOME_PRIME)
@@ -104,22 +156,321 @@
 		}                                    \
 	} while (0)
 
-static inline void *__ast_alloc_region(size_t size, const enum func_type which, const char *file, int lineno, const char *func, unsigned int cache)
+#define MPROTECT(a,b,c) \
+	do { \
+		int __p = c; \
+		if (mprotect(a,b,c)) { \
+			fprintf(stderr, "Cannot set memory protections '%s' (%d) on %p: %s\n", \
+				__p == PROT_NONE ? "PROT_NONE" : __p == PROT_READ ? "PROT_READ" : __p == (PROT_READ | PROT_WRITE) ? "PROT_READ|PROT_WRITE" : "unknown", \
+				__p, a, strerror(errno)); \
+			abort(); \
+		} \
+	} while (0)
+
+static void *memory_reporter(void *notused)
+{
+	struct ast_region *cur;
+	int last_seen_violation = 0;
+	for (;;) {
+		/* Any errors to report? */
+		if (last_violation != -1) {
+			for (; last_seen_violation != last_violation;
+					last_seen_violation = (last_seen_violation == ARRAY_LEN(violations) - 1) ? 0 : last_seen_violation + 1) {
+				if ((cur = violations[last_seen_violation].base_addr) == NULL) {
+					memset(&violations[last_seen_violation], 0, sizeof(violations[0]));
+					continue;
+				}
+
+				astmm_log("Intercepted invalid %s to %p (%p+%d), originally allocated in %s at %s:%u and freed in %s at %s:%u\n",
+					violations[last_seen_violation].error == PROT_READ ? "read" : "write",
+					violations[last_seen_violation].violation, cur->data,
+					(int) (violations[last_seen_violation].violation - (void *) cur->data),
+					cur->alloc_func, cur->alloc_file, cur->alloc_lineno,
+					cur->free_func, cur->free_file, cur->free_lineno);
+				memset(&violations[last_seen_violation], 0, sizeof(violations[0]));
+				MPROTECT(cur, cur->fullsize, PROT_READ | PROT_WRITE);
+				cur->operation = 0;
+				cur->mperm = PROT_NONE;
+				MPROTECT(cur, cur->fullsize, PROT_NONE);
+			}
+		}
+		sleep(5);
+	}
+	return NULL;
+}
+
+static void *memory_destructor(void *notused)
+{
+	struct ast_region *cur;
+	for (;;) {
+		ast_mutex_lock(&reglock);
+		/* Delete any segment which is free for at least HOLD_LENGTH seconds */
+		while ((cur = regions[FREE_LIST]) && !mprotect(cur, sizeof(*cur), PROT_READ) && cur->freetime < time(NULL) - HOLD_LENGTH) {
+			int i;
+
+			MPROTECT(cur, cur->fullsize, PROT_READ | PROT_WRITE);
+
+			cur->mperm = PROT_READ | PROT_WRITE;
+			regions[FREE_LIST] = cur->next;
+			if (cur == lastfree) {
+				lastfree = NULL;
+			}
+#if 0 /* Verification that this thread is running only */
+			astmm_log("Freeing memory at %p (size %d, originally allocated in %s of %s, line %d)\n", cur->data, cur->len, cur->alloc_func, cur->alloc_file, cur->alloc_lineno);
+#endif
+			if (cur->operation) {
+				for (i = 0; i < ARRAY_LEN(violations); i++) {
+					if (cur == violations[i].base_addr) {
+						astmm_log("Intercepted invalid %s to %p (%p+%d), originally allocated in %s at %s:%u and freed in %s at %s:%u\n",
+							violations[i].error == PROT_READ ? "read" : "write",
+							violations[i].violation, cur->data,
+							(int) (violations[i].violation - (void *) cur->data),
+							cur->alloc_func, cur->alloc_file, cur->alloc_lineno,
+							cur->free_func, cur->free_file, cur->free_lineno);
+						memset(&violations[i], 0, sizeof(violations[i]));
+						break;
+					}
+				}
+			}
+
+			/* If memory was read/written incorrectly, move it to the "polluted" list; 
+			 * otherwise, move it to the available list. */
+			if (cur->vlocation) {
+				cur->next = regions[POLLUTED_LIST];
+				regions[POLLUTED_LIST] = cur;
+			} else {
+				cur->next = regions[AVAILABLE_LIST];
+				regions[AVAILABLE_LIST] = cur;
+			}
+		}
+		if ((cur = regions[FREE_LIST])) {
+			int sleep_time = HOLD_LENGTH - (time(NULL) - cur->freetime);
+
+			/* Re-protect region opened to reads while we examined cur->freetime (in previous loop) */
+			MPROTECT(cur, sizeof(*cur), PROT_NONE);
+
+			ast_mutex_unlock(&reglock);
+			if (sleep_time > 0) {
+				sleep(sleep_time);
+			} else {
+				sched_yield();
+			}
+		} else {
+			ast_mutex_unlock(&reglock);
+			astmm_log("Nothing in free list.  Sleeping for %d seconds.\n", HOLD_LENGTH);
+			sleep(HOLD_LENGTH);
+		}
+	}
+	/* Never reached */
+	return NULL;
+}
+
+static void handle_sigsegv(int signal, siginfo_t *info, void *unused)
+{
+	struct ast_region *cur;
+
+	if (info->si_code == SEGV_MAPERR) {
+		fprintf(stderr, "Stepped on invalid page: %p\n", info->si_addr);
+		abort();
+	}
+
+	/* Access violation errors are the only things I handle;
+	 * anything else goes to the default handler. */
+	if (info->si_code != SEGV_ACCERR || info->si_addr == NULL) {
+		if (default_sigsegv.sa_flags & SA_SIGINFO && default_sigsegv.sa_sigaction != NULL) {
+			(default_sigsegv.sa_sigaction)(signal, info, unused);
+		} else if (default_sigsegv.sa_handler != NULL) {
+			(default_sigsegv.sa_handler)(signal);
+		} else {
+			abort();
+		}
+		return;
+	}
+
+	/* Find base address */
+	cur = (void *) ((size_t) info->si_addr - ((size_t) info->si_addr % pagesize));
+	MPROTECT(cur, sizeof(*cur), PROT_READ);
+	while (cur->fence != FENCE_MAGIC && cur->len > cur->fullsize) {
+		/*!
+		 * This loop is kind of weird.  By calling this routine, we expect that
+		 * the memory segment is one allocated by us, so this should terminate
+		 * when we find FENCE_MAGIC.  OTOH, it's possible that this wasn't us,
+		 * and we'll eventually step on something that wasn't an access problem,
+		 * the signal handler will fire again, call the default handler, and we'll
+		 * crash.  That is what we'd expect to happen, anyway, if this wasn't our
+		 * segment, so all is good.
+		 */
+		cur -= pagesize;
+		MPROTECT(cur, sizeof(*cur), PROT_READ);
+	}
+
+	/*!
+	 * The general rule of thumb is don't try to allocate memory or output to a
+	 * file descriptor in a signal handler.  Therefore, we must otherwise raise
+	 * flags for later reporting.  This might not be completely true, but
+	 * consider what signal handler this is.  This isn't the place to split
+	 * hairs.
+	 */
+	if (cur->mperm == PROT_READ) {
+		int newperm = PROT_READ | PROT_WRITE;
+		/* Need to modify cur, so let us write */
+		MPROTECT(cur, cur->fullsize, newperm);
+		cur->mperm = newperm;
+		if (cur->vlocation == info->si_addr) {
+			cur->operation = PROT_WRITE;
+			if (violations[last_violation].base_addr == cur && violations[last_violation].violation == info->si_addr) {
+				violations[last_violation].error = PROT_WRITE;
+			}
+		}
+	} else {
+		/* Error in astmm code */
+		if ((void *) cur->data > (void *) info->si_addr) {
+			/* Extra cast above due to OpenBSD */
+			abort();
+		}
+		/* We're about to modify, so let us write */
+		MPROTECT(cur, cur->fullsize, PROT_READ | PROT_WRITE);
+		cur->mperm = PROT_READ;
+		cur->vlocation = info->si_addr;
+		cur->operation = PROT_READ;
+		MPROTECT(cur, cur->fullsize, cur->mperm);
+
+		if (++last_violation >= ARRAY_LEN(violations)) {
+			last_violation = 0;
+		}
+		violations[last_violation].base_addr = cur;
+		violations[last_violation].violation = info->si_addr;
+		violations[last_violation].when = time(NULL);
+		violations[last_violation].error = cur->operation;
+	}
+
+	/*!
+	 * Okay, if we've done our job right, we now know that the user
+	 * stepped on memory that was freed, we've intercepted that access,
+	 * allowed the memory to be read/written, and return.  This will allow
+	 * the (previously illegal) operation to continue, as if the segfault
+	 * never actually occurred.  Yes, that seems weird, but that's the way
+	 * this signal works.
+	 *
+	 * Now here's the interesting part.  This signal handler will get
+	 * re-entered immediately if we didn't clear the right protection, which
+	 * is what we designed, when we differentiate between an attempted read
+	 * (which won't come back) and a write (which will).  We can therefore
+	 * determine which type of access occurred to free'd memory.
+	 *
+	 * The rub is that once we unprotect this memory, we cannot easily
+	 * re-protect the memory, since returning releases the control from the
+	 * signal handler.  Thus, we only will detect the FIRST illegal access
+	 * of (this segment of) free'd memory, not any subsequent.  This hopefully
+	 * is sufficient for our purposes.
+	 */
+}
+
+static void mm_cleanup(void)
 {
 	struct ast_region *reg;
+	ast_mutex_lock(&reglock);
+	while ((reg = regions[FREE_LIST])) {
+		MPROTECT(reg, sizeof(*reg), PROT_READ | PROT_WRITE);
+		MPROTECT(reg, reg->fullsize, PROT_READ | PROT_WRITE);
+		reg->operation = 0;
+		regions[FREE_LIST] = reg->next;
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__Darwin__)
+		munmap(reg, reg->fullsize);
+#else
+		free(reg);
+#endif
+	}
+	ast_mutex_unlock(&reglock);
+}
+
+static inline void *__ast_hold_alloc_region(size_t size, const enum func_type which, const char *file, int lineno, const char *func, unsigned int cache)
+{
+	struct ast_region *reg = NULL;
 	void *ptr = NULL;
 	unsigned int *fence;
 	int hash;
-
-	if (!(reg = malloc(size + sizeof(*reg) + sizeof(*fence)))) {
+	struct ast_region *prev = NULL, *best_prev = NULL, *best_reg = NULL;
+	size_t fullsize = size + sizeof(*reg) + sizeof(*fence);
+
+	if (pagesize == -1 && (pagesize = sysconf(_SC_PAGESIZE)) == -1) {
+		ast_log(LOG_ERROR, "Cannot retrieve system memory page size?");
+		abort();
+	}
+
+	if (!cache) {
+		/*!
+		 * What, expand the size to cover the full page?  Doesn't that eat memory?
+		 * Yes, but consider that we aren't the only consumers of memory in this
+		 * process.  Supposing we only allocated half a page.  Malloc would be free
+		 * to allocate the remaining space to something else, like perhaps a libc
+		 * internal structure.  If we then protect that memory, and libc tries to
+		 * access it, we flag a memory error where none existed.  Thus, we must
+		 * only allocate full memory pages.
+		 */
+		fullsize = (fullsize / pagesize) * pagesize == fullsize ? fullsize : ((fullsize / pagesize) + 1) * pagesize;
+		/* Look for memory in our available list, first */
+		ast_mutex_lock(&reglock);
+		for (reg = regions[AVAILABLE_LIST]; reg; prev = reg, reg = reg->next) {
+			if (fullsize < reg->fullsize) {
+				/* Not big enough */
+				continue;
+			}
+
+			if (reg->fullsize == fullsize) {
+				if (prev) {
+					prev->next = reg->next;
+				} else {
+					regions[AVAILABLE_LIST] = reg->next;
+				}
+				/* Don't let the indicated size shrink to below the actual size. */
+				fullsize = reg->fullsize;
+				break;
+			}
+
+			/* If I don't find an exact match, then find me the smallest available
+			 * block that matches my needs. */
+			if (!best_reg || best_reg->fullsize > reg->fullsize) {
+				best_reg = reg;
+				best_prev = prev;
+			}
+		}
+
+		if (!reg && best_reg) {
+			reg = best_reg;
+			/* Remove it from the available list */
+			if (best_prev) {
+				best_prev->next = reg->next;
+			} else {
+				regions[AVAILABLE_LIST] = reg->next;
+			}
+			/* Don't let the indicated size shrink to below the actual size. */
+			fullsize = reg->fullsize;
+		}
+		ast_mutex_unlock(&reglock);
+	}
+
+	/* Do I need a new allocation? */
+	if ((cache && !(reg = malloc(fullsize))) ||
+#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__Darwin__)
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+		(!cache && !reg && (reg = mmap(NULL, fullsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)
+#else
+		(!cache && !reg && !(reg = memalign(pagesize, fullsize)))
+#endif
+			) {
 		astmm_log("Memory Allocation Failure - '%d' bytes in function %s "
 			  "at line %d of %s\n", (int) size, func, lineno, file);
-	}
-
-	ast_copy_string(reg->file, file, sizeof(reg->file));
-	ast_copy_string(reg->func, func, sizeof(reg->func));
-	reg->lineno = lineno;
+		return NULL;
+	}
+
+	ast_copy_string(reg->alloc_file, file + (strlen(file) > sizeof(reg->alloc_file) - 1 ? strlen(file) - sizeof(reg->alloc_file) + 1 : 0), sizeof(reg->alloc_file));
+	ast_copy_string(reg->alloc_func, func, sizeof(reg->alloc_func));
+	reg->alloc_lineno = lineno;
 	reg->len = size;
+	reg->fullsize = fullsize;
 	reg->which = which;
 	reg->cache = cache;
 	ptr = reg->data;
@@ -136,22 +487,52 @@
 	return ptr;
 }
 
-static inline size_t __ast_sizeof_region(void *ptr)
+static inline void *__ast_alloc_region(size_t size, const enum func_type which, const char *file, int lineno, const char *func, unsigned int cache)
+{
+	struct ast_region *reg = NULL;
+	void *ptr = NULL;
+	unsigned int *fence;
+	int hash;
+	if (!(reg = malloc(size + sizeof(*reg) + sizeof(*fence)))) {
+		astmm_log("Memory Allocation Failure - '%d' bytes in function %s "
+			  "at line %d of %s\n", (int) size, func, lineno, file);
+		return NULL;
+	}
+
+	ast_copy_string(reg->alloc_file, file, sizeof(reg->alloc_file));
+	ast_copy_string(reg->alloc_func, func, sizeof(reg->alloc_func));
+	reg->alloc_lineno = lineno;
+	reg->len = size;
+	reg->fullsize = 1;
+	reg->which = which;
+	reg->cache = cache;
+	ptr = reg->data;
+	hash = HASH(ptr);
+	reg->fence = FENCE_MAGIC;
+	fence = (ptr + reg->len);
+	put_unaligned_uint32(fence, FENCE_MAGIC);
+
+	ast_mutex_lock(&reglock);
+	reg->next = regions[hash];
+	regions[hash] = reg;
+	ast_mutex_unlock(&reglock);
+
+	return ptr;
+}
+
+static inline struct ast_region *ptr2region(void *ptr)
 {
 	int hash = HASH(ptr);
 	struct ast_region *reg;
-	size_t len = 0;
-	
+
 	ast_mutex_lock(&reglock);
 	for (reg = regions[hash]; reg; reg = reg->next) {
 		if (reg->data == ptr) {
-			len = reg->len;
 			break;
 		}
 	}
 	ast_mutex_unlock(&reglock);
-
-	return len;
+	return reg;
 }
 
 static void __ast_free_region(void *ptr, const char *file, int lineno, const char *func)
@@ -159,6 +540,7 @@
 	int hash;
 	struct ast_region *reg, *prev = NULL;
 	unsigned int *fence;
+	time_t now;
 
 	if (!ptr) {
 		return;
@@ -166,72 +548,184 @@
 
 	hash = HASH(ptr);
 
+	now = time(NULL);
+
+	/* Mark this segment as freed */
 	ast_mutex_lock(&reglock);
 	for (reg = regions[hash]; reg; reg = reg->next) {
 		if (reg->data == ptr) {
-			if (prev)
+			fence = (unsigned int *)(reg->data + reg->len);
+			if (reg->fence != FENCE_MAGIC) {
+				astmm_log("WARNING: Low fence violation at %p, in %s of %s, "
+					"line %d, freed in %s of %s, line %d\n", reg->data,
+					reg->alloc_func, reg->alloc_file, reg->alloc_lineno,
+					func, file, lineno);
+				/* Restore FENCE_MAGIC, as it's needed for extended checking */
+				reg->fence = FENCE_MAGIC;
+			}
+			if (get_unaligned_uint32(fence) != FENCE_MAGIC) {
+				astmm_log("WARNING: High fence violation (%x) at %p, in %s of %s, "
+					"line %d, freed in %s of %s, line %d\n", get_unaligned_uint32(fence), reg->data,
+					reg->alloc_func, reg->alloc_file, reg->alloc_lineno,
+					func, file, lineno);
+			}
+
+			/* Remove from "allocated" list */
+			if (prev) {
 				prev->next = reg->next;
-			else
+			} else {
 				regions[hash] = reg->next;
+			}
+			reg->next = NULL;
+
+			if (reg->fullsize % pagesize == 0) {
+				reg->mperm = PROT_NONE;
+				reg->operation = 0;
+				reg->vlocation = NULL;
+				reg->freetime = now;
+				ast_copy_string(reg->free_file, file, sizeof(reg->free_file));
+				ast_copy_string(reg->free_func, func, sizeof(reg->free_func));
+				reg->free_lineno = lineno;
+
+				/* By inserting at the end of the list, we ensure that we won't need
+				 * to search the list for entries to delete, but merely prune the
+				 * head of the list until the head no longer has a time over HOLD_LENGTH
+				 * seconds old. */
+				if (lastfree == NULL) {
+					lastfree = reg;
+					regions[FREE_LIST] = reg;
+				} else {
+					MPROTECT(lastfree, sizeof(*lastfree), PROT_READ | PROT_WRITE);
+					lastfree->next = reg;
+					MPROTECT(lastfree, sizeof(*lastfree), PROT_NONE);
+					lastfree = reg;
+				}
+				MPROTECT(reg, reg->fullsize, PROT_NONE);
+			} else {
+				/* Not an even multiple of pagesize, so not a candidate for MALLOC_HOLD treatment */
+				free(reg);
+			}
 			break;
 		}
 		prev = reg;
 	}
+
+	if (!reg) {
+		astmm_log("WARNING: Freeing unused memory at %p, in %s of %s, line %d\n",
+			ptr, func, file, lineno);
+	}
 	ast_mutex_unlock(&reglock);
-
-	if (reg) {
-		fence = (unsigned int *)(reg->data + reg->len);
-		if (reg->fence != FENCE_MAGIC) {
-			astmm_log("WARNING: Low fence violation at %p, in %s of %s, "
-				"line %d\n", reg->data, reg->func, reg->file, reg->lineno);
-		}
+}
+
+void *__ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
+{
+	void *ptr;
+
+	if ((ptr = __ast_alloc_region(size * nmemb, FUNC_CALLOC, file, lineno, func, 0))) {
+		memset(ptr, 0, size * nmemb);
+	}
+
+	return ptr;
+}
+
+void *__ast_hold_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
+{
+	void *ptr;
+
+	if ((ptr = __ast_hold_alloc_region(size * nmemb, FUNC_CALLOC, file, lineno, func, 0))) {
+		memset(ptr, 0, size * nmemb);
+	}
+
+	return ptr;
+}
+
+void *__ast_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
+{
+	void *ptr;
+
+	if ((ptr = __ast_alloc_region(size * nmemb, FUNC_CALLOC, file, lineno, func, 1))) {
+		memset(ptr, 0, size * nmemb);
+	}
+	return ptr;
+}
+
+void *__ast_hold_calloc_cache(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
+{
+	void *ptr;
+
+	if ((ptr = __ast_hold_alloc_region(size * nmemb, FUNC_CALLOC, file, lineno, func, 1))) {
+		memset(ptr, 0, size * nmemb);
+	}
+
+	return ptr;
+}
+
+void *__ast_hold_malloc(size_t size, const char *file, int lineno, const char *func)
+{

[... 493 lines stripped ...]



More information about the asterisk-commits mailing list