[asterisk-commits] russell: branch russell/frame_caching r41039 - /team/russell/frame_caching/main/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Aug 24 20:19:20 MST 2006


Author: russell
Date: Thu Aug 24 22:19:20 2006
New Revision: 41039

URL: http://svn.digium.com/view/asterisk?rev=41039&view=rev
Log:
don't allow a thread's cache of frame headers to grow beyond a size of 10.
In cases where the cache will help, it will stay very small, because frames
will be added at the same rate they are removed.  However, there are some cases
where one thread is allocating frames, while another frees them.  In this case,
the cache would grow for forever.  To prevent memory usage from exploding, I
just limit the size.

Modified:
    team/russell/frame_caching/main/frame.c

Modified: team/russell/frame_caching/main/frame.c
URL: http://svn.digium.com/view/asterisk/team/russell/frame_caching/main/frame.c?rev=41039&r1=41038&r2=41039&view=diff
==============================================================================
--- team/russell/frame_caching/main/frame.c (original)
+++ team/russell/frame_caching/main/frame.c Thu Aug 24 22:19:20 2006
@@ -68,9 +68,25 @@
 /*! \brief A per-thread cache of frame headers */
 AST_THREADSTORAGE_CUSTOM(frame_cache, frame_cache_init, frame_cache_cleanup);
 
+/*! 
+ * \brief Maximum ast_frame cache size
+ *
+ * In most cases where the frame header cache will be useful, the size
+ * of the cache will stay very small.  However, it is not always the case that
+ * the same thread that allocates the frame will be the one freeing them, so
+ * sometimes a thread will never have any frames in its cache, or the cache
+ * will never be pulled from.  For the latter case, we limit the maximum size. 
+ */ 
+#define FRAME_CACHE_MAX_SIZE	10
+
 /*! \brief This is just so ast_frames, a list head struct for holding a list of
  *  ast_frame structures, is defined. */
 AST_LIST_HEAD_NOLOCK(ast_frames, ast_frame);
+
+struct ast_frame_cache {
+	struct ast_frames list;
+	size_t size;
+};
 
 #define SMOOTHER_SIZE 8000
 
@@ -277,14 +293,15 @@
 static struct ast_frame *ast_frame_header_new(void)
 {
 	struct ast_frame *f;
-	struct ast_frames *frames;
+	struct ast_frame_cache *frames;
 
 	if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
-		if ((f = AST_LIST_REMOVE_HEAD(frames, frame_list))) {
+		if ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) {
 			size_t mallocd_len = f->mallocd_hdr_len;
 			memset(f, 0, sizeof(*f));
 			f->mallocd_hdr_len = mallocd_len;
 			f->mallocd = AST_MALLOCD_HDR;
+			frames->size--;
 			ast_atomic_fetchadd_int((int *) &removed_from_cache, 1);
 			return f;
 		}
@@ -308,10 +325,10 @@
 
 static void frame_cache_cleanup(void *data)
 {
-	struct ast_frames *frames = data;
+	struct ast_frame_cache *frames = data;
 	struct ast_frame *f;
 
-	while ((f = AST_LIST_REMOVE_HEAD(frames, frame_list))) {
+	while ((f = AST_LIST_REMOVE_HEAD(&frames->list, frame_list))) {
 		free(f);
 		ast_atomic_fetchadd_int((int *) &headers_freed, 1);
 	}
@@ -353,12 +370,16 @@
 	if (fr->mallocd == AST_MALLOCD_HDR) {
 		/* Cool, only the header is malloc'd, let's just cache those for now 
 		 * to keep things simple... */
-		struct ast_frames *frames;
-
-		if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
-			AST_LIST_INSERT_HEAD(frames, fr, frame_list);
+		struct ast_frame_cache *frames;
+
+		if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames))) 
+		    && frames->size < FRAME_CACHE_MAX_SIZE) {
+			AST_LIST_INSERT_HEAD(&frames->list, fr, frame_list);
+			frames->size++;
 			ast_atomic_fetchadd_int((int *) &added_to_cache, 1);
 			return;
+		} else {
+			ast_verbose("Not adding frame to cache. frames='%d'  frames->size='%d'\n", frames, frames->size);
 		}
 	}
 
@@ -445,7 +466,7 @@
 
 struct ast_frame *ast_frdup(const struct ast_frame *f)
 {
-	struct ast_frames *frames;
+	struct ast_frame_cache *frames;
 	struct ast_frame *out;
 	int len, srclen = 0;
 	void *buf = NULL;
@@ -462,13 +483,14 @@
 		len += srclen + 1;
 
 	if ((frames = ast_threadstorage_get(&frame_cache, sizeof(*frames)))) {
-		AST_LIST_TRAVERSE_SAFE_BEGIN(frames, out, frame_list) {
+		AST_LIST_TRAVERSE_SAFE_BEGIN(&frames->list, out, frame_list) {
 			if (out->mallocd_hdr_len >= len) {
 				size_t mallocd_len = out->mallocd_hdr_len;
-				AST_LIST_REMOVE_CURRENT(frames, frame_list);
+				AST_LIST_REMOVE_CURRENT(&frames->list, frame_list);
 				memset(out, 0, sizeof(*out));
 				out->mallocd_hdr_len = mallocd_len;
 				buf = out;
+				frames->size--;
 				ast_atomic_fetchadd_int((int *) &removed_from_cache, 1);
 				break;
 			}



More information about the asterisk-commits mailing list