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

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Aug 18 10:42:38 CDT 2009


Author: tilghman
Date: Tue Aug 18 10:42:34 2009
New Revision: 212725

URL: http://svn.asterisk.org/svn-view/asterisk?view=rev&rev=212725
Log:
Rollback some of the extravagant memory allocations, to help this run on larger systems

Modified:
    team/tilghman/malloc_hold/include/asterisk/astmm.h
    team/tilghman/malloc_hold/main/astmm.c

Modified: team/tilghman/malloc_hold/include/asterisk/astmm.h
URL: http://svn.asterisk.org/svn-view/asterisk/team/tilghman/malloc_hold/include/asterisk/astmm.h?view=diff&rev=212725&r1=212724&r2=212725
==============================================================================
--- team/tilghman/malloc_hold/include/asterisk/astmm.h (original)
+++ team/tilghman/malloc_hold/include/asterisk/astmm.h Tue Aug 18 10:42:34 2009
@@ -52,6 +52,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);
@@ -77,6 +78,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__)

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=212725&r1=212724&r2=212725
==============================================================================
--- team/tilghman/malloc_hold/main/astmm.c (original)
+++ team/tilghman/malloc_hold/main/astmm.c Tue Aug 18 10:42:34 2009
@@ -413,65 +413,69 @@
 		abort();
 	}
 
-	/*!
-	 * 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;
+	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;
-			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);
+		}
+		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
-	if (!reg && (reg = mmap(NULL, fullsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0)) == MAP_FAILED) {
+		(!cache && !reg && (reg = mmap(NULL, fullsize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS, -1, 0)) == MAP_FAILED)
 #else
-	if (!reg && !(reg = memalign(pagesize, fullsize))) {
-#endif
+		(!cache && !reg && !(reg = memalign(pagesize, fullsize)))
+#endif
+			) {
 #else /* !MALLOC_HOLD */
 	if (!(reg = malloc(size + sizeof(*reg) + sizeof(*fence)))) {
 #endif
@@ -564,28 +568,33 @@
 			}
 			reg->next = NULL;
 
-			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;
+			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 {
-				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);
+				/* Not an even multiple of pagesize, so not a candidate for MALLOC_HOLD treatment */
+				free(reg);
+			}
 			break;
 		}
 		prev = reg;
@@ -653,6 +662,11 @@
 	return __ast_alloc_region(size, FUNC_MALLOC, file, lineno, func, 0);
 }
 
+void *__ast_malloc_cache(size_t size, const char *file, int lineno, const char *func) 
+{
+	return __ast_alloc_region(size, FUNC_MALLOC, file, lineno, func, 1);
+}
+
 void __ast_free(void *ptr, const char *file, int lineno, const char *func) 
 {
 	__ast_free_region(ptr, file, lineno, func);
@@ -670,14 +684,19 @@
 	}
 
 #ifdef MALLOC_HOLD
-	if (ptr && (size + sizeof(*reg) < reg->fullsize)) {
+	if (ptr && (size + sizeof(*reg) + sizeof(unsigned int) < reg->fullsize)) {
+		/* No need to allocate another block, but reset our FENCE_MAGIC now. */
+		unsigned int *fence = (unsigned int *) (reg->data + reg->len);
+		if (get_unaligned_uint32(fence) != FENCE_MAGIC) {
+			astmm_log("WARNING: High fence violation at %p, in %s of %s, "
+				"line %d\n", reg->data, reg->alloc_func, reg->alloc_file, reg->alloc_lineno);
+		}
+		fence = (unsigned int *) reg->data + size;
 		reg->len = size;
-#else
-	if (ptr && (size + sizeof(*reg) < reg->len)) {
-#endif
-		/* No need to allocate another block */
+		put_unaligned_uint32(fence, FENCE_MAGIC);
 		return ptr;
 	}
+#endif
 
 	if (!(tmp = __ast_alloc_region(size, FUNC_REALLOC, file, lineno, func, 0)))
 		return NULL;
@@ -699,7 +718,7 @@
 		return NULL;
 
 	len = strlen(s) + 1;
-	if ((ptr = __ast_alloc_region(len, FUNC_STRDUP, file, lineno, func, 0)))
+	if ((ptr = __ast_alloc_region(len, FUNC_STRDUP, file, lineno, func, 1)))
 		strcpy(ptr, s);
 
 	return ptr;
@@ -716,7 +735,7 @@
 	len = strlen(s) + 1;
 	if (len > n)
 		len = n;
-	if ((ptr = __ast_alloc_region(len, FUNC_STRNDUP, file, lineno, func, 0)))
+	if ((ptr = __ast_alloc_region(len, FUNC_STRNDUP, file, lineno, func, 1)))
 		strcpy(ptr, s);
 
 	return ptr;
@@ -733,7 +752,7 @@
 	va_copy(ap2, ap);
 	size = vsnprintf(&s, 1, fmt, ap2);
 	va_end(ap2);
-	if (!(*strp = __ast_alloc_region(size + 1, FUNC_ASPRINTF, file, lineno, func, 0))) {
+	if (!(*strp = __ast_alloc_region(size + 1, FUNC_ASPRINTF, file, lineno, func, 1))) {
 		va_end(ap);
 		return -1;
 	}
@@ -753,7 +772,7 @@
 	va_copy(ap2, ap);
 	size = vsnprintf(&s, 1, fmt, ap2);
 	va_end(ap2);
-	if (!(*strp = __ast_alloc_region(size + 1, FUNC_VASPRINTF, file, lineno, func, 0))) {
+	if (!(*strp = __ast_alloc_region(size + 1, FUNC_VASPRINTF, file, lineno, func, 1))) {
 		va_end(ap);
 		return -1;
 	}
@@ -943,7 +962,7 @@
 }
 
 static char show_memory_help[] = 
-"Usage: memory show allocations [<file>]\n"
+"Usage: memory show allocations [<file>|anomolies]\n"
 "       Dumps a list of all segments of allocated memory, optionally\n"
 "limited to those from a specific file\n";
 




More information about the svn-commits mailing list