mirror of
				https://github.com/open5gs/open5gs.git
				synced 2025-11-03 21:43:25 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			221 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
 | 
						|
 *
 | 
						|
 * This file is part of Open5GS.
 | 
						|
 *
 | 
						|
 * This program is free software: you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU Affero General Public License as published by
 | 
						|
 * the Free Software Foundation, either version 3 of the License, or
 | 
						|
 * (at your option) any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | 
						|
 */
 | 
						|
 | 
						|
#include "ogs-core.h"
 | 
						|
 | 
						|
#undef OGS_LOG_DOMAIN
 | 
						|
#define OGS_LOG_DOMAIN __ogs_mem_domain
 | 
						|
 | 
						|
/*****************************************
 | 
						|
 * Memory Pool - Use talloc library
 | 
						|
 *****************************************/
 | 
						|
 | 
						|
void *__ogs_talloc_core;
 | 
						|
 | 
						|
static ogs_thread_mutex_t mutex;
 | 
						|
 | 
						|
void ogs_mem_init(void)
 | 
						|
{
 | 
						|
    ogs_thread_mutex_init(&mutex);
 | 
						|
 | 
						|
    talloc_enable_null_tracking();
 | 
						|
 | 
						|
#define TALLOC_MEMSIZE 1
 | 
						|
    __ogs_talloc_core = talloc_named_const(NULL, TALLOC_MEMSIZE, "core");
 | 
						|
}
 | 
						|
 | 
						|
void ogs_mem_final(void)
 | 
						|
{
 | 
						|
    if (talloc_total_size(__ogs_talloc_core) != TALLOC_MEMSIZE)
 | 
						|
        talloc_report_full(__ogs_talloc_core, stderr);
 | 
						|
 | 
						|
    talloc_free(__ogs_talloc_core);
 | 
						|
 | 
						|
    ogs_thread_mutex_destroy(&mutex);
 | 
						|
}
 | 
						|
 | 
						|
void *ogs_mem_get_mutex(void)
 | 
						|
{
 | 
						|
    return &mutex;
 | 
						|
}
 | 
						|
 | 
						|
void *ogs_talloc_size(const void *ctx, size_t size, const char *name)
 | 
						|
{
 | 
						|
    void *ptr = NULL;
 | 
						|
 | 
						|
    ogs_thread_mutex_lock(&mutex);
 | 
						|
 | 
						|
    ptr = talloc_named_const(ctx, size, name);
 | 
						|
    ogs_expect(ptr);
 | 
						|
 | 
						|
    ogs_thread_mutex_unlock(&mutex);
 | 
						|
 | 
						|
    return ptr;
 | 
						|
}
 | 
						|
 | 
						|
void *ogs_talloc_zero_size(const void *ctx, size_t size, const char *name)
 | 
						|
{
 | 
						|
    void *ptr = NULL;
 | 
						|
 | 
						|
    ogs_thread_mutex_lock(&mutex);
 | 
						|
 | 
						|
    ptr = _talloc_zero(ctx, size, name);
 | 
						|
    ogs_expect(ptr);
 | 
						|
 | 
						|
    ogs_thread_mutex_unlock(&mutex);
 | 
						|
 | 
						|
    return ptr;
 | 
						|
}
 | 
						|
 | 
						|
void *ogs_talloc_realloc_size(
 | 
						|
        const void *context, void *oldptr, size_t size, const char *name)
 | 
						|
{
 | 
						|
    void *ptr = NULL;
 | 
						|
 | 
						|
    ogs_thread_mutex_lock(&mutex);
 | 
						|
 | 
						|
    ptr = _talloc_realloc(context, oldptr, size, name);
 | 
						|
    ogs_expect(ptr);
 | 
						|
 | 
						|
    ogs_thread_mutex_unlock(&mutex);
 | 
						|
 | 
						|
    return ptr;
 | 
						|
}
 | 
						|
 | 
						|
int ogs_talloc_free(void *ptr, const char *location)
 | 
						|
{
 | 
						|
    int ret;
 | 
						|
 | 
						|
    ogs_thread_mutex_lock(&mutex);
 | 
						|
 | 
						|
    ret = _talloc_free(ptr, location);
 | 
						|
 | 
						|
    ogs_thread_mutex_unlock(&mutex);
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
/*****************************************
 | 
						|
 * Memory Pool - Use pkbuf library
 | 
						|
 *****************************************/
 | 
						|
 | 
						|
void *ogs_malloc_debug(size_t size, const char *file_line)
 | 
						|
{
 | 
						|
    size_t headroom = 0;
 | 
						|
    ogs_pkbuf_t *pkbuf = NULL;
 | 
						|
 | 
						|
    ogs_assert(size);
 | 
						|
 | 
						|
    headroom = sizeof(ogs_pkbuf_t *);
 | 
						|
    pkbuf = ogs_pkbuf_alloc_debug(NULL, headroom + size, file_line);
 | 
						|
    if (!pkbuf) {
 | 
						|
        ogs_error("ogs_pkbuf_alloc_debug[headroom:%d, size:%d] failed",
 | 
						|
                (int)headroom, (int)size);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    ogs_pkbuf_reserve(pkbuf, headroom);
 | 
						|
    memcpy(pkbuf->head, &pkbuf, headroom);
 | 
						|
    ogs_pkbuf_put(pkbuf, size);
 | 
						|
 | 
						|
    return pkbuf->data;
 | 
						|
}
 | 
						|
 | 
						|
int ogs_free_debug(void *ptr)
 | 
						|
{
 | 
						|
    size_t headroom;
 | 
						|
    ogs_pkbuf_t *pkbuf = NULL;
 | 
						|
 | 
						|
    if (!ptr)
 | 
						|
        return OGS_ERROR;
 | 
						|
 | 
						|
    headroom = sizeof(ogs_pkbuf_t *);
 | 
						|
    memcpy(&pkbuf, (unsigned char*)ptr - headroom, headroom);
 | 
						|
    ogs_assert(pkbuf);
 | 
						|
 | 
						|
    ogs_pkbuf_free(pkbuf);
 | 
						|
 | 
						|
    return OGS_OK;
 | 
						|
}
 | 
						|
 | 
						|
void *ogs_calloc_debug(size_t nmemb, size_t size, const char *file_line)
 | 
						|
{
 | 
						|
    void *ptr = NULL;
 | 
						|
 | 
						|
    ptr = ogs_malloc_debug(nmemb * size, file_line);
 | 
						|
    if (!ptr) {
 | 
						|
        ogs_error("ogs_malloc_debug[nmemb:%d, size:%d] failed",
 | 
						|
                (int)nmemb, (int)size);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    memset(ptr, 0, nmemb * size);
 | 
						|
    return ptr;
 | 
						|
}
 | 
						|
 | 
						|
void *ogs_realloc_debug(void *ptr, size_t size, const char *file_line)
 | 
						|
{
 | 
						|
    size_t headroom = 0;
 | 
						|
    ogs_pkbuf_t *pkbuf = NULL;
 | 
						|
    ogs_cluster_t *cluster = NULL;
 | 
						|
 | 
						|
    if (!ptr)
 | 
						|
        return ogs_malloc(size);
 | 
						|
 | 
						|
    headroom = sizeof(ogs_pkbuf_t *);
 | 
						|
 | 
						|
    memcpy(&pkbuf, (unsigned char*)ptr - headroom, headroom);
 | 
						|
 | 
						|
    if (!pkbuf) {
 | 
						|
        ogs_error("Cannot get pkbuf from ptr[%p], headroom[%d]",
 | 
						|
                ptr, (int)headroom);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    cluster = pkbuf->cluster;
 | 
						|
    if (!cluster) {
 | 
						|
        ogs_error("No cluster");
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!size) {
 | 
						|
        ogs_pkbuf_free(pkbuf);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    if (size > (cluster->size - headroom)) {
 | 
						|
        void *new = NULL;
 | 
						|
 | 
						|
        new = ogs_malloc_debug(size, file_line);
 | 
						|
        if (!new) {
 | 
						|
            ogs_error("ogs_malloc_debug[%d] failed", (int)size);
 | 
						|
            return NULL;
 | 
						|
        }
 | 
						|
 | 
						|
        memcpy(new, ptr, pkbuf->len);
 | 
						|
 | 
						|
        ogs_pkbuf_free(pkbuf);
 | 
						|
        return new;
 | 
						|
    } else {
 | 
						|
        pkbuf->tail = pkbuf->data + size;
 | 
						|
        pkbuf->len = size;
 | 
						|
        return ptr;
 | 
						|
    }
 | 
						|
}
 |