From 1a316ca6dbe2dd583719605a2a6765ae41024801 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Sun, 30 Sep 2007 20:05:18 +0000 Subject: [PATCH] add log and event object recycling to reduce malloc per sec in high call load git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@5768 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_log.h | 4 +-- src/switch_event.c | 48 ++++++++++++++++++++++++-------- src/switch_log.c | 59 ++++++++++++++++++++-------------------- 3 files changed, 68 insertions(+), 43 deletions(-) diff --git a/src/include/switch_log.h b/src/include/switch_log.h index 45850f18c0..6080076090 100644 --- a/src/include/switch_log.h +++ b/src/include/switch_log.h @@ -50,11 +50,11 @@ SWITCH_BEGIN_EXTERN_C /*! The complete log message */ char *data; /*! The file where the message originated */ - char *file; + char file[80]; /*! The line number where the message originated */ uint32_t line; /*! The function where the message originated */ - char *func; + char func[80]; /*! The log level of the message */ switch_log_level_t level; /*! The time when the log line was sent */ diff --git a/src/switch_event.c b/src/switch_event.c index ac5d826dd1..78e6f2c6cd 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -50,7 +50,8 @@ static int POOL_COUNT_MAX = SWITCH_CORE_QUEUE_LEN; static switch_hash_t *CUSTOM_HASH = NULL; static int THREAD_RUNNING = 0; static int EVENT_QUEUE_HAVEMORE = 0; - +static switch_queue_t *EVENT_RECYCLE_QUEUE = NULL; +static switch_queue_t *EVENT_HEADER_RECYCLE_QUEUE = NULL; #if 0 static void *locked_alloc(switch_size_t len) { @@ -97,7 +98,7 @@ static char *my_dup (const char *s) #define DUP(str) my_dup(str) #endif #ifndef FREE -#define FREE(ptr) if (ptr) free(ptr) +#define FREE(ptr) switch_safe_free(ptr) #endif /* make sure this is synced with the switch_event_types_t enum in switch_types.h @@ -365,6 +366,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_reserve_subclass_detailed(char *own SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) { int x = 0, last = 0; + void *pop; if (THREAD_RUNNING > 0) { THREAD_RUNNING = -1; @@ -403,6 +405,17 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void) } switch_core_hash_destroy(&CUSTOM_HASH); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled event node(s) and %d recycled event header node(s)\n", + switch_queue_size(EVENT_RECYCLE_QUEUE),switch_queue_size(EVENT_HEADER_RECYCLE_QUEUE)); + + + while (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } + while (switch_queue_trypop(EVENT_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } + return SWITCH_STATUS_SUCCESS; } @@ -433,6 +446,10 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) switch_queue_create(&EVENT_QUEUE[0], POOL_COUNT_MAX + 10, THRUNTIME_POOL); switch_queue_create(&EVENT_QUEUE[1], POOL_COUNT_MAX + 10, THRUNTIME_POOL); switch_queue_create(&EVENT_QUEUE[2], POOL_COUNT_MAX + 10, THRUNTIME_POOL); + switch_queue_create(&EVENT_RECYCLE_QUEUE, SWITCH_CORE_QUEUE_LEN, THRUNTIME_POOL); + switch_queue_create(&EVENT_HEADER_RECYCLE_QUEUE, SWITCH_CORE_QUEUE_LEN, THRUNTIME_POOL); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Activate Eventing Engine.\n"); switch_mutex_init(&BLOCK, SWITCH_MUTEX_NESTED, RUNTIME_POOL); @@ -453,14 +470,19 @@ SWITCH_DECLARE(switch_status_t) switch_event_init(switch_memory_pool_t *pool) SWITCH_DECLARE(switch_status_t) switch_event_create_subclass(switch_event_t **event, switch_event_types_t event_id, const char *subclass_name) { - + void *pop; + if (event_id != SWITCH_EVENT_CUSTOM && subclass_name) { return SWITCH_STATUS_GENERR; } - - if ((*event = ALLOC(sizeof(switch_event_t))) == 0) { - return SWITCH_STATUS_MEMERR; + + if (switch_queue_trypop(EVENT_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + *event = (switch_event_t *) pop; + } else { + *event = ALLOC(sizeof(switch_event_t)); + assert(*event); } + memset(*event, 0, sizeof(switch_event_t)); (*event)->event_id = event_id; @@ -519,7 +541,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_del_header(switch_event_t *event, c } FREE(hp->name); FREE(hp->value); - FREE(hp); + switch_queue_push(EVENT_HEADER_RECYCLE_QUEUE, hp); status = SWITCH_STATUS_SUCCESS; break; } @@ -543,9 +565,13 @@ SWITCH_DECLARE(switch_status_t) switch_event_add_header(switch_event_t *event, s return SWITCH_STATUS_MEMERR; } else { switch_event_header_t *header, *hp; + void *pop; - if ((header = ALLOC(sizeof(*header))) == 0) { - return SWITCH_STATUS_MEMERR; + if (switch_queue_trypop(EVENT_HEADER_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + header = (switch_event_header_t *) pop; + } else { + header = ALLOC(sizeof(*header)); + assert(header); } memset(header, 0, sizeof(*header)); @@ -603,10 +629,10 @@ SWITCH_DECLARE(void) switch_event_destroy(switch_event_t **event) hp = hp->next; FREE(this->name); FREE(this->value); - FREE(this); + switch_queue_push(EVENT_HEADER_RECYCLE_QUEUE, this); } FREE(ep->body); - FREE(ep); + switch_queue_push(EVENT_RECYCLE_QUEUE, ep); } *event = NULL; } diff --git a/src/switch_log.c b/src/switch_log.c index 77edd3d0ba..7bb714e316 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -57,6 +57,7 @@ static switch_memory_pool_t *LOG_POOL = NULL; static switch_log_binding_t *BINDINGS = NULL; static switch_mutex_t *BINDLOCK = NULL; static switch_queue_t *LOG_QUEUE = NULL; +static switch_queue_t *LOG_RECYCLE_QUEUE = NULL; static int8_t THREAD_RUNNING = 0; static uint8_t MAX_LEVEL = 0; @@ -133,7 +134,6 @@ static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t * thread, void *obj) } node = (switch_log_node_t *) pop; - switch_mutex_lock(BINDLOCK); for (binding = BINDINGS; binding; binding = binding->next) { if (binding->level >= node->level) { @@ -141,21 +141,9 @@ static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t * thread, void *obj) } } switch_mutex_unlock(BINDLOCK); - if (node) { - if (node->data) { - free(node->data); - } - - if (node->file) { - free(node->file); - } - - if (node->func) { - free(node->func); - } - - free(node); - } + + switch_safe_free(node->data); + switch_queue_push(LOG_RECYCLE_QUEUE, node); } THREAD_RUNNING = 0; @@ -177,6 +165,7 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char switch_time_t now = switch_time_now(); uint32_t len; const char *extra_fmt = "%s [%s] %s:%d %s()%c%s"; + va_start(ap, fmt); handle = switch_core_data_channel(channel); @@ -225,27 +214,28 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char free(data); } else if (level <= MAX_LEVEL) { switch_log_node_t *node; + void *pop = NULL; - if ((node = malloc(sizeof(*node)))) { - node->data = data; - node->file = strdup(filep); - node->func = strdup(funcp); - node->line = line; - node->level = level; - node->content = content; - node->timestamp = now; - switch_queue_push(LOG_QUEUE, node); + if (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + node = (switch_log_node_t *) pop; } else { - free(data); + node = malloc(sizeof(*node)); + assert(node); } + + node->data = data; + switch_set_string(node->file, filep); + switch_set_string(node->func, funcp); + node->line = line; + node->level = level; + node->content = content; + node->timestamp = now; + switch_queue_push(LOG_QUEUE, node); } } } - if (new_fmt) { - free(new_fmt); - } - + switch_safe_free(new_fmt); fflush(handle); } @@ -264,6 +254,7 @@ SWITCH_DECLARE(switch_status_t) switch_log_init(switch_memory_pool_t *pool) switch_queue_create(&LOG_QUEUE, SWITCH_CORE_QUEUE_LEN, LOG_POOL); + switch_queue_create(&LOG_RECYCLE_QUEUE, SWITCH_CORE_QUEUE_LEN, LOG_POOL); switch_mutex_init(&BINDLOCK, SWITCH_MUTEX_NESTED, LOG_POOL); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, log_thread, NULL, LOG_POOL); @@ -276,11 +267,19 @@ SWITCH_DECLARE(switch_status_t) switch_log_init(switch_memory_pool_t *pool) SWITCH_DECLARE(switch_status_t) switch_log_shutdown(void) { + void *pop; + THREAD_RUNNING = -1; switch_queue_push(LOG_QUEUE, NULL); while (THREAD_RUNNING) { switch_yield(1000); } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Returning %d recycled log node(s)\n", switch_queue_size(LOG_RECYCLE_QUEUE)); + while (switch_queue_trypop(LOG_RECYCLE_QUEUE, &pop) == SWITCH_STATUS_SUCCESS) { + free(pop); + } + return SWITCH_STATUS_SUCCESS; }