[svn-commits] tilghman: branch tilghman/malloc_hold r208505 - in /team/tilghman/malloc_hold...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Jul 23 17:43:13 CDT 2009


Author: tilghman
Date: Thu Jul 23 17:43:10 2009
New Revision: 208505

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=208505
Log:
Update branch to reviewboard

Modified:
    team/tilghman/malloc_hold/include/asterisk/config.h
    team/tilghman/malloc_hold/main/astmm.c
    team/tilghman/malloc_hold/main/config.c
    team/tilghman/malloc_hold/res/res_config_odbc.c
    team/tilghman/malloc_hold/res/res_config_pgsql.c

Modified: team/tilghman/malloc_hold/include/asterisk/config.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/tilghman/malloc_hold/include/asterisk/config.h?view=diff&rev=208505&r1=208504&r2=208505
==============================================================================
--- team/tilghman/malloc_hold/include/asterisk/config.h (original)
+++ team/tilghman/malloc_hold/include/asterisk/config.h Thu Jul 23 17:43:10 2009
@@ -45,11 +45,7 @@
 	char stuff[0];
 };
 
-#ifdef MALLOC_DEBUG
-typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments, const char *who_asked);
-#else
 typedef struct ast_config *config_load_func(const char *database, const char *table, const char *configfile, struct ast_config *config, int withcomments);
-#endif
 typedef struct ast_variable *realtime_var_get(const char *database, const char *table, va_list ap);
 typedef struct ast_config *realtime_multi_get(const char *database, const char *table, va_list ap);
 typedef int realtime_update(const char *database, const char *table, const char *keyfield, const char *entity, va_list ap);
@@ -69,12 +65,7 @@
  *
  * Returns NULL on error, or an ast_config data structure on success
  */
-#ifdef MALLOC_DEBUG
-#define	ast_config_load(a)	ast_config_load2(a,__FILE__)
-struct ast_config *ast_config_load2(const char *filename, const char *who_asked);
-#else
 struct ast_config *ast_config_load(const char *filename);
-#endif
 struct ast_config *ast_config_load_with_comments(const char *filename);
 
 /*! \brief Destroys a config 
@@ -198,12 +189,7 @@
 struct ast_variable *ast_category_detach_variables(struct ast_category *cat);
 void ast_category_rename(struct ast_category *cat, const char *name);
 
-#ifdef MALLOC_DEBUG
-#define ast_variable_new(a,b)	_ast_variable_new(a,b,__FILE__,__LINE__,__PRETTY_FUNCTION__)
-struct ast_variable *_ast_variable_new(const char *name, const char *value, const char *file, int line, const char *func);
-#else
 struct ast_variable *ast_variable_new(const char *name, const char *value);
-#endif
 void ast_variable_append(struct ast_category *category, struct ast_variable *variable);
 int ast_variable_delete(struct ast_category *category, char *variable, char *match);
 int ast_variable_update(struct ast_category *category, const char *variable, 
@@ -211,11 +197,7 @@
 
 int config_text_file_save(const char *filename, const struct ast_config *cfg, const char *generator);
 
-#ifdef MALLOC_DEBUG
-struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, int withcomments, const char *who_asked);
-#else
 struct ast_config *ast_config_internal_load(const char *configfile, struct ast_config *cfg, int withcomments);
-#endif
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }

Modified: team/tilghman/malloc_hold/main/astmm.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/tilghman/malloc_hold/main/astmm.c?view=diff&rev=208505&r1=208504&r2=208505
==============================================================================
--- team/tilghman/malloc_hold/main/astmm.c (original)
+++ team/tilghman/malloc_hold/main/astmm.c Thu Jul 23 17:43:10 2009
@@ -85,9 +85,8 @@
 
 static struct ast_region {
 	struct ast_region *next;
-	void *freebt[16];
 	unsigned int freetime;
-	unsigned int btcount;
+	unsigned int unused;
 	size_t len;
 	char file[40];
 	char func[40];
@@ -96,7 +95,11 @@
 	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 + 1];
+
+#ifdef MALLOC_HOLD
+static struct ast_region *lastfree = NULL;
+#endif
 
 #define HASH(a) \
 	(((unsigned long)(a)) % SOME_PRIME)
@@ -195,59 +198,35 @@
 			}
 
 			memset(ptr, 0, reg->len);
-			reg->which = FUNC_FREE;
 			reg->freetime = now;
-#if defined(linux) && defined(AST_DEVMODE) && defined(NOT)
-			reg->btcount = backtrace(reg->freebt, 16);
-#endif
-		}
-	}
-
-	/* Delete any segment which is free for at least 120 seconds */
-	for (reg = regions[hash]; reg; reg = reg->next) {
-		if (reg->which == FUNC_FREE && reg->freetime < now - 120) {
-			struct ast_region *tbf = reg;
-			unsigned char *ptr;
+
+			/* Move to "free" list */
 			if (prev) {
 				prev->next = reg->next;
-				reg = prev;
 			} else {
-				reg = regions[hash] = reg->next;
-			}
-
-			for (ptr = tbf->data; ptr < tbf->data + tbf->len; ptr++) {
-				if (*ptr != 0) {
-#if defined(linux) && defined(AST_DEVMODE) && defined(NOT)
-					char **strings;
-					int i;
-#endif
-					astmm_log("WARNING: memory (%p) written to after being freed "
-						"at %p (+%d/%d), (originally in %s of %s, line %d)\n",
-						tbf->data, ptr, ptr - tbf->data, tbf->len, tbf->func, tbf->file, tbf->lineno);
-#if defined(linux) && defined(AST_DEVMODE) && defined(NOT)
-					if ((strings = backtrace_symbols(tbf->freebt, tbf->btcount))) {
-						astmm_log("%d backtrace records\n", tbf->btcount);
-						for (i = 0; i < tbf->btcount; i++) {
-#if __WORDSIZE == 32
-							astmm_log("#%d: [%08X] %s\n", i, (unsigned int)tbf->freebt[i], strings[i]);
-#elif __WORDSIZE == 64
-							astmm_log("#%d: [%016lX] %s\n", i, (unsigned long)tbf->freebt[i], strings[i]);
-#endif
-						}
-						free(strings);
-					}
-#endif
-					break;
-				}
-			}
-			free(tbf);
-
-			if (reg == NULL) {
-				break;
-			}
-		} else {
-			prev = reg;
-		}
+				regions[hash] = reg->next;
+			}
+			reg->next = NULL;
+
+			/* 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 120
+			 * seconds old. */
+			if (lastfree == NULL) {
+				lastfree = reg;
+				regions[SOME_PRIME] = reg;
+			} else {
+				lastfree->next = reg;
+				lastfree = 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);
 #else
@@ -564,10 +543,75 @@
 	show_memory_summary_help, NULL, &cli_show_memory_summary_deprecated },
 };
 
+#ifdef MALLOC_HOLD
+static void *memory_destructor(void *notused)
+{
+	struct ast_region *cur;
+	for (;;) {
+		ast_mutex_lock(&reglock);
+		/* Delete any segment which is free for at least 120 seconds */
+		while ((cur = regions[SOME_PRIME]) && cur->freetime < time(NULL) - 120) {
+			unsigned char *ptr;
+
+			for (ptr = cur->data; ptr < cur->data + cur->len; ptr++) {
+				if (*ptr != 0) {
+					astmm_log("WARNING: memory (%p) written to after being freed "
+						"at %p (+%d/%d), (originally in %s of %s, line %d)\n",
+						cur->data, ptr, ptr - cur->data, cur->len, cur->func, cur->file, cur->lineno);
+					break;
+				}
+			}
+
+			regions[SOME_PRIME] = cur->next;
+			if (cur == lastfree) {
+				astmm_log("Freeing last bit of memory in free list.\n");
+				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->func, cur->file, cur->lineno);
+#endif
+			free(cur);
+		}
+		ast_mutex_unlock(&reglock);
+		if (regions[SOME_PRIME]) {
+			sleep(120 - (time(NULL) - regions[SOME_PRIME]->freetime));
+		} else {
+			astmm_log("Nothing in free list.  Sleeping for 120 seconds.\n");
+			sleep(120);
+		}
+	}
+	/* Never reached */
+	return NULL;
+}
+
+/* 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)
+#endif
+
 void __ast_mm_init(void)
 {
 	char filename[PATH_MAX];
 	size_t pad = sizeof(struct ast_region) - offsetof(struct ast_region, data);
+#ifdef MALLOC_HOLD
+	pthread_t notused;
+
+	ast_pthread_create_background(&notused, NULL, memory_destructor, NULL);
+#endif
 
 	if (pad) {
 		ast_log(LOG_ERROR, "struct ast_region has %d bytes of padding! This must be eliminated for low-fence checking to work properly!\n", (int) pad);

Modified: team/tilghman/malloc_hold/main/config.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/tilghman/malloc_hold/main/config.c?view=diff&rev=208505&r1=208504&r2=208505
==============================================================================
--- team/tilghman/malloc_hold/main/config.c (original)
+++ team/tilghman/malloc_hold/main/config.c Thu Jul 23 17:43:10 2009
@@ -183,26 +183,12 @@
 	int max_include_level;
 };
 
-#ifdef MALLOC_DEBUG
-struct ast_variable *_ast_variable_new(const char *name, const char *value, const char *file, int line, const char *func)
-#else
-struct ast_variable *ast_variable_new(const char *name, const char *value)
-#endif
+struct ast_variable *ast_variable_new(const char *name, const char *value) 
 {
 	struct ast_variable *variable;
 	int name_len = strlen(name) + 1;	
 
-	if ((variable =
-#ifdef MALLOC_DEBUG
-		__ast_calloc
-#else
-		ast_calloc
-#endif
-			(1, name_len + strlen(value) + 1 + sizeof(*variable)
-#ifdef MALLOC_DEBUG
-			, file, line, func
-#endif
-		))) {
+	if ((variable = ast_calloc(1, name_len + strlen(value) + 1 + sizeof(*variable)))) {
 		variable->name = variable->stuff;
 		variable->value = variable->stuff + name_len;		
 		strcpy(variable->name,name);
@@ -632,13 +618,8 @@
 	cfg->current = (struct ast_category *) cat;
 }
 
-#ifdef MALLOC_DEBUG
-static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments,
-				char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size, const char *file, int line, const char *func)
-#else
 static int process_text_line(struct ast_config *cfg, struct ast_category **cat, char *buf, int lineno, const char *configfile, int withcomments,
 				char **comment_buffer, int *comment_buffer_size, char **lline_buffer, int *lline_buffer_size)
-#endif
 {
 	char *c;
 	char *cur = buf;
@@ -757,11 +738,7 @@
 				} else
 					exec_file[0] = '\0';
 				/* A #include */
-#ifdef MALLOC_DEBUG
-				do_include = ast_config_internal_load(cur, cfg, withcomments, "config.c") ? 1 : 0;
-#else
 				do_include = ast_config_internal_load(cur, cfg, withcomments) ? 1 : 0;
-#endif
 				if(!ast_strlen_zero(exec_file))
 					unlink(exec_file);
 				if (!do_include) {
@@ -803,11 +780,7 @@
 				c++;
 			} else
 				object = 0;
-#ifdef MALLOC_DEBUG
-			if ((v = _ast_variable_new(ast_strip(cur), ast_strip(c), file, line, func))) {
-#else
 			if ((v = ast_variable_new(ast_strip(cur), ast_strip(c)))) {
-#endif
 				v->lineno = lineno;
 				v->object = object;
 				/* Put and reset comments */
@@ -833,11 +806,7 @@
 	return 0;
 }
 
-#ifdef MALLOC_DEBUG
-static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments, const char *who_asked)
-#else
 static struct ast_config *config_text_file_load(const char *database, const char *table, const char *filename, struct ast_config *cfg, int withcomments)
-#endif
 {
 	char fn[256];
 #if defined(LOW_MEMORY)
@@ -988,11 +957,7 @@
 				if (process_buf) {
 					char *buf = ast_strip(process_buf);
 					if (!ast_strlen_zero(buf)) {
-#ifdef MALLOC_DEBUG
-						if (process_text_line(cfg, &cat, buf, lineno, fn, withcomments, &comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size, filename, lineno, who_asked)) {
-#else
 						if (process_text_line(cfg, &cat, buf, lineno, fn, withcomments, &comment_buffer, &comment_buffer_size, &lline_buffer, &lline_buffer_size)) {
-#endif
 							cfg = NULL;
 							break;
 						}
@@ -1229,11 +1194,7 @@
 
 	configtmp = ast_config_new();
 	configtmp->max_include_level = 1;
-#ifdef MALLOC_DEBUG
-	config = ast_config_internal_load(extconfig_conf, configtmp, 0, "config.c");
-#else
 	config = ast_config_internal_load(extconfig_conf, configtmp, 0);
-#endif
 	if (!config) {
 		ast_config_destroy(configtmp);
 		return 0;
@@ -1372,11 +1333,7 @@
 	.load_func = config_text_file_load,
 };
 
-#ifdef MALLOC_DEBUG
-struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments, const char *who_asked)
-#else
 struct ast_config *ast_config_internal_load(const char *filename, struct ast_config *cfg, int withcomments)
-#endif
 {
 	char db[256];
 	char table[256];
@@ -1406,11 +1363,7 @@
 		}
 	}
 
-#ifdef MALLOC_DEBUG
-	result = loader->load_func(db, table, filename, cfg, withcomments, who_asked);
-#else
 	result = loader->load_func(db, table, filename, cfg, withcomments);
-#endif
 
 	if (result)
 		result->include_level--;
@@ -1420,11 +1373,7 @@
 	return result;
 }
 
-#ifdef MALLOC_DEBUG
-struct ast_config *ast_config_load2(const char *filename, const char *who_asked)
-#else
 struct ast_config *ast_config_load(const char *filename)
-#endif
 {
 	struct ast_config *cfg;
 	struct ast_config *result;
@@ -1433,11 +1382,7 @@
 	if (!cfg)
 		return NULL;
 
-#ifdef MALLOC_DEBUG
-	result = ast_config_internal_load(filename, cfg, 0, who_asked);
-#else
 	result = ast_config_internal_load(filename, cfg, 0);
-#endif
 	if (!result)
 		ast_config_destroy(cfg);
 
@@ -1453,11 +1398,7 @@
 	if (!cfg)
 		return NULL;
 
-#ifdef MALLOC_DEBUG
-	result = ast_config_internal_load(filename, cfg, 1, "config.c");
-#else
 	result = ast_config_internal_load(filename, cfg, 1);
-#endif
 	if (!result)
 		ast_config_destroy(cfg);
 

Modified: team/tilghman/malloc_hold/res/res_config_odbc.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/tilghman/malloc_hold/res/res_config_odbc.c?view=diff&rev=208505&r1=208504&r2=208505
==============================================================================
--- team/tilghman/malloc_hold/res/res_config_odbc.c (original)
+++ team/tilghman/malloc_hold/res/res_config_odbc.c Thu Jul 23 17:43:10 2009
@@ -450,11 +450,7 @@
 	return sth;
 }
 
-#ifdef MALLOC_DEBUG
-static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments, const char *who_asked)
-#else
 static struct ast_config *config_odbc(const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments)
-#endif
 {
 	struct ast_variable *new_v;
 	struct ast_category *cur_cat;
@@ -510,11 +506,7 @@
 
 	while ((res = SQLFetch(stmt)) != SQL_NO_DATA) {
 		if (!strcmp (q.var_name, "#include")) {
-#ifdef MALLOC_DEBUG
-			if (!ast_config_internal_load(q.var_val, cfg, 0, __FILE__)) {
-#else
 			if (!ast_config_internal_load(q.var_val, cfg, 0)) {
-#endif
 				SQLFreeHandle(SQL_HANDLE_STMT, stmt);
 				ast_odbc_release_obj(obj);
 				return NULL;

Modified: team/tilghman/malloc_hold/res/res_config_pgsql.c
URL: http://svn.asterisk.org/svn-view/asterisk/team/tilghman/malloc_hold/res/res_config_pgsql.c?view=diff&rev=208505&r1=208504&r2=208505
==============================================================================
--- team/tilghman/malloc_hold/res/res_config_pgsql.c (original)
+++ team/tilghman/malloc_hold/res/res_config_pgsql.c Thu Jul 23 17:43:10 2009
@@ -490,11 +490,7 @@
 
 static struct ast_config *config_pgsql(const char *database, const char *table,
 					   const char *file, struct ast_config *cfg,
-#ifdef MALLOC_DEBUG
-					   int withcomments, const char *who_asked)
-#else
 					   int withcomments)
-#endif
 {
 	PGresult *result = NULL;
 	long num_rows;
@@ -560,11 +556,7 @@
 			char *field_var_val = PQgetvalue(result, rowIndex, 2);
 			char *field_cat_metric = PQgetvalue(result, rowIndex, 3);
 			if (!strcmp(field_var_name, "#include")) {
-#ifdef MALLOC_DEBUG
-				if (!ast_config_internal_load(field_var_val, cfg, 0, __FILE__)) {
-#else
 				if (!ast_config_internal_load(field_var_val, cfg, 0)) {
-#endif
 					PQclear(result);
 					ast_mutex_unlock(&pgsql_lock);
 					return NULL;




More information about the svn-commits mailing list