aboutsummaryrefslogtreecommitdiffstats
path: root/channels/iax2-parser.c
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-31 19:03:41 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2008-07-31 19:03:41 +0000
commitc8ccc483f850a3b80d49ffa690c958524bbd8b95 (patch)
treeb0895c3e3dde4fae253515f9234c6a66693b162a /channels/iax2-parser.c
parent38884ff9440fcedc6528efa676b66095b4b776ae (diff)
Optimize frame cache by realloc'ing the smallest frame when the cache is full.
This ensures that we don't just keep a cache of tiny frames, continually doing an alloc/free for each data frame, thus negating the point of having a cache. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@134867 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/iax2-parser.c')
-rw-r--r--channels/iax2-parser.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 196093ba2..55c363f66 100644
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -999,9 +999,11 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
#if !defined(LOW_MEMORY)
struct iax_frames *iax_frames = NULL;
+ struct iax_frame *smallest;
/* Attempt to get a frame from this thread's cache */
if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
+ smallest = AST_LIST_FIRST(&iax_frames->list);
AST_LIST_TRAVERSE_SAFE_BEGIN(&iax_frames->list, fr, list) {
if (fr->afdatalen >= datalen) {
size_t afdatalen = fr->afdatalen;
@@ -1010,12 +1012,21 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
memset(fr, 0, sizeof(*fr));
fr->afdatalen = afdatalen;
break;
+ } else if (smallest->afdatalen > fr->afdatalen) {
+ smallest = fr;
}
}
AST_LIST_TRAVERSE_SAFE_END;
}
if (!fr) {
- if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
+ if (iax_frames->size >= FRAME_CACHE_MAX_SIZE && smallest) {
+ /* Make useless cache into something more useful */
+ AST_LIST_REMOVE(&iax_frames->list, smallest, list);
+ if (!(fr = ast_realloc(smallest, sizeof(*fr) + datalen))) {
+ AST_LIST_INSERT_TAIL(&iax_frames->list, smallest, list);
+ return NULL;
+ }
+ } else if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
return NULL;
fr->afdatalen = datalen;
}
@@ -1065,7 +1076,13 @@ void iax_frame_free(struct iax_frame *fr)
if (iax_frames->size < FRAME_CACHE_MAX_SIZE) {
fr->direction = 0;
- AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
+ /* Pseudo-sort: keep smaller frames at the top of the list. This should
+ * increase the chance that we pick the smallest applicable frame for use. */
+ if (AST_LIST_FIRST(&iax_frames->list) && AST_LIST_FIRST(&iax_frames->list)->afdatalen < fr->afdatalen) {
+ AST_LIST_INSERT_TAIL(&iax_frames->list, fr, list);
+ } else {
+ AST_LIST_INSERT_HEAD(&iax_frames->list, fr, list);
+ }
iax_frames->size++;
return;
}