From fcfc247c0ca14c92da0777ab04ff89e3ddd53a8c Mon Sep 17 00:00:00 2001 From: sachinites Date: Sun, 16 Feb 2020 01:29:51 -0800 Subject: [PATCH] Linux Memory Manager Integrated with the Project --- BitOp/bitarr.c | 2 +- LinkedList/LinkedListApi.c | 15 +- LinkedList/LinkedListApi.h | 2 +- LinuxMemoryManager/Makefile | 21 + LinuxMemoryManager/css.h | 12 + LinuxMemoryManager/gluethread/glthread.h | 104 ++++ LinuxMemoryManager/mm.c | 641 +++++++++++++++++++++++ LinuxMemoryManager/mm.h | 168 ++++++ LinuxMemoryManager/uapi_mm.h | 65 +++ LinuxMemoryManager/uapi_mm_new.h | 65 +++ LinuxMemoryManager/uapi_mm_old.h | 65 +++ Makefile | 13 +- Queue/Queue.c | 3 +- Stack/stack.c | 5 +- Tree/redblack.c | 4 +- advert.c | 3 +- complete_spf_path.c | 25 +- conflct_res.c | 1 + data_plane.c | 43 +- igp_sr_ext.c | 3 +- instance.c | 11 +- mem_init.c | 97 ++++ prefix.c | 7 +- routes.c | 28 +- routes.h | 5 +- spfclihandler.c | 13 +- spfcmdcodes.h | 1 + spfcomputation.c | 11 +- spfdcm.c | 16 + spfutil.c | 5 +- spring_adjsid.c | 3 +- sr_tlv_api.c | 5 +- testapp.c | 4 +- tilfa.c | 36 +- tilfa.h | 3 +- topo.c | 5 +- 36 files changed, 1397 insertions(+), 113 deletions(-) create mode 100644 LinuxMemoryManager/Makefile create mode 100644 LinuxMemoryManager/css.h create mode 100644 LinuxMemoryManager/gluethread/glthread.h create mode 100644 LinuxMemoryManager/mm.c create mode 100644 LinuxMemoryManager/mm.h create mode 100644 LinuxMemoryManager/uapi_mm.h create mode 100644 LinuxMemoryManager/uapi_mm_new.h create mode 100644 LinuxMemoryManager/uapi_mm_old.h create mode 100644 mem_init.c diff --git a/BitOp/bitarr.c b/BitOp/bitarr.c index 378b6ec..6f44168 100644 --- a/BitOp/bitarr.c +++ b/BitOp/bitarr.c @@ -172,7 +172,7 @@ print_bit_array(bit_array_t *bitarr){ int main(int argc, char **argv){ - bit_array_t *arr = calloc(1, sizeof(bit_array_t)); + bit_array_t *arr = XCALLOC(1, bit_array_t); init_bit_array(arr, 15); set_bit(arr, 11); set_bit(arr, 21); diff --git a/LinkedList/LinkedListApi.c b/LinkedList/LinkedListApi.c index 1691662..b2082c5 100644 --- a/LinkedList/LinkedListApi.c +++ b/LinkedList/LinkedListApi.c @@ -4,13 +4,14 @@ #include #include "LinkedListApi.h" #include +#include "../LinuxMemoryManager/uapi_mm.h" ll_t* init_singly_ll(){ - return calloc(1, sizeof(ll_t)); + return XCALLOC(1, ll_t); } singly_ll_node_t* singly_ll_init_node(void* data){ - singly_ll_node_t* node = calloc(1, sizeof(singly_ll_node_t)); + singly_ll_node_t* node = XCALLOC(1, singly_ll_node_t); node->data = data; return node; } @@ -92,14 +93,14 @@ singly_ll_delete_node(ll_t *ll, singly_ll_node_t *node){ node->data = node->next->data; temp = node->next; node->next = node->next->next; - free(temp); + XFREE(temp); DEC_NODE_COUNT_SINGLY_LL(ll); return 0; } /* if node is the only node in LL*/ if(ll->node_count == 1 && GET_HEAD_SINGLY_LL(ll) == node){ - free(node); + XFREE(node); GET_HEAD_SINGLY_LL(ll) = NULL; DEC_NODE_COUNT_SINGLY_LL(ll); return 0; @@ -113,7 +114,7 @@ singly_ll_delete_node(ll_t *ll, singly_ll_node_t *node){ } trav->next = NULL; - free(node); + XFREE(node); DEC_NODE_COUNT_SINGLY_LL(ll); return 0; } @@ -276,7 +277,7 @@ delete_singly_ll(ll_t *ll){ *next = GET_NEXT_NODE_SINGLY_LL(head); do{ - free(head); + XFREE(head); head = next; if(next) next = GET_NEXT_NODE_SINGLY_LL(next); @@ -327,7 +328,7 @@ singly_ll_delete_node_by_data_ptr(ll_t *ll, void *data){ return; singly_ll_remove_node(ll, list_node); - free(list_node); + XFREE(list_node); list_node = NULL; } diff --git a/LinkedList/LinkedListApi.h b/LinkedList/LinkedListApi.h index aaa789e..387265c 100644 --- a/LinkedList/LinkedListApi.h +++ b/LinkedList/LinkedListApi.h @@ -79,7 +79,7 @@ void singly_ll_add_ordered_data(ll_t *ll, void *data); else if(node_ptr && prev){ \ prev->next = node_ptr->next; \ } \ - free(node_ptr); \ + XFREE(node_ptr); \ list_ptr->node_count--; \ node_ptr = NULL;} diff --git a/LinuxMemoryManager/Makefile b/LinuxMemoryManager/Makefile new file mode 100644 index 0000000..8e2e29e --- /dev/null +++ b/LinuxMemoryManager/Makefile @@ -0,0 +1,21 @@ +CC=gcc +CFLAGS=-g +TARGET:testapp.exe libmm.a +OUTFILES=testapp.exe libmm.a +EXTERNAL_LIBS= +OBJS=gluethread/glthread.o mm.o + +testapp.exe:testapp.o ${OBJS} + ${CC} ${CFLAGS} testapp.o ${OBJS} -o testapp.exe ${EXTERNAL_LIBS} +testapp.o:testapp.c + ${CC} ${CFLAGS} -c testapp.c -o testapp.o +gluethread/glthread.o:gluethread/glthread.c + ${CC} ${CFLAGS} -c -I gluethread gluethread/glthread.c -o gluethread/glthread.o +mm.o:mm.c + ${CC} ${CFLAGS} -c mm.c -o mm.o +libmm.a:${OBJ} + ar rs libmm.a ${OBJ} +clean: + rm -f testapp.o + rm -f ${OUTFILES} + rm -f ${OBJS} diff --git a/LinuxMemoryManager/css.h b/LinuxMemoryManager/css.h new file mode 100644 index 0000000..b3d8331 --- /dev/null +++ b/LinuxMemoryManager/css.h @@ -0,0 +1,12 @@ +#ifndef __CSS__ +#define __CSS__ + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_GREEN "\x1b[32m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_BLUE "\x1b[34m" +#define ANSI_COLOR_MAGENTA "\x1b[35m" +#define ANSI_COLOR_CYAN "\x1b[36m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#endif diff --git a/LinuxMemoryManager/gluethread/glthread.h b/LinuxMemoryManager/gluethread/glthread.h new file mode 100644 index 0000000..8b87d14 --- /dev/null +++ b/LinuxMemoryManager/gluethread/glthread.h @@ -0,0 +1,104 @@ +/* + * ===================================================================================== + * + * Filename: glthread.h + * + * Description: This file defines the Data structure and APIs for Glue thread + * + * Version: 1.0 + * Created: Monday 12 March 2018 02:01:51 IST + * Revision: 1.0 + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Networking Developer (AS), sachinites@gmail.com + * Company: Brocade Communications(Jul 2012- Mar 2016), Current : Juniper Networks(Apr 2017 - Present) + * + * This file is part of the SPFComputation distribution (https://github.com/sachinites). + * Copyright (c) 2017 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * 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 . + * + * ===================================================================================== + */ + +#ifndef __GLUETHREAD__ +#define __GLUETHREAD__ + +typedef struct _glthread{ + + struct _glthread *left; + struct _glthread *right; +} glthread_t; + +void +glthread_add_next(glthread_t *base_glthread, glthread_t *new_glthread); + +void +glthread_add_before(glthread_t *base_glthread, glthread_t *new_glthread); + +void +remove_glthread(glthread_t *glthread); + +void +init_glthread(glthread_t *glthread); + +void +glthread_add_last(glthread_t *base_glthread, glthread_t *new_glthread); + +#define IS_GLTHREAD_LIST_EMPTY(glthreadptr) \ + ((glthreadptr)->right == 0 && (glthreadptr)->left == 0) + +#define GLTHREAD_TO_STRUCT(fn_name, structure_name, field_name, glthreadptr) \ + static inline structure_name * fn_name(glthread_t *glthreadptr){ \ + return (structure_name *)((char *)(glthreadptr) - (char *)&(((structure_name *)0)->field_name)); \ + } + +/* delete safe loop*/ +/*Normal continue and break can be used with this loop macro*/ + +#define BASE(glthreadptr) ((glthreadptr)->right) + +#define ITERATE_GLTHREAD_BEGIN(glthreadptrstart, glthreadptr) \ +{ \ + glthread_t *_glthread_ptr = NULL; \ + glthreadptr = BASE(glthreadptrstart); \ + for(; glthreadptr!= NULL; glthreadptr = _glthread_ptr){ \ + _glthread_ptr = (glthreadptr)->right; + +#define ITERATE_GLTHREAD_END(glthreadptrstart, glthreadptr) \ + }} + +#define GLTHREAD_GET_USER_DATA_FROM_OFFSET(glthreadptr, offset) \ + (void *)((char *)(glthreadptr) - offset) + +void +delete_glthread_list(glthread_t *base_glthread); + +unsigned int +get_glthread_list_count(glthread_t *base_glthread); + +void +glthread_priority_insert(glthread_t *base_glthread, + glthread_t *glthread, + int (*comp_fn)(void *, void *), + int offset); + + +#if 0 +void * +gl_thread_search(glthread_t *base_glthread, + void *(*thread_to_struct_fn)(glthread_t *), + void *key, + int (*comparison_fn)(void *, void *)); + +#endif +#endif /* __GLUETHREAD__ */ diff --git a/LinuxMemoryManager/mm.c b/LinuxMemoryManager/mm.c new file mode 100644 index 0000000..b4b3b1f --- /dev/null +++ b/LinuxMemoryManager/mm.c @@ -0,0 +1,641 @@ +/* + * ===================================================================================== + * + * Filename: mm.c + * + * Description: This file implements the routine for Memory Manager + * + * Version: 1.0 + * Created: 01/30/2020 10:31:41 AM + * Revision: none + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), sachinites@gmail.com + * Company: Juniper Networks + * + * This file is part of the Linux Memory Manager distribution (https://github.com/sachinites) + * Copyright (c) 2019 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, version 3. + * + * 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. + * + * visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects + * + * ===================================================================================== + */ + +#include "mm.h" +#include +#include +#include +#include +#include /*for getpagesize*/ +#include "css.h" + +static vm_page_family_t *first_vm_page_family = NULL; +static size_t SYSTEM_PAGE_SIZE = 0; + +void +mm_init(){ + + SYSTEM_PAGE_SIZE = getpagesize() * 2; +} + +static inline uint32_t +mm_max_page_allocatable_memory(){ + + return (uint32_t) + (SYSTEM_PAGE_SIZE - offset_of(vm_page_t, page_memory)); +} + +#define MAX_PAGE_ALLOCATABLE_MEMORY \ + (mm_max_page_allocatable_memory()) + +static vm_page_t * +mm_get_available_page_index(vm_page_family_t *vm_page_family){ + + vm_page_t *curr, *prev; + int page_index = -1; + + if(!vm_page_family->first_page) + return NULL; + + ITERATE_VM_PAGE_BEGIN(vm_page_family, curr){ + + if((int)(curr->page_index) == page_index + 1){ + page_index++; + prev = curr; + continue; + } + return curr->prev; + } ITERATE_VM_PAGE_END(vm_page_family, curr) + + return prev; +} + +/*Return a fresh new virtual page*/ +vm_page_t * +allocate_vm_page(vm_page_family_t *vm_page_family){ + + vm_page_t *prev_page = + mm_get_available_page_index(vm_page_family); + + vm_page_t *vm_page = calloc(1, SYSTEM_PAGE_SIZE); + vm_page->block_meta_data.is_free = MM_TRUE; + vm_page->block_meta_data.block_size = + MAX_PAGE_ALLOCATABLE_MEMORY; + vm_page->block_meta_data.offset = + offset_of(vm_page_t, block_meta_data); + init_glthread(&vm_page->block_meta_data.priority_thread_glue); + vm_page->block_meta_data.prev_block = NULL; + vm_page->block_meta_data.next_block = NULL; + vm_page->next = NULL; + vm_page->prev = NULL; + vm_page_family->no_of_system_calls_to_alloc_dealloc_vm_pages++; + vm_page->pg_family = vm_page_family; + + if(!prev_page){ + vm_page->page_index = 0; + vm_page->next = vm_page_family->first_page; + if(vm_page_family->first_page) + vm_page_family->first_page->prev = vm_page; + vm_page_family->first_page = vm_page; + return vm_page; + } + + vm_page->next = prev_page->next; + vm_page->prev = prev_page; + if(vm_page->next) + vm_page->next->prev = vm_page; + prev_page->next = vm_page; + vm_page->page_index = prev_page->page_index + 1; + return vm_page; +} + + +void +mm_instantiate_new_page_family( + char *struct_name, + uint32_t struct_size){ + + if(struct_size > SYSTEM_PAGE_SIZE){ + printf("Error : %s() Structure %s Size exceeds system page size\n", + __FUNCTION__, struct_name); + return; + } + + if(!first_vm_page_family){ + first_vm_page_family = calloc(1, sizeof(vm_page_family_t)); + strncpy(first_vm_page_family->struct_name, struct_name, + MM_MAX_STRUCT_NAME); + first_vm_page_family->struct_size = struct_size; + first_vm_page_family->first_page = NULL; + first_vm_page_family->next = NULL; + first_vm_page_family->prev = NULL; + init_glthread(&first_vm_page_family->free_block_priority_list_head); + return; + } + + vm_page_family_t *vm_page_family_curr; + + ITERATE_PAGE_FAMILIES_BEGIN(first_vm_page_family, vm_page_family_curr){ + + if(strncmp(vm_page_family_curr->struct_name, + struct_name, + MM_MAX_STRUCT_NAME) != 0){ + + continue; + } + /*Page family already exists*/ + assert(0); + } ITERATE_PAGE_FAMILIES_END(first_vm_page_family, vm_page_family_curr); + + /*Page family do not exist, create a new one*/ + vm_page_family_curr = calloc(1, sizeof(vm_page_family_t)); + strncpy(vm_page_family_curr->struct_name, struct_name, + MM_MAX_STRUCT_NAME); + vm_page_family_curr->struct_size = struct_size; + vm_page_family_curr->first_page = NULL; + init_glthread(&first_vm_page_family->free_block_priority_list_head); + + /*Add new page family to the list of Page families*/ + vm_page_family_curr->next = first_vm_page_family; + first_vm_page_family->prev = vm_page_family_curr; + first_vm_page_family = vm_page_family_curr; +} + +vm_page_family_t * +lookup_page_family_by_name(char *struct_name){ + + vm_page_family_t *vm_page_family_curr; + ITERATE_PAGE_FAMILIES_BEGIN(first_vm_page_family, vm_page_family_curr){ + + if(strncmp(vm_page_family_curr->struct_name, + struct_name, + MM_MAX_STRUCT_NAME) == 0){ + + return vm_page_family_curr; + } + } ITERATE_PAGE_FAMILIES_END(first_vm_page_family, vm_page_family_curr); + return NULL; +} + +static int +free_blocks_comparison_function( + void *_block_meta_data1, + void *_block_meta_data2){ + + block_meta_data_t *block_meta_data1 = + (block_meta_data_t *)_block_meta_data1; + + block_meta_data_t *block_meta_data2 = + (block_meta_data_t *)_block_meta_data2; + + if(block_meta_data1->block_size > block_meta_data2->block_size) + return -1; + else if(block_meta_data1->block_size < block_meta_data2->block_size) + return 1; + return 0; +} + +static void +mm_add_free_block_meta_data_to_free_block_list( + vm_page_family_t *vm_page_family, + block_meta_data_t *free_block){ + + assert(free_block->is_free == MM_TRUE); + glthread_priority_insert(&vm_page_family->free_block_priority_list_head, + &free_block->priority_thread_glue, + free_blocks_comparison_function, + offset_of(block_meta_data_t, priority_thread_glue)); +} + +static vm_page_t * +mm_family_new_page_add(vm_page_family_t *vm_page_family){ + + vm_page_t *vm_page = allocate_vm_page(vm_page_family); + + if(!vm_page) + return NULL; + + /* The new page is like one free block, add it to the + * free block list*/ + mm_add_free_block_meta_data_to_free_block_list( + vm_page_family, &vm_page->block_meta_data); + + return vm_page; +} + +/* Fn to mark block_meta_data as being Allocated for + * 'size' bytes of application data. Return TRUE if + * block allocation succeeds*/ +static vm_bool_t +mm_allocate_free_block( + vm_page_family_t *vm_page_family, + block_meta_data_t *block_meta_data, + uint32_t size){ + + assert(block_meta_data->is_free == MM_TRUE); + + assert(block_meta_data->block_size >= size); + + uint32_t remaining_size = + block_meta_data->block_size - size; + + block_meta_data->is_free = MM_FALSE; + block_meta_data->block_size = size; + + /*Unchanged*/ + //block_meta_data->offset = ?? + + /* Since this block of memory is not allocated, remove it from + * priority list of free blocks*/ + remove_glthread(&block_meta_data->priority_thread_glue); + + vm_page_family->total_memory_in_use_by_app += + sizeof(block_meta_data_t) + size; + /* No need to do anything else if this block is completely used + * to satisfy memory request*/ + if(!remaining_size) + return MM_TRUE; + + /* If the remaining memory chunk in this free block is unusable + * because of fragmentation - however this should not be possible + * except the boundry condition*/ + if(remaining_size < + (sizeof(block_meta_data_t) + vm_page_family->struct_size)){ + /*printf("Warning : %uB Memory Unusable at page bottom\n", + remaining_size);*/ + return MM_TRUE; + } + + block_meta_data_t *next_block_meta_data = NULL; + + next_block_meta_data = NEXT_META_BLOCK_BY_SIZE(block_meta_data); + + next_block_meta_data->is_free = MM_TRUE; + + next_block_meta_data->block_size = + remaining_size - sizeof(block_meta_data_t); + + next_block_meta_data->offset = block_meta_data->offset + + sizeof(block_meta_data_t) + block_meta_data->block_size; + + init_glthread(&next_block_meta_data->priority_thread_glue); + + mm_bind_blocks_for_allocation(block_meta_data, next_block_meta_data); + + mm_add_free_block_meta_data_to_free_block_list( + vm_page_family, next_block_meta_data); + + return MM_TRUE; +} + +static vm_page_t * +mm_get_page_satisfying_request( + vm_page_family_t *vm_page_family, + uint32_t req_size, + block_meta_data_t **block_meta_data/*O/P*/){ + + vm_bool_t status = MM_FALSE; + vm_page_t *vm_page = NULL; + + block_meta_data_t *biggest_block_meta_data = + mm_get_biggest_free_block_page_family(vm_page_family); + + if(!biggest_block_meta_data || + biggest_block_meta_data->block_size < req_size){ + + /*Time to add a new page to Page family to satisfy the request*/ + vm_page = mm_family_new_page_add(vm_page_family); + /*Allocate the free block from this page now*/ + status = mm_allocate_free_block(vm_page_family, + &vm_page->block_meta_data, req_size); + + if(status == MM_FALSE){ + *block_meta_data = NULL; + mm_vm_page_delete_and_free(vm_page); + return NULL; + } + + *block_meta_data = &vm_page->block_meta_data; + return vm_page; + } + /*The biggest block meta data can satisfy the request*/ + status = mm_allocate_free_block(vm_page_family, + biggest_block_meta_data, req_size); + + if(status == MM_FALSE){ + *block_meta_data = NULL; + return NULL; + } + + *block_meta_data = biggest_block_meta_data; + + return MM_GET_PAGE_FROM_META_BLOCK(biggest_block_meta_data); +} + +/* The public fn to be invoked by the application for Dynamic + * Memory Allocations.*/ +void * +xcalloc(char *struct_name, int units){ + + void *result = NULL; + + vm_page_family_t *pg_family = + lookup_page_family_by_name(struct_name); + + if(!pg_family){ + + printf("Error : Structure %s not registered with Memory Manager\n", + struct_name); + assert(0); + return NULL; + } + + if(units * pg_family->struct_size > MAX_PAGE_ALLOCATABLE_MEMORY){ + + printf("Error : Memory Requested Exceeds Page Size\n"); + assert(0); + return NULL; + } + + if(!pg_family->first_page){ + + pg_family->first_page = mm_family_new_page_add(pg_family); + + if(mm_allocate_free_block(pg_family, + &pg_family->first_page->block_meta_data, + units * pg_family->struct_size)){ + memset((char *)pg_family->first_page->page_memory, 0, + sizeof(units * pg_family->struct_size)); + return (void *)pg_family->first_page->page_memory; + } + } + + /*Find the page which can satisfy the request*/ + block_meta_data_t *free_block_meta_data; + + vm_page_t *vm_page_curr = mm_get_page_satisfying_request( + pg_family, units * pg_family->struct_size, + &free_block_meta_data); + + if(free_block_meta_data){ + /*Sanity Checks*/ + if(free_block_meta_data->is_free == MM_TRUE || + !IS_GLTHREAD_LIST_EMPTY(&free_block_meta_data->priority_thread_glue)){ + assert(0); + } + memset((char *)(free_block_meta_data + 1), 0, free_block_meta_data->block_size); + return (void *)(free_block_meta_data + 1); + } + + assert(0); + return NULL; +} + +static void +mm_union_free_blocks(block_meta_data_t *first, + block_meta_data_t *second){ + + assert(first->is_free == MM_TRUE && + second->is_free == MM_TRUE); + + first->block_size += sizeof(block_meta_data_t) + + second->block_size; + remove_glthread(&first->priority_thread_glue); + remove_glthread(&second->priority_thread_glue); + mm_bind_blocks_for_deallocation(first, second); +} + +void +mm_vm_page_delete_and_free( + vm_page_t *vm_page){ + + vm_page_family_t *vm_page_family = + vm_page->pg_family; + + assert(vm_page_family->first_page); + + if(vm_page_family->first_page == vm_page){ + vm_page_family->first_page = vm_page->next; + if(vm_page->next) + vm_page->next->prev = NULL; + vm_page_family->no_of_system_calls_to_alloc_dealloc_vm_pages++; + free(vm_page); + return; + } + + if(vm_page->next) + vm_page->next->prev = vm_page->prev; + vm_page->prev->next = vm_page->next; + vm_page_family->no_of_system_calls_to_alloc_dealloc_vm_pages++; + free(vm_page); +} + +static block_meta_data_t * +mm_free_blocks(block_meta_data_t *to_be_free_block){ + + block_meta_data_t *return_block = NULL; + + assert(to_be_free_block->is_free == MM_FALSE); + + vm_page_t *hosting_page = + MM_GET_PAGE_FROM_META_BLOCK(to_be_free_block); + + vm_page_family_t *vm_page_family = hosting_page->pg_family; + + vm_page_family->total_memory_in_use_by_app -= + sizeof(block_meta_data_t) + to_be_free_block->block_size; + + to_be_free_block->is_free = MM_TRUE; + + return_block = to_be_free_block; + + block_meta_data_t *next_block = NEXT_META_BLOCK(to_be_free_block); + + if(next_block && next_block->is_free == MM_TRUE){ + /*Union two free blocks*/ + mm_union_free_blocks(to_be_free_block, next_block); + return_block = to_be_free_block; + } + /*Check the previous block if it was free*/ + block_meta_data_t *prev_block = PREV_META_BLOCK(to_be_free_block); + + if(prev_block && prev_block->is_free){ + mm_union_free_blocks(prev_block, to_be_free_block); + return_block = prev_block; + } + + if(mm_is_vm_page_empty(hosting_page)){ + mm_vm_page_delete_and_free(hosting_page); + return NULL; + } + mm_add_free_block_meta_data_to_free_block_list( + hosting_page->pg_family, return_block); + + return return_block; +} + +void +xfree(void *app_data){ + + block_meta_data_t *block_meta_data = + (block_meta_data_t *)((char *)app_data - sizeof(block_meta_data_t)); + + assert(block_meta_data->is_free == MM_FALSE); + mm_free_blocks(block_meta_data); +} + +vm_bool_t +mm_is_vm_page_empty(vm_page_t *vm_page){ + + if(vm_page->block_meta_data.next_block == NULL && + vm_page->block_meta_data.prev_block == NULL && + vm_page->block_meta_data.is_free == MM_TRUE){ + + return MM_TRUE; + } + return MM_FALSE; +} + +void +mm_print_vm_page_details(vm_page_t *vm_page, uint32_t i){ + + printf("\tPage Index : %u \n", vm_page->page_index); + printf("\t\t next = %p, prev = %p\n", vm_page->next, vm_page->prev); + printf("\t\t page family = %s\n", vm_page->pg_family->struct_name); + + uint32_t j = 0; + block_meta_data_t *curr; + ITERATE_VM_PAGE_ALL_BLOCKS_BEGIN(vm_page, curr){ + + printf(ANSI_COLOR_YELLOW "\t\t\t%-14p Block %-3u %s block_size = %-6u " + "offset = %-6u prev = %-14p next = %p\n" + ANSI_COLOR_RESET, curr, + j++, curr->is_free ? "F R E E D" : "ALLOCATED", + curr->block_size, curr->offset, + curr->prev_block, + curr->next_block); + } ITERATE_VM_PAGE_ALL_BLOCKS_END(vm_page, curr); +} + +void +mm_print_memory_usage(){ + + uint32_t i = 0; + vm_page_t *vm_page = NULL; + vm_page_family_t *vm_page_family_curr; + uint32_t number_of_struct_families = 0; + uint32_t total_memory_in_use_by_application = 0; + uint32_t cumulative_vm_pages_claimed_from_kernel = 0; + + printf("\nPage Size = %zu Bytes\n", SYSTEM_PAGE_SIZE); + + ITERATE_PAGE_FAMILIES_BEGIN(first_vm_page_family, vm_page_family_curr){ + + number_of_struct_families++; + + printf(ANSI_COLOR_GREEN "vm_page_family : %s, struct size = %u\n" + ANSI_COLOR_RESET, + vm_page_family_curr->struct_name, + vm_page_family_curr->struct_size); + printf(ANSI_COLOR_CYAN "\tApp Used Memory %uB, #Sys Calls %u\n" + ANSI_COLOR_RESET, + vm_page_family_curr->total_memory_in_use_by_app, + vm_page_family_curr->\ + no_of_system_calls_to_alloc_dealloc_vm_pages); + + total_memory_in_use_by_application += + vm_page_family_curr->total_memory_in_use_by_app; + + i = 0; + + ITERATE_VM_PAGE_BEGIN(vm_page_family_curr, vm_page){ + + cumulative_vm_pages_claimed_from_kernel++; + mm_print_vm_page_details(vm_page, i++); + + } ITERATE_VM_PAGE_END(vm_page_family_curr, vm_page); + printf("\n"); + } ITERATE_PAGE_FAMILIES_END(first_vm_page_family, vm_page_family_curr); + + printf(ANSI_COLOR_MAGENTA "\nTotal Applcation Memory Usage : %u Bytes\n" + ANSI_COLOR_RESET, total_memory_in_use_by_application); + + printf(ANSI_COLOR_MAGENTA "# Of VM Pages in Use : %u (%lu Bytes)\n" \ + ANSI_COLOR_RESET, + cumulative_vm_pages_claimed_from_kernel, + SYSTEM_PAGE_SIZE * cumulative_vm_pages_claimed_from_kernel); + + float memory_app_use_to_total_memory_ratio = 0.0; + + if(cumulative_vm_pages_claimed_from_kernel){ + memory_app_use_to_total_memory_ratio = + (float)(total_memory_in_use_by_application * 100)/\ + (float)(cumulative_vm_pages_claimed_from_kernel * SYSTEM_PAGE_SIZE); + } + printf(ANSI_COLOR_MAGENTA "Memory In Use by Application = %f%%\n" + ANSI_COLOR_RESET, + memory_app_use_to_total_memory_ratio); + + printf("Total Memory being used by Memory Manager = %lu Bytes\n", + ((cumulative_vm_pages_claimed_from_kernel *\ + SYSTEM_PAGE_SIZE) + + (number_of_struct_families * sizeof(vm_page_family_t)))); +} + +void +mm_print_block_usage(){ + + vm_page_t *vm_page_curr; + vm_page_family_t *vm_page_family_curr; + block_meta_data_t *block_meta_data_curr; + uint32_t total_block_count, free_block_count, + occupied_block_count; + uint32_t application_memory_usage; + + ITERATE_PAGE_FAMILIES_BEGIN(first_vm_page_family, vm_page_family_curr){ + + total_block_count = 0; + free_block_count = 0; + application_memory_usage = 0; + occupied_block_count = 0; + ITERATE_VM_PAGE_BEGIN(vm_page_family_curr, vm_page_curr){ + + ITERATE_VM_PAGE_ALL_BLOCKS_BEGIN(vm_page_curr, block_meta_data_curr){ + + total_block_count++; + + /*Sanity Checks*/ + if(block_meta_data_curr->is_free == MM_FALSE){ + assert(IS_GLTHREAD_LIST_EMPTY(&block_meta_data_curr->\ + priority_thread_glue)); + } + if(block_meta_data_curr->is_free == MM_TRUE){ + assert(!IS_GLTHREAD_LIST_EMPTY(&block_meta_data_curr->\ + priority_thread_glue)); + } + + if(block_meta_data_curr->is_free == MM_TRUE){ + free_block_count++; + } + else{ + application_memory_usage += + block_meta_data_curr->block_size + \ + sizeof(block_meta_data_t); + occupied_block_count++; + } + } ITERATE_VM_PAGE_ALL_BLOCKS_END(vm_page_curr, block_meta_data_curr); + } ITERATE_VM_PAGE_END(vm_page_family_curr, vm_page_curr); + + printf("%-20s TBC : %-4u FBC : %-4u OBC : %-4u AppMemUsage : %u\n", + vm_page_family_curr->struct_name, total_block_count, + free_block_count, occupied_block_count, application_memory_usage); + + } ITERATE_PAGE_FAMILIES_END(first_vm_page_family, vm_page_family_curr); +} diff --git a/LinuxMemoryManager/mm.h b/LinuxMemoryManager/mm.h new file mode 100644 index 0000000..a476ba2 --- /dev/null +++ b/LinuxMemoryManager/mm.h @@ -0,0 +1,168 @@ +/* + * ===================================================================================== + * + * Filename: mm.h + * + * Description: This file defines the public APIs and Data structures used for Memory Manager + * + * Version: 1.0 + * Created: 01/30/2020 10:11:20 AM + * Revision: none + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), sachinites@gmail.com + * Company: Juniper Networks + * + * This file is part of the Linux Memory Manager distribution (https://github.com/sachinites) + * Copyright (c) 2019 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, version 3. + * + * 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. + * + * visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects + * + * ===================================================================================== + */ + +#ifndef __MM__ +#define __MM__ + +#include +#include "gluethread/glthread.h" +#include /*for size_t*/ + + +typedef enum{ + + MM_FALSE, + MM_TRUE +} vm_bool_t; + +typedef struct block_meta_data_{ + + vm_bool_t is_free; + uint32_t block_size; + uint32_t offset; /*offset from the start of the page*/ + glthread_t priority_thread_glue; + struct block_meta_data_ *prev_block; + struct block_meta_data_ *next_block; +} block_meta_data_t; +GLTHREAD_TO_STRUCT(glthread_to_block_meta_data, + block_meta_data_t, priority_thread_glue, glthread_ptr); + +#define offset_of(container_structure, field_name) \ + ((size_t)&(((container_structure *)0)->field_name)) + +/*Forward Declaration*/ +struct vm_page_family_; + +typedef struct vm_page_{ + struct vm_page_ *next; + struct vm_page_ *prev; + struct vm_page_family_ *pg_family; /*back pointer*/ + uint32_t page_index; + block_meta_data_t block_meta_data; + char page_memory[0]; +} vm_page_t; + +#define MM_GET_PAGE_FROM_META_BLOCK(block_meta_data_ptr) \ + ((vm_page_t *)((char *)block_meta_data_ptr - block_meta_data_ptr->offset)) + +#define NEXT_META_BLOCK(block_meta_data_ptr) \ + (block_meta_data_ptr->next_block) + +#define NEXT_META_BLOCK_BY_SIZE(block_meta_data_ptr) \ + (block_meta_data_t *)((char *)(block_meta_data_ptr + 1) \ + + block_meta_data_ptr->block_size) + +#define PREV_META_BLOCK(block_meta_data_ptr) \ + (block_meta_data_ptr->prev_block) + +#define mm_bind_blocks_for_allocation(allocated_meta_block, free_meta_block) \ + free_meta_block->prev_block = allocated_meta_block; \ + free_meta_block->next_block = allocated_meta_block->next_block; \ + allocated_meta_block->next_block = free_meta_block; \ + if (free_meta_block->next_block)\ + free_meta_block->next_block->prev_block = free_meta_block + +#define mm_bind_blocks_for_deallocation(freed_meta_block_top, freed_meta_block_down) \ + freed_meta_block_top->next_block = freed_meta_block_down->next_block; \ + if(freed_meta_block_down->next_block) \ + freed_meta_block_down->next_block->prev_block = freed_meta_block_top + +vm_bool_t +mm_is_vm_page_empty(vm_page_t *vm_page); + +#define MM_MAX_STRUCT_NAME 32 +typedef struct vm_page_family_{ + + char struct_name[MM_MAX_STRUCT_NAME]; + uint32_t struct_size; + vm_page_t *first_page; + struct vm_page_family_ *next; + struct vm_page_family_ *prev; + glthread_t free_block_priority_list_head; + /*Statistics*/ + uint32_t total_memory_in_use_by_app; + uint32_t no_of_system_calls_to_alloc_dealloc_vm_pages; +} vm_page_family_t; + +static inline block_meta_data_t * +mm_get_biggest_free_block_page_family( + vm_page_family_t *vm_page_family){ + + glthread_t *biggest_free_block_glue = + vm_page_family->free_block_priority_list_head.right; + + if(biggest_free_block_glue) + return glthread_to_block_meta_data(biggest_free_block_glue); + + return NULL; +} + +vm_page_t * +allocate_vm_page(); + +void +mm_init(); + +#define ITERATE_PAGE_FAMILIES_BEGIN(first_vm_page_family_ptr, curr) \ +{ \ + curr = first_vm_page_family_ptr; \ + vm_page_family_t *next = NULL; \ + for(; curr; curr = next){ \ + next = curr->next; + +#define ITERATE_PAGE_FAMILIES_END(first_vm_page_family_ptr, curr) \ + }} + +vm_page_family_t * +lookup_page_family_by_name(char *struct_name); + + +#define ITERATE_VM_PAGE_BEGIN(vm_page_family_ptr, curr) \ +{ \ + curr = vm_page_family_ptr->first_page; \ + vm_page_t *next = NULL; \ + for(; curr; curr = next){ \ + next = curr->next; + +#define ITERATE_VM_PAGE_END(vm_page_family_ptr, curr) \ + }} + +#define ITERATE_VM_PAGE_ALL_BLOCKS_BEGIN(vm_page_ptr, curr) \ +{\ + curr = &vm_page_ptr->block_meta_data;\ + block_meta_data_t *next = NULL;\ + for( ; curr; curr = next){\ + next = NEXT_META_BLOCK(curr); + +#define ITERATE_VM_PAGE_ALL_BLOCKS_END(vm_page_ptr, curr) \ + }} + +void mm_vm_page_delete_and_free(vm_page_t *vm_page); +#endif /**/ diff --git a/LinuxMemoryManager/uapi_mm.h b/LinuxMemoryManager/uapi_mm.h new file mode 100644 index 0000000..9b43c4e --- /dev/null +++ b/LinuxMemoryManager/uapi_mm.h @@ -0,0 +1,65 @@ +/* + * ===================================================================================== + * + * Filename: uapi_mm.h + * + * Description: This Header file ocntains public APIs to be used by the application + * + * Version: 1.0 + * Created: 02/01/2020 10:00:27 PM + * Revision: none + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), sachinites@gmail.com + * Company: Juniper Networks + * + * This file is part of the Linux Memory Manager distribution (https://github.com/sachinites) + * Copyright (c) 2019 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, version 3. + * + * 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. + * + * visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects + * + * ===================================================================================== + */ + +#ifndef __UAPI_MM__ +#define __UAPI_MM__ + +#include + +void * +xcalloc(char *struct_name, int units); + +void +xfree(void *app_ptr); + +/*Printing Functions*/ +void mm_print_memory_usage(); +void mm_print_block_usage(); + +/*Initialization Functions*/ +void +mm_init(); + +/*Registration function*/ +void +mm_instantiate_new_page_family( + char *struct_name, + uint32_t struct_size); + +#define XCALLOC(units, struct_name) \ + (xcalloc(#struct_name, units)) + +#define MM_REG_STRUCT(struct_name) \ + (mm_instantiate_new_page_family(#struct_name, sizeof(struct_name))) + +#define XFREE(ptr) \ + xfree(ptr) + +#endif /* __UAPI_MM__ */ diff --git a/LinuxMemoryManager/uapi_mm_new.h b/LinuxMemoryManager/uapi_mm_new.h new file mode 100644 index 0000000..9b43c4e --- /dev/null +++ b/LinuxMemoryManager/uapi_mm_new.h @@ -0,0 +1,65 @@ +/* + * ===================================================================================== + * + * Filename: uapi_mm.h + * + * Description: This Header file ocntains public APIs to be used by the application + * + * Version: 1.0 + * Created: 02/01/2020 10:00:27 PM + * Revision: none + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), sachinites@gmail.com + * Company: Juniper Networks + * + * This file is part of the Linux Memory Manager distribution (https://github.com/sachinites) + * Copyright (c) 2019 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, version 3. + * + * 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. + * + * visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects + * + * ===================================================================================== + */ + +#ifndef __UAPI_MM__ +#define __UAPI_MM__ + +#include + +void * +xcalloc(char *struct_name, int units); + +void +xfree(void *app_ptr); + +/*Printing Functions*/ +void mm_print_memory_usage(); +void mm_print_block_usage(); + +/*Initialization Functions*/ +void +mm_init(); + +/*Registration function*/ +void +mm_instantiate_new_page_family( + char *struct_name, + uint32_t struct_size); + +#define XCALLOC(units, struct_name) \ + (xcalloc(#struct_name, units)) + +#define MM_REG_STRUCT(struct_name) \ + (mm_instantiate_new_page_family(#struct_name, sizeof(struct_name))) + +#define XFREE(ptr) \ + xfree(ptr) + +#endif /* __UAPI_MM__ */ diff --git a/LinuxMemoryManager/uapi_mm_old.h b/LinuxMemoryManager/uapi_mm_old.h new file mode 100644 index 0000000..99d527b --- /dev/null +++ b/LinuxMemoryManager/uapi_mm_old.h @@ -0,0 +1,65 @@ +/* + * ===================================================================================== + * + * Filename: uapi_mm.h + * + * Description: This Header file ocntains public APIs to be used by the application + * + * Version: 1.0 + * Created: 02/01/2020 10:00:27 PM + * Revision: none + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), sachinites@gmail.com + * Company: Juniper Networks + * + * This file is part of the Linux Memory Manager distribution (https://github.com/sachinites) + * Copyright (c) 2019 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, version 3. + * + * 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. + * + * visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects + * + * ===================================================================================== + */ + +#ifndef __UAPI_MM__ +#define __UAPI_MM__ + +#include + +void * +xcalloc(char *struct_name, int units); + +void +xfree(void *app_ptr); + +/*Printing Functions*/ +void mm_print_memory_usage(); +void mm_print_block_usage(); + +/*Initialization Functions*/ +void +mm_init(); + +/*Registration function*/ +void +mm_instantiate_new_page_family( + char *struct_name, + uint32_t struct_size); + +#define XCALLOC(units, struct_name) \ + (calloc(units, sizeof(struct_name))) + +#define MM_REG_STRUCT(struct_name) \ + (mm_instantiate_new_page_family(#struct_name, sizeof(struct_name))) + +#define XFREE(ptr) \ + free(ptr) + +#endif /* __UAPI_MM__ */ diff --git a/Makefile b/Makefile index 9b565c5..212fc84 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ CC=gcc #GCOV=-fprofile-arcs -ftest-coverage CFLAGS=-g -Wall -O0 ${GCOV} -INCLUDES=-I . -I ./gluethread -I ./Stack -I ./CommandParser -I ./LinkedList -I ./Queue -I ./mpls -I ./BitOp -I ./Libtrace +INCLUDES=-I . -I ./gluethread -I ./Stack -I ./CommandParser -I ./LinkedList -I ./Queue -I ./mpls -I ./BitOp -I ./Libtrace -I ./LinuxMemoryManager USECLILIB=-lcli TARGET:rpd TARGET_NAME=rpd -DSOBJ=LinkedList/LinkedListApi.o Queue/Queue.o Stack/stack.o gluethread/glthread.o BitOp/bitarr.o Tree/redblack.o +DSOBJ=LinkedList/LinkedListApi.o Queue/Queue.o Stack/stack.o gluethread/glthread.o BitOp/bitarr.o Tree/redblack.o LinuxMemoryManager/mm.o OBJ=advert.o \ instance.o \ routes.o \ @@ -30,7 +30,8 @@ OBJ=advert.o \ glevel.o \ spring_adjsid.o \ flex_algo.o \ - tilfa.o + tilfa.o \ + mem_init.o ${TARGET_NAME}:testapp.o ${OBJ} ${DSOBJ} @echo "Building final executable : ${TARGET_NAME}" @echo "Linking with libcli.a(${USECLILIB})" @@ -42,6 +43,9 @@ conflct_res.o:conflct_res.c glevel.o:glevel.c @echo "Building glevel.o" @ ${CC} ${CFLAGS} -c ${INCLUDES} glevel.c -o glevel.o +mem_init.o:mem_init.c + @echo "Building mem_init.o" + @ ${CC} ${CFLAGS} -c ${INCLUDES} mem_init.c -o mem_init.o testapp.o:testapp.c @echo "Building testapp.o" @ ${CC} ${CFLAGS} -c ${INCLUDES} testapp.c -o testapp.o @@ -126,6 +130,8 @@ ${DSOBJ}: @ ${CC} ${CFLAGS} -c ${INCLUDES} BitOp/bitarr.c -o BitOp/bitarr.o @echo "Building Tree/redblack.o" @ ${CC} ${CFLAGS} -c -I ./Tree Tree/redblack.c -o Tree/redblack.o + @echo "Building Linux Memory Manager LinuxMemoryManager/mm.o" + @ ${CC} ${CFLAGS} -c -I ./LinuxMemoryManager LinuxMemoryManager/mm.c -o LinuxMemoryManager/mm.o clean: rm -f *.o rm -f rpd @@ -141,6 +147,7 @@ cleanall: rm -f gluethread/*.o rm -f BitOp/*.o rm -f Tree/*.o + rm -f LinuxMemoryManager/*.o (cd LinkedList; make clean) (cd CommandParser; make clean) make clean diff --git a/Queue/Queue.c b/Queue/Queue.c index 8ffae77..1856214 100755 --- a/Queue/Queue.c +++ b/Queue/Queue.c @@ -1,9 +1,10 @@ #include "Queue.h" #include #include +#include "../LinuxMemoryManager/uapi_mm.h" Queue_t* initQ(){ - Queue_t *q = calloc(1, sizeof(Queue_t)); + Queue_t *q = XCALLOC(1, Queue_t); q->rear = Q_DEFAULT_SIZE -1; q->front = q->rear; return q; diff --git a/Stack/stack.c b/Stack/stack.c index e3b0a57..2024134 100755 --- a/Stack/stack.c +++ b/Stack/stack.c @@ -3,11 +3,12 @@ #include #include #include "stack.h" +#include "../LinuxMemoryManager/uapi_mm.h" stack_t* get_new_stack() { - stack_t *stack = calloc(1, sizeof(stack_t)); + stack_t *stack = XCALLOC(1, stack_t); if(!stack) return NULL; memset(stack, 0, sizeof(stack_t)); @@ -100,6 +101,6 @@ void free_stack(stack_t *stack) { if(!stack) return; - free(stack); + XFREE(stack); return; } diff --git a/Tree/redblack.c b/Tree/redblack.c index f950a3b..55cae1e 100755 --- a/Tree/redblack.c +++ b/Tree/redblack.c @@ -12,6 +12,8 @@ #include #include "redblack.h" #endif +#include "../LinuxMemoryManager/uapi_mm.h" + /** * @file * @@ -51,7 +53,7 @@ redblack_root_free (rbroot *root) #ifdef _KERNEL FREE(root, M_IFSTATE); #else - free(root); + XFREE(root); #endif } diff --git a/advert.c b/advert.c index 9360fe3..140b12a 100644 --- a/advert.c +++ b/advert.c @@ -37,6 +37,7 @@ #include "spfutil.h" #include "Queue.h" #include "spftrace.h" +#include "LinuxMemoryManager/uapi_mm.h" char * advert_id_str(ADVERT_ID_T advert_id){ @@ -158,7 +159,7 @@ generate_lsp(instance_t *instance, assert(is_queue_empty(q)); reuse_q(q); } - free(q); + XFREE(q); q = NULL; } diff --git a/complete_spf_path.c b/complete_spf_path.c index b91893d..cc3efaf 100644 --- a/complete_spf_path.c +++ b/complete_spf_path.c @@ -40,6 +40,7 @@ #include "spf_candidate_tree.h" #include "no_warn.h" #include "sr_tlv_api.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; extern void init_instance_traversal(instance_t * instance); @@ -99,7 +100,7 @@ clear_spf_predecessors(glthread_t *spf_predecessors){ pred_info_t *pred_info = glthread_to_pred_info(curr); remove_glthread(curr); - free(pred_info); + XFREE(pred_info); } ITERATE_GLTHREAD_END(spf_predecessors, curr); } @@ -116,7 +117,7 @@ add_pred_info_to_spf_predecessors(spf_info_t *spf_info, pred_info_t *pred_info = NULL; - pred_info = calloc(1, sizeof(pred_info_t)); + pred_info = XCALLOC(1, pred_info_t); pred_info->oif = oif; @@ -131,7 +132,7 @@ add_pred_info_to_spf_predecessors(spf_info_t *spf_info, ITERATE_GLTHREAD_BEGIN(spf_predecessors, curr){ temp = glthread_to_pred_info(curr); if(pred_info_compare_fn((void *)pred_info, (void *)temp) == 0){ - free(pred_info); + XFREE(pred_info); return; } } ITERATE_GLTHREAD_END(spf_predecessors, curr); @@ -156,7 +157,7 @@ del_pred_info_from_spf_predecessors(glthread_t *spf_predecessors, node_t *pred_n if(pred_info_compare_fn(&pred_info, lst_pred_info)) continue; remove_glthread(&(lst_pred_info->glue)); - free(lst_pred_info); + XFREE(lst_pred_info); return; } ITERATE_GLTHREAD_END(spf_predecessors, curr); assert(0); @@ -465,7 +466,7 @@ run_spf_paths_dijkastra(node_t *spf_root, /*copy spf path list from node to its result*/ res = GET_SPF_PATH_RESULT(spf_root, candidate_node, level, nh); assert(!res); - res = calloc(1, sizeof(spf_path_result_t)); + res = XCALLOC(1, spf_path_result_t); init_glthread(&res->pred_db); init_glthread(&res->glue); glthread_add_next(&spf_root->spf_path_result[level][nh], &res->glue); @@ -484,7 +485,7 @@ run_spf_paths_dijkastra(node_t *spf_root, else if(spf_type == TILFA_RUN){ res = TILFA_GET_SPF_PATH_RESULT(spf_root, candidate_node, level); assert(!res); - res = calloc(1, sizeof(spf_path_result_t)); + res = XCALLOC(1, spf_path_result_t); init_glthread(&res->pred_db); init_glthread(&res->glue); glthread_add_next(tilfa_get_post_convergence_spf_path_head( @@ -561,7 +562,7 @@ run_spf_paths_dijkastra(node_t *spf_root, ITERATE_GLTHREAD_BEGIN(&candidate_node->pred_lst[level][nh], curr){ pred_info = glthread_to_pred_info(curr); - pred_info_copy = calloc(1, sizeof(pred_info_t)); + pred_info_copy = XCALLOC(1, pred_info_t); memcpy(pred_info_copy, pred_info, sizeof(pred_info_t)); #ifdef __ENABLE_TRACE__ sprintf(instance->traceopts->b, "Node : %s : Predecessor copied = %s", @@ -623,7 +624,7 @@ run_spf_paths_dijkastra(node_t *spf_root, ITERATE_GLTHREAD_BEGIN(&candidate_node->pred_lst[level][nh], curr){ pred_info = glthread_to_pred_info(curr); - pred_info_copy = calloc(1, sizeof(pred_info_t)); + pred_info_copy = XCALLOC(1, pred_info_t); memcpy(pred_info_copy, pred_info, sizeof(pred_info_t)); #ifdef __ENABLE_TRACE__ sprintf(instance->traceopts->b, "Node : %s : Predecessor copied = %s", @@ -660,7 +661,7 @@ run_spf_paths_dijkastra(node_t *spf_root, pred_info = glthread_to_pred_info(curr); remove_glthread(&pred_info->glue); - free(pred_info); + XFREE(pred_info); } ITERATE_GLTHREAD_END(&candidate_node->pred_lst[level][nh], curr); } #ifdef __ENABLE_TRACE__ @@ -693,10 +694,10 @@ spf_clear_spf_path_result(node_t *spf_root, LEVEL level){ pred_info = glthread_to_pred_info(curr1); remove_glthread(&pred_info->glue); - free(pred_info); + XFREE(pred_info); } ITERATE_GLTHREAD_END(&spf_path_result->pred_db, curr1); remove_glthread(&spf_path_result->glue); - free(spf_path_result); + XFREE(spf_path_result); } ITERATE_GLTHREAD_END(&spf_root->spf_path_result[level][nh], curr); init_glthread(&spf_root->spf_path_result[level][nh]); }ITERATE_NH_TYPE_END; @@ -750,7 +751,7 @@ compute_spf_paths(node_t *spf_root, LEVEL level, spf_type_t spf_type){ } run_spf_paths_dijkastra(spf_root, level, &instance->ctree, spf_type); assert(is_queue_empty(q)); - free(q); + XFREE(q); q = NULL; SPF_RE_INIT_CANDIDATE_TREE(&instance->ctree); } diff --git a/conflct_res.c b/conflct_res.c index e94d196..fb1ef5b 100644 --- a/conflct_res.c +++ b/conflct_res.c @@ -35,6 +35,7 @@ #include "sr_tlv_api.h" #include "spfutil.h" #include +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; diff --git a/data_plane.c b/data_plane.c index af9b37f..700be07 100644 --- a/data_plane.c +++ b/data_plane.c @@ -15,7 +15,7 @@ * * This file is part of the SPDComputation distribution (https://github.com/sachinites). * Copyright (c) 2017 Abhishek Sagar. - * This program is free software: you can redistribute it and/or modify + * This program is XFREE software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * @@ -38,6 +38,7 @@ #include "ldp.h" #include "spfutil.h" #include "stack.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; void @@ -176,16 +177,16 @@ is_mpls_0_un_nh_t_equal(internal_un_nh_t *nh1, internal_un_nh_t *nh2){ void free_un_nexthop(internal_un_nh_t *nh){ - free(nh); + XFREE(nh); } internal_un_nh_t * malloc_un_nexthop(){ - return calloc(1, sizeof(internal_un_nh_t)); + return XCALLOC(1, internal_un_nh_t); } int -free_rt_un_entry(rt_un_entry_t *rt_un_entry){ +XFREE_rt_un_entry(rt_un_entry_t *rt_un_entry){ internal_un_nh_t *nxt_hop = NULL; glthread_t *curr = NULL; @@ -201,7 +202,7 @@ free_rt_un_entry(rt_un_entry_t *rt_un_entry){ if(IS_GLTHREAD_LIST_EMPTY((&rt_un_entry->glthread))){ remove_glthread(&rt_un_entry->glthread); - free(rt_un_entry); + XFREE(rt_un_entry); return 0; } return -1; @@ -243,7 +244,7 @@ inet_0_rt_un_route_install_nexthop(rt_un_table_t *rib, rt_key_t *rt_key, LEVEL l internal_un_nh_t *existing_nh = NULL; if(!rt_un_entry){ - rt_un_entry = calloc(1, sizeof(rt_un_entry_t)); + rt_un_entry = XCALLOC(1, rt_un_entry_t); memcpy(&rt_un_entry->rt_key, rt_key, sizeof(rt_key_t)); time(&rt_un_entry->last_refresh_time); rt_un_entry->level = level; @@ -381,7 +382,7 @@ inet_0_rt_un_route_delete(rt_un_table_t *rib, rt_key_t *rt_key){ ITERATE_GLTHREAD_BEGIN(&rib->head, curr){ temp = glthread_to_rt_un_entry(curr); if(UN_RTENTRY_PFX_MATCH(temp, rt_key)){ - free_rt_un_entry(temp); + XFREE_rt_un_entry(temp); rib->count--; return TRUE; } @@ -407,7 +408,7 @@ inet_3_rt_un_route_install_nexthop(rt_un_table_t *rib, rt_key_t *rt_key, LEVEL l internal_un_nh_t *existing_nh = NULL; if(!rt_un_entry){ - rt_un_entry = calloc(1, sizeof(rt_un_entry_t)); + rt_un_entry = XCALLOC(1, rt_un_entry_t); memcpy(&rt_un_entry->rt_key, rt_key, sizeof(rt_key_t)); time(&rt_un_entry->last_refresh_time); rt_un_entry->level = level; @@ -544,7 +545,7 @@ inet_3_rt_un_route_delete(rt_un_table_t *rib, rt_key_t *rt_key){ ITERATE_GLTHREAD_BEGIN(&rib->head, curr){ temp = glthread_to_rt_un_entry(curr); if(UN_RTENTRY_PFX_MATCH(temp, rt_key)){ - free_rt_un_entry(temp); + XFREE_rt_un_entry(temp); rib->count--; return TRUE; } @@ -589,7 +590,7 @@ mpls_0_rt_un_route_install_nexthop(rt_un_table_t *rib, rt_key_t *rt_key, LEVEL l internal_un_nh_t *existing_nh = NULL; if(!rt_un_entry){ - rt_un_entry = calloc(1, sizeof(rt_un_entry_t)); + rt_un_entry = XCALLOC(1, rt_un_entry_t); memcpy(&rt_un_entry->rt_key, rt_key, sizeof(rt_key_t)); time(&rt_un_entry->last_refresh_time); rt_un_entry->level = level; @@ -701,7 +702,7 @@ mpls_0_rt_un_route_delete(rt_un_table_t *rib, rt_key_t *rt_key){ ITERATE_GLTHREAD_BEGIN(&rib->head, curr){ temp = glthread_to_rt_un_entry(curr); if(UN_RTENTRY_LABEL_MATCH(temp, rt_key)){ - free_rt_un_entry(temp); + XFREE_rt_un_entry(temp); rib->count--; return TRUE; } @@ -855,7 +856,7 @@ mpls_0_unifiy_nexthop(internal_nh_t *nexthop, PROTOCOL proto){ rt_un_table_t * init_rib(rib_type_t rib_type){ - rt_un_table_t * rib = calloc(1, sizeof(rt_un_table_t)); + rt_un_table_t * rib = XCALLOC(1, rt_un_table_t); rib->count = 0; init_glthread(&rib->head); @@ -907,7 +908,7 @@ flush_rib(rt_un_table_t *rib, LEVEL level){ rt_un_entry = glthread_to_rt_un_entry(curr); if(rt_un_entry->level != level) continue; - rc = free_rt_un_entry(rt_un_entry); + rc = XFREE_rt_un_entry(rt_un_entry); if(rc == 0) count++; } ITERATE_GLTHREAD_END(&rib->head, curr); rib->count -= count; @@ -1596,10 +1597,10 @@ ping(char *node_name, char *dst_prefix){ if(IS_MPLS_LABEL_STACK_EMPTY(mpls_label_stack)){ /* Auto Done : :D : * Get the prefix from mpls_label_stack and feed it to Ist pref order to next_node*/ - free_mpls_label_stack(mpls_label_stack); + XFREE_mpls_label_stack(mpls_label_stack); } else{ - free_mpls_label_stack(mpls_label_stack); + XFREE_mpls_label_stack(mpls_label_stack); return -1; } } @@ -1630,16 +1631,16 @@ ping(char *node_name, char *dst_prefix){ mpls_label_stack_t * get_new_mpls_label_stack(){ - mpls_label_stack_t *mpls_stack = calloc(1, sizeof(mpls_label_stack_t)); - mpls_stack->stack = get_new_stack(); - return mpls_stack; + mpls_label_stack_t *mpls_stack = XCALLOC(1, mpls_label_stack_t); + mpls_stack->stack = get_new_stack(); + return mpls_stack; } void -free_mpls_label_stack(mpls_label_stack_t *mpls_label_stack){ +XFREE_mpls_label_stack(mpls_label_stack_t *mpls_label_stack){ free_stack(mpls_label_stack->stack); - free(mpls_label_stack); + XFREE(mpls_label_stack); } void @@ -1658,7 +1659,7 @@ void SWAP_MPLS_LABEL(mpls_label_stack_t *mpls_label_stack, mpls_label_t label){ POP_MPLS_LABEL(mpls_label_stack); - PUSH_MPLS_LABEL(mpls_label_stack, label); + PUSH_MPLS_LABEL(mpls_label_stack, label); } char * diff --git a/igp_sr_ext.c b/igp_sr_ext.c index 830fde9..475e54a 100644 --- a/igp_sr_ext.c +++ b/igp_sr_ext.c @@ -43,6 +43,7 @@ #include "sr_tlv_api.h" #include "bitarr.h" #include "no_warn.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; @@ -142,7 +143,7 @@ spring_disable_cleanup(node_t *node){ prefix_sid_subtlv_t *prefix_sid = NULL; free((SRGB_INDEX_ARRAY(node->srgb))->array); - free(node->srgb); + XFREE(node->srgb); node->use_spring_backups = FALSE; /*Break the association between prefixes and prefix SIDs*/ diff --git a/instance.c b/instance.c index c782fdf..876ff36 100644 --- a/instance.c +++ b/instance.c @@ -38,8 +38,10 @@ #include "spfutil.h" #include "spftrace.h" #include "spf_candidate_tree.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; +extern void init_memory_manager(); static void add_node_to_owning_instance(instance_t *instance, node_t *node){ @@ -151,7 +153,7 @@ create_new_edge(char *from_ifname, prefix_t *to_prefix, LEVEL level){/*LEVEL value can be LEVEL12 also*/ - edge_t *edge = calloc(1, sizeof(edge_t)); + edge_t *edge = XCALLOC(1, edge_t); /*ifnames may be specified as NULL in case of edges incoming to PN or * outgoing from PN*/ @@ -205,7 +207,7 @@ create_new_lsp_adj(char *lsp_name, unsigned int metric, LEVEL level){ - edge_t *edge = calloc(1, sizeof(edge_t)); + edge_t *edge = XCALLOC(1, edge_t); strncpy(edge->from.intf_name, lsp_name, IF_NAME_SIZE); edge->from.intf_name[IF_NAME_SIZE - 1] = '\0'; @@ -391,12 +393,13 @@ extern void init_pfe(); instance_t * get_new_instance(){ - instance_t *instance = calloc(1, sizeof(instance_t)); + init_memory_manager(); + instance_t *instance = XCALLOC(1, instance_t); instance->instance_node_list = init_singly_ll(); singly_ll_set_comparison_fn(instance->instance_node_list, instance_node_comparison_fn); SPF_CANDIDATE_TREE_INIT(&instance->ctree); - instance->traceopts = calloc(1, sizeof(traceoptions)); + instance->traceopts = XCALLOC(1, traceoptions); init_trace(instance->traceopts); register_display_trace_options(instance->traceopts, _spf_display_trace_options); enable_spf_trace(instance, SPF_EVENTS_BIT); diff --git a/mem_init.c b/mem_init.c new file mode 100644 index 0000000..bb6c418 --- /dev/null +++ b/mem_init.c @@ -0,0 +1,97 @@ +/* + * ===================================================================================== + * + * Filename: mem_init.c + * + * Description: This file integrates the Linux Memory Manager with the SPF Project + * + * Version: 1.0 + * Created: 02/15/2020 11:42:22 AM + * Revision: none + * Compiler: gcc + * + * Author: Er. Abhishek Sagar, Juniper Networks (https://csepracticals.wixsite.com/csepracticals), sachinites@gmail.com + * Company: Juniper Networks + * + * This file is part of the SPFComputation distribution (https://github.com/sachinites) + * Copyright (c) 2019 Abhishek Sagar. + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General + * Public License as published by the Free Software Foundation, version 3. + * + * 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. + * + * visit website : https://csepracticals.wixsite.com/csepracticals for more courses and projects + * + * ===================================================================================== + */ + +#include "BitOp/bitarr.h" +#include "LinkedList/LinkedListApi.h" +#include "Queue/Queue.h" +#include "Stack/stack.h" +#include "complete_spf_path.h" +#include "data_plane.h" +#include "instance.h" +#include "Libtrace/libtrace.h" +#include "prefix.h" +#include "routes.h" +#include "spfcomputation.h" +#include "igp_sr_ext.h" +#include "mpls/rsvp.h" +#include "mpls/ldp.h" +#include "spring_adjsid.h" +#include "tilfa.h" +#include "gluethread/glthread.h" +#include "LinuxMemoryManager/uapi_mm.h" + +static boolean is_mm_registered = FALSE; + +void +init_memory_manager(){ + + if(is_mm_registered) + return; + is_mm_registered = TRUE; + + mm_init(); + MM_REG_STRUCT(bit_array_t); + MM_REG_STRUCT(ll_t); + MM_REG_STRUCT(singly_ll_node_t); + MM_REG_STRUCT(Queue_t); + MM_REG_STRUCT(stack_t); + MM_REG_STRUCT(pred_info_t); + MM_REG_STRUCT(spf_path_result_t); + MM_REG_STRUCT(internal_un_nh_t); + MM_REG_STRUCT(rt_un_entry_t); + MM_REG_STRUCT(rt_un_table_t); + MM_REG_STRUCT(mpls_label_stack_t); + //MM_REG_STRUCT(node_t); + MM_REG_STRUCT(edge_t); + MM_REG_STRUCT(instance_t); + MM_REG_STRUCT(traceoptions); + MM_REG_STRUCT(prefix_t); + MM_REG_STRUCT(routes_t); + MM_REG_STRUCT(internal_nh_t); + MM_REG_STRUCT(srgb_t); + MM_REG_STRUCT(rsvp_tunnel_t); + MM_REG_STRUCT(ldp_config_t); + MM_REG_STRUCT(rsvp_config_t); + MM_REG_STRUCT(spf_result_t); + MM_REG_STRUCT(self_spf_result_t); + MM_REG_STRUCT(lan_intf_adj_sid_t); + MM_REG_STRUCT(p2p_intf_adj_sid_t); + MM_REG_STRUCT(lan_adj_sid_subtlv_t); + MM_REG_STRUCT(p2p_adj_sid_subtlv_t); + MM_REG_STRUCT(prefix_sid_subtlv_t); + MM_REG_STRUCT(tilfa_remote_spf_result_t); + MM_REG_STRUCT(tilfa_info_t); + MM_REG_STRUCT(tilfa_lcl_config_t); + MM_REG_STRUCT(protected_resource_t); + MM_REG_STRUCT(tilfa_cfg_globals_t); + MM_REG_STRUCT(glthread_t); + //MM_REG_STRUCT(gen_segment_list_t); + //MM_REG_STRUCT(tilfa_segment_list_t); +} diff --git a/prefix.c b/prefix.c index 41d45e9..6608bee 100644 --- a/prefix.c +++ b/prefix.c @@ -41,13 +41,14 @@ #include "routes.h" #include "spftrace.h" #include "sr_tlv_api.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; prefix_t * create_new_prefix(const char *prefix, unsigned char mask, LEVEL level){ - prefix_t *prefix2 = calloc(1, sizeof(prefix_t)); + prefix_t *prefix2 = XCALLOC(1, prefix_t); if(prefix) strncpy(prefix2->prefix, prefix, PREFIX_LEN); prefix2->prefix[PREFIX_LEN] = '\0'; @@ -488,11 +489,11 @@ void free_prefix(prefix_t *prefix){ if(!prefix->psid_thread_ptr){ - free(prefix); + XFREE(prefix); return; } free_prefix_sid(prefix); - free(prefix); + XFREE(prefix); } /*Return true if node is one of the best prefix originator for a route*/ diff --git a/routes.c b/routes.c index 3d72c30..1d7bb23 100644 --- a/routes.c +++ b/routes.c @@ -130,7 +130,7 @@ routes_t * route_malloc(){ nh_type_t nh; - routes_t *route = calloc(1, sizeof(routes_t)); + routes_t *route = XCALLOC(1, routes_t); ITERATE_NH_TYPE_BEGIN(nh){ route->primary_nh_list[nh] = init_singly_ll(); singly_ll_set_comparison_fn(route->primary_nh_list[nh], instance_node_comparison_fn); @@ -156,7 +156,7 @@ merge_route_primary_nexthops(routes_t *route, spf_result_t *result, nh_type_t nh if(is_internal_nh_exist(route->primary_nh_list[nh], &result->next_hop[nh][i])) continue; - int_nxt_hop = calloc(1, sizeof(internal_nh_t)); + int_nxt_hop = XCALLOC(1, internal_nh_t); copy_internal_nh_t(result->next_hop[nh][i], *int_nxt_hop); singly_ll_add_node_by_val(route->primary_nh_list[nh], int_nxt_hop); #ifdef __ENABLE_TRACE__ @@ -212,7 +212,7 @@ merge_route_backup_nexthops(routes_t *route, } } - int_nxt_hop = calloc(1, sizeof(internal_nh_t)); + int_nxt_hop = XCALLOC(1, internal_nh_t); copy_internal_nh_t(result->node->backup_next_hop[route->level][nh][i], *int_nxt_hop); singly_ll_add_node_by_val(route->backup_nh_list[nh], int_nxt_hop); #ifdef __ENABLE_TRACE__ @@ -242,19 +242,19 @@ free_route(routes_t *route){ ITERATE_NH_TYPE_BEGIN(nh){ ROUTE_FLUSH_PRIMARY_NH_LIST(route, nh); - free(route->primary_nh_list[nh]); + XFREE(route->primary_nh_list[nh]); route->primary_nh_list[nh] = 0; ROUTE_FLUSH_BACKUP_NH_LIST(route, nh); - free(route->backup_nh_list[nh]); + XFREE(route->backup_nh_list[nh]); route->backup_nh_list[nh] = 0; } ITERATE_NH_TYPE_END; if(route->rt_type == UNICAST_T){ delete_singly_ll(route->like_prefix_list); } - free(route->like_prefix_list); + XFREE(route->like_prefix_list); route->like_prefix_list = NULL; - free(route); + XFREE(route); } routes_t * @@ -418,7 +418,7 @@ overwrite_route(spf_info_t *spf_info, routes_t *route, for(i = 0 ; i < MAX_NXT_HOPS; i++){ if(!is_internal_nh_t_empty(result->next_hop[nh][i])){ - int_nxt_hop = calloc(1, sizeof(internal_nh_t)); + int_nxt_hop = XCALLOC(1, internal_nh_t); copy_internal_nh_t(result->next_hop[nh][i], *int_nxt_hop); ROUTE_ADD_NH(route->primary_nh_list[nh], int_nxt_hop); #ifdef __ENABLE_TRACE__ @@ -456,7 +456,7 @@ overwrite_route(spf_info_t *spf_info, routes_t *route, } } - int_nxt_hop = calloc(1, sizeof(internal_nh_t)); + int_nxt_hop = XCALLOC(1, internal_nh_t); copy_internal_nh_t((result->node->backup_next_hop[level][nh][i]), *int_nxt_hop); ROUTE_ADD_NH(route->backup_nh_list[nh], int_nxt_hop); #ifdef __ENABLE_TRACE__ @@ -657,7 +657,7 @@ update_route(spf_info_t *spf_info, /*spf_info of computing node*/ for(i = 0; i < MAX_NXT_HOPS; i++){ if(!is_internal_nh_t_empty(result->next_hop[nh][i])){ - int_nxt_hop = calloc(1, sizeof(internal_nh_t)); + int_nxt_hop = XCALLOC(1, internal_nh_t); copy_internal_nh_t(result->next_hop[nh][i], *int_nxt_hop); ROUTE_ADD_NH(route->primary_nh_list[nh], int_nxt_hop); #ifdef __ENABLE_TRACE__ @@ -671,7 +671,7 @@ update_route(spf_info_t *spf_info, /*spf_info of computing node*/ } for(i = 0 ; i < MAX_NXT_HOPS; i++){ if(!is_internal_nh_t_empty((result->node->backup_next_hop[level][nh][i]))){ - int_nxt_hop = calloc(1, sizeof(internal_nh_t)); + int_nxt_hop = XCALLOC(1, internal_nh_t); copy_internal_nh_t((result->node->backup_next_hop[level][nh][i]), *int_nxt_hop); ROUTE_ADD_NH(route->backup_nh_list[nh], int_nxt_hop); #ifdef __ENABLE_TRACE__ @@ -1110,7 +1110,7 @@ refine_route_backups(routes_t *route){ backup->protected_link->intf_name); trace(instance->traceopts, ROUTE_CALCULATION_BIT); #endif - free(backup); + XFREE(backup); ITERATIVE_LIST_NODE_DELETE2(route->backup_nh_list[nh], list_node1, prev_list_node); } } ITERATE_LIST_END2(route->backup_nh_list[nh], list_node1, prev_list_node); @@ -1491,7 +1491,7 @@ update_node_segment_routes_for_remote(spf_info_t *spf_info, LEVEL level){ ITERATE_NH_TYPE_BEGIN(nh){ ITERATE_LIST_BEGIN(igp_route->primary_nh_list[nh], list_node){ nxthop = list_node->data; - new_nxthop = calloc(1, sizeof(internal_nh_t)); + new_nxthop = XCALLOC(1, internal_nh_t); copy_internal_nh_t(*nxthop, *new_nxthop); singly_ll_add_node_by_val(sr_route->primary_nh_list[nh], new_nxthop); } ITERATE_LIST_END; @@ -1500,7 +1500,7 @@ update_node_segment_routes_for_remote(spf_info_t *spf_info, LEVEL level){ ITERATE_NH_TYPE_BEGIN(nh){ ITERATE_LIST_BEGIN(igp_route->backup_nh_list[nh], list_node){ nxthop = list_node->data; - new_nxthop = calloc(1, sizeof(internal_nh_t)); + new_nxthop = XCALLOC(1, internal_nh_t); copy_internal_nh_t(*nxthop, *new_nxthop); singly_ll_add_node_by_val(sr_route->backup_nh_list[nh], new_nxthop); } ITERATE_LIST_END; diff --git a/routes.h b/routes.h index 767e297..daea89e 100644 --- a/routes.h +++ b/routes.h @@ -34,6 +34,7 @@ #define __ROUTES__ #include "instance.h" +#include "LinuxMemoryManager/uapi_mm.h" typedef struct routes_{ @@ -82,7 +83,7 @@ ROUTE_FLUSH_PRIMARY_NH_LIST(routes_t *route, nh_type_t nh){ ITERATE_LIST_BEGIN(route->primary_nh_list[nh], list_node){ - free(list_node->data); + XFREE(list_node->data); list_node->data = NULL; } ITERATE_LIST_END; @@ -104,7 +105,7 @@ ROUTE_FLUSH_BACKUP_NH_LIST(routes_t *route, nh_type_t nh){ ITERATE_LIST_BEGIN(route->backup_nh_list[nh], list_node){ - free(list_node->data); + XFREE(list_node->data); list_node->data = NULL; } ITERATE_LIST_END; diff --git a/spfclihandler.c b/spfclihandler.c index a5f1092..65dd9e1 100644 --- a/spfclihandler.c +++ b/spfclihandler.c @@ -46,6 +46,7 @@ #include "no_warn.h" #include "complete_spf_path.h" #include "spring_adjsid.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t * instance; @@ -909,7 +910,7 @@ instance_node_spring_config_handler(param_t *param, ser_buff_t *tlv_buf, op_mode return 0; } node->spring_enabled = TRUE; - node->srgb = calloc(1, sizeof(srgb_t)); + node->srgb = XCALLOC(1, srgb_t); init_srgb_defaults(node->srgb); break; case CONFIG_DISABLE: @@ -1067,7 +1068,7 @@ instance_node_spring_show_handler(param_t *param, ser_buff_t *tlv_buf, op_mode e prefix->hosting_node->node_name, PREFIX_SID_INDEX(prefix)); } ITERATE_LIST_END; delete_singly_ll(res); - free(res); + XFREE(res); } break; case CMDCODE_DEBUG_SHOW_PREFIX_SID_CONFLICT_RESULT: @@ -1091,7 +1092,7 @@ instance_node_spring_show_handler(param_t *param, ser_buff_t *tlv_buf, op_mode e prefix->hosting_node->node_name, PREFIX_SID_INDEX(prefix)); } ITERATE_LIST_END; delete_singly_ll(res); - free(res); + XFREE(res); } break; case CMDCODE_SHOW_NODE_SPRING: @@ -1139,7 +1140,7 @@ debug_trace_mpls_stack_label(param_t *param, ser_buff_t *tlv_buf, op_mode enable node = (node_t *)singly_ll_search_by_key(instance->instance_node_list, node_name); transient_mpls_pfe_engine(node, mpls_label_stack, &next_node); - free_mpls_label_stack(mpls_label_stack); + XFREE_mpls_label_stack(mpls_label_stack); return 0; } @@ -1239,12 +1240,12 @@ instance_node_rsvp_config_handler(param_t *param, ser_buff_t *tlv_buf, op_mode e if(rc == -1) { printf("RSVP tunnel creation failed\n"); } - rsvp_tunnel = calloc(1, sizeof(rsvp_tunnel_t)); + rsvp_tunnel = XCALLOC(1, rsvp_tunnel_t); memcpy(rsvp_tunnel, &rsvp_tunnel_data, sizeof(rsvp_tunnel_t)); strncpy(rsvp_tunnel->lsp_name, rsvp_lsp_name, RSVP_LSP_NAME_SIZE); rc = add_new_rsvp_tunnel(node, rsvp_tunnel); if(rc == -1){ - free(rsvp_tunnel); + XFREE(rsvp_tunnel); } } break; diff --git a/spfcmdcodes.h b/spfcmdcodes.h index 4ed3b95..e1b86d2 100644 --- a/spfcmdcodes.h +++ b/spfcmdcodes.h @@ -179,4 +179,5 @@ #define CMDCODE_DEBUG_SHOW_TILFA 112 /*debug show instance node tilfa*/ #define CMDCODE_CONFIG_NODE_TILFA_ENABLE 113 /*config node source-packet-routing use-post-convergence-paths*/ #define CMDCODE_DEBUG_TRACEOPTIONS_TILFA 114 /*config debug set trace tilfa*/ +#define CMDCODE_DEBUG_SHOW_MEMORY_USAGE 115 /*debug show mem-usage*/ #endif /* __SPFCMDCODES__H */ diff --git a/spfcomputation.c b/spfcomputation.c index 7642941..3faae73 100644 --- a/spfcomputation.c +++ b/spfcomputation.c @@ -42,6 +42,7 @@ #include "no_warn.h" #include "complete_spf_path.h" #include "spf_candidate_tree.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; @@ -201,7 +202,7 @@ run_dijkastra(node_t *spf_root, LEVEL level, candidate_tree_t *ctree, if(candidate_node->node_type[level] != PSEUDONODE){ res = singly_ll_search_by_key(res_lst, candidate_node); if(!res) { - res = calloc(1, sizeof(spf_result_t)); + res = XCALLOC(1, spf_result_t); singly_ll_add_node_by_val(res_lst, (void *)res); } } @@ -230,7 +231,7 @@ run_dijkastra(node_t *spf_root, LEVEL level, candidate_tree_t *ctree, sprintf(instance->traceopts->b, "Curr node : %s, Creating New self spf result with spf root %s", candidate_node->node_name, spf_root->node_name); trace(instance->traceopts, DIJKSTRA_BIT); #endif - self_res = calloc(1, sizeof(self_spf_result_t)); + self_res = XCALLOC(1, self_spf_result_t); self_res->spf_root = spf_root; self_res->res = res; singly_ll_add_node_by_val(candidate_node->self_spf_result[level], self_res); @@ -468,11 +469,11 @@ spf_clear_result(node_t *spf_root, LEVEL level){ result->node->self_spf_result[level], self_result); - free(self_result); + XFREE(self_result); self_result = NULL; } - free(result); + XFREE(result); result = NULL; }ITERATE_LIST_END; delete_singly_ll(spf_root->spf_run_result[level]); @@ -547,7 +548,7 @@ spf_init(candidate_tree_t *ctree, ITERATE_NODE_LOGICAL_NBRS_END; } assert(is_queue_empty(q)); - free(q); + XFREE(q); q = NULL; /* step 3 : Initialize direct nexthops. diff --git a/spfdcm.c b/spfdcm.c index b26e047..80dab99 100644 --- a/spfdcm.c +++ b/spfdcm.c @@ -47,6 +47,7 @@ #include "no_warn.h" #include "spf_candidate_tree.h" #include "complete_spf_path.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; @@ -177,6 +178,14 @@ validate_metric_value(char *value_passed){ return VALIDATION_FAILED; } +static int +display_mem_usage(param_t *param, ser_buff_t *tlv_buf, + op_mode enable_or_disable){ + + mm_print_memory_usage(); + mm_print_block_usage(); +} + static int node_slot_config_handler(param_t *param, ser_buff_t *tlv_buf, op_mode enable_or_disable){ @@ -2006,6 +2015,13 @@ spf_init_dcm(){ /*debug show commands*/ { + { + /*debug show mem-usage*/ + static param_t mem_usage; + init_param(&mem_usage, CMD, "mem-usage", display_mem_usage, 0, INVALID, 0, "Memory Usage"); + libcli_register_param(debug_show, &mem_usage); + set_param_cmd_code(&mem_usage, CMDCODE_DEBUG_SHOW_MEMORY_USAGE); + } /*debug show log-status*/ { static param_t log_status; diff --git a/spfutil.c b/spfutil.c index 64cafe4..8c0f7b5 100644 --- a/spfutil.c +++ b/spfutil.c @@ -36,6 +36,7 @@ #include "Queue.h" #include "advert.h" #include "spftrace.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; @@ -283,7 +284,7 @@ get_system_id_from_router_id(node_t *ingress_lsr, } if(strncmp(nbr_node->router_id, tail_end_ip, PREFIX_LEN) == 0){ - free(q); + XFREE(q); q = NULL; return nbr_node; } @@ -293,7 +294,7 @@ get_system_id_from_router_id(node_t *ingress_lsr, ITERATE_NODE_PHYSICAL_NBRS_END(curr_node, nbr_node, pn_node, level); } assert(is_queue_empty(q)); - free(q); + XFREE(q); q = NULL; return NULL; } diff --git a/spring_adjsid.c b/spring_adjsid.c index bf4dcd2..3a17471 100644 --- a/spring_adjsid.c +++ b/spring_adjsid.c @@ -36,6 +36,7 @@ #include "spfcmdcodes.h" #include "instance.h" #include "spfutil.h" +#include "LinuxMemoryManager/uapi_mm.h" void print_lan_adj_sid_info(edge_end_t *interface, @@ -168,7 +169,7 @@ set_adj_sid(node_t *node, char *intf_name, LEVEL level, } if(head){ - lan_intf_adj_sid_t *lan_intf_adj_sid = calloc(1, sizeof(lan_intf_adj_sid_t)); + lan_intf_adj_sid_t *lan_intf_adj_sid = XCALLOC(1, lan_intf_adj_sid_t); lan_intf_adj_sid->adj_sid_type = ADJ_SID_TYPE_LABEL; /*We support only labels*/ lan_intf_adj_sid->sid.sid = label; strncpy(lan_intf_adj_sid->nbr_system_id, nbr_sys_id, PREFIX_LEN); diff --git a/sr_tlv_api.c b/sr_tlv_api.c index f536594..40ec337 100644 --- a/sr_tlv_api.c +++ b/sr_tlv_api.c @@ -36,6 +36,7 @@ #include "spfutil.h" #include "bitsop.h" #include "glthread.h" +#include "LinuxMemoryManager/uapi_mm.h" void diplay_prefix_sid(prefix_t *prefix){ @@ -210,7 +211,7 @@ update_prefix_sid(node_t *node, prefix_t *prefix, prefix_sid_subtlv_t *prefix_sid = NULL; if(!prefix->psid_thread_ptr){ - prefix_sid = calloc(1, sizeof(prefix_sid_subtlv_t)); + prefix_sid = XCALLOC(1, prefix_sid_subtlv_t); prefix_sid->type = PREFIX_SID_SUBTLV_TYPE; prefix_sid->length = 0; /*never used*/ prefix_sid->flags = 0; @@ -267,5 +268,5 @@ free_prefix_sid(prefix_t *prefix){ prefix_sid_subtlv_t *prefix_sid = glthread_to_prefix_sid(glthread); prefix_sid->prefix = NULL; remove_glthread(glthread); - free(prefix_sid); + XFREE(prefix_sid); } diff --git a/testapp.c b/testapp.c index fc1bf86..ce0f8e1 100644 --- a/testapp.c +++ b/testapp.c @@ -92,8 +92,8 @@ main(int argc, char **argv){ //instance = tilfa_topo_one_hop_test(); //instance = tilfa_topo_p_q_distance_1(); //instance = tilfa_topo_page_408_node_protection(); - instance = tilfa_topo_2_adj_segment_example(); - //instance = tilfa_ecmp_topology(); + //instance = tilfa_topo_2_adj_segment_example(); + instance = tilfa_ecmp_topology(); start_shell(); return 0; } diff --git a/tilfa.c b/tilfa.c index b3f92f2..26171a0 100644 --- a/tilfa.c +++ b/tilfa.c @@ -143,14 +143,14 @@ tilfa_get_remote_spf_result_lst(tilfa_info_t *tilfa_info, ITERATE_LIST_BEGIN2(inner_lst, curr1, prev1){ spf_res = curr1->data; - free(spf_res); + XFREE(spf_res); }ITERATE_LIST_END2(inner_lst, curr1, prev1); delete_singly_ll(inner_lst); return inner_lst; } } ITERATE_LIST_END2(outer_lst, curr, prev); - tilfa_rem_spf_result = calloc(1, sizeof(tilfa_remote_spf_result_t)); + tilfa_rem_spf_result = XCALLOC(1, tilfa_remote_spf_result_t); tilfa_rem_spf_result->node = node; tilfa_rem_spf_result->rem_spf_result_lst = init_singly_ll(); @@ -213,7 +213,7 @@ init_tilfa(node_t *node){ LEVEL level_it; - node->tilfa_info = calloc(1, sizeof(tilfa_info_t)); + node->tilfa_info = XCALLOC(1, tilfa_info_t); node->tilfa_info->tilfa_gl_var.max_segments_allowed = TILFA_MAX_SEGMENTS; init_glthread(&node->tilfa_info->tilfa_lcl_config_head); @@ -287,7 +287,7 @@ tilfa_update_config(node_t *plr_node, } else if(link_protection != DONT_KNOW || node_protection != DONT_KNOW){ - tilfa_lcl_config = calloc(1, sizeof(tilfa_lcl_config_t)); + tilfa_lcl_config = XCALLOC(1, tilfa_lcl_config_t); strncpy(tilfa_lcl_config->protected_link, protected_link, IF_NAME_SIZE); tilfa_lcl_config->protected_link[IF_NAME_SIZE -1] = '\0'; if(link_protection == TRUE || link_protection == FALSE) @@ -303,7 +303,7 @@ tilfa_update_config(node_t *plr_node, tilfa_lcl_config->link_protection == FALSE){ remove_glthread(&tilfa_lcl_config->config_glue); - free(tilfa_lcl_config); + XFREE(tilfa_lcl_config); config_change = TRUE; } return config_change; @@ -384,11 +384,11 @@ tilfa_clear_post_convergence_spf_path( pred_info = glthread_to_pred_info(curr1); remove_glthread(&pred_info->glue); - free(pred_info); + XFREE(pred_info); } ITERATE_GLTHREAD_END(&spf_path_result->pred_db, curr1); remove_glthread(&spf_path_result->glue); - free(spf_path_result); + XFREE(spf_path_result); } ITERATE_GLTHREAD_END(post_convergence_spf_path_head, curr); init_glthread(post_convergence_spf_path_head); @@ -438,7 +438,7 @@ tilfa_clear_all_pre_convergence_results(node_t *node, LEVEL level){ ITERATE_LIST_BEGIN(tilfa_info->tilfa_pre_convergence_spf_results[level], list_node){ result = list_node->data; - free(result); + XFREE(result); result = NULL; }ITERATE_LIST_END; @@ -466,7 +466,7 @@ tilfa_clear_all_post_convergence_results(node_t *spf_root, LEVEL level, ITERATE_LIST_BEGIN(tilfa_info->tilfa_post_convergence_spf_results[level], list_node){ result = list_node->data; - free(result); + XFREE(result); result = NULL; }ITERATE_LIST_END; @@ -547,7 +547,7 @@ tilfa_fill_protected_resource_from_config(node_t *plr_node, tilfa_lcl_config_t *tilfa_lcl_config){ protected_resource_t *temp_pr_res = - calloc(1, sizeof(protected_resource_t)); + XCALLOC(1, protected_resource_t); temp_pr_res->plr_node = plr_node; temp_pr_res->protected_link = get_interface_from_intf_name(plr_node, @@ -555,7 +555,7 @@ tilfa_fill_protected_resource_from_config(node_t *plr_node, if(!temp_pr_res->protected_link){ temp_pr_res->plr_node = NULL; - free(temp_pr_res); + XFREE(temp_pr_res); return; } @@ -639,15 +639,15 @@ tilfa_clear_preconvergence_remote_spf_results(tilfa_info_t *tilfa_info, ITERATE_LIST_BEGIN2(inner_lst, curr1, prev1){ spf_res = curr1->data; - free(spf_res); + XFREE(spf_res); curr1->data = NULL; } ITERATE_LIST_END2(inner_lst, curr1, prev1); delete_singly_ll(inner_lst); - free(inner_lst); + XFREE(inner_lst); tilfa_rem_spf_result->rem_spf_result_lst = NULL; - free(tilfa_rem_spf_result); + XFREE(tilfa_rem_spf_result); ITERATIVE_LIST_NODE_DELETE2(outer_lst, curr, prev); if(node) return; @@ -923,7 +923,7 @@ tilfa_p_node_qualification_test_wrt_root( uint32_t dist_S_to_pnode = tilfa_dist_from_self( tilfa_info, node_to_test, level); - /*loop free wrt Source*/ + /*loop XFREE wrt Source*/ if(!(dist_nbr_to_pnode < dist_nbr_to_S + dist_S_to_pnode)) return FALSE; @@ -998,7 +998,7 @@ tilfa_q_node_qualification_test_wrt_destination( node_t *protected_node = edge->to.node; /* Mandatory condition should be satisified : - * q node must be loop-free node wrt S*/ + * q node must be loop-XFREE node wrt S*/ dist_q_to_S = tilfa_dist_from_x_to_y_reverse_spf(tilfa_info, spf_root, node_to_test, level); @@ -1172,7 +1172,7 @@ tilfa_attempt_connect_p_q_by_prefix_sid(node_t *spf_root, uint32_t dist_S_to_qnode = tilfa_dist_from_self( tilfa_info, q_node, level); - /*loop free wrt Source*/ + /*loop XFREE wrt Source*/ if(!(dist_pnode_to_qnode < dist_pnode_to_S + dist_S_to_qnode)) return FALSE; @@ -2534,7 +2534,7 @@ route_fetch_tilfa_backups(node_t *spf_root, &tilfa_segment_list->gen_segment_list[i], tilfa_segment_list->pr_res, inet3, mpls0)){ - tilfa_bck_up = calloc(1, sizeof(internal_nh_t)); + tilfa_bck_up = XCALLOC(1, internal_nh_t); copy_internal_nh_t(tilfa_bck_up_lcl, (*tilfa_bck_up)); ROUTE_ADD_NH(route->backup_nh_list[LSPNH], tilfa_bck_up); } diff --git a/tilfa.h b/tilfa.h index 016f89a..4d7e007 100644 --- a/tilfa.h +++ b/tilfa.h @@ -36,6 +36,7 @@ #include "data_plane.h" #include "complete_spf_path.h" #include "spring_adjsid.h" +#include "LinuxMemoryManager/uapi_mm.h" typedef struct edge_end_ interface_t; @@ -197,7 +198,7 @@ static inline void tilfa_unlock_protected_resource( pr_res->ref_count--; assert(pr_res->ref_count >= 0); if(!pr_res->ref_count) - free(pr_res); + XFREE(pr_res); } static inline void tilfa_lock_protected_resource( diff --git a/topo.c b/topo.c index 5f39a39..07a51c9 100644 --- a/topo.c +++ b/topo.c @@ -35,6 +35,7 @@ #include "libcli.h" #include "spfcmdcodes.h" #include "spfclihandler.h" +#include "LinuxMemoryManager/uapi_mm.h" extern instance_t *instance; @@ -1884,7 +1885,7 @@ config_dynamic_topology(param_t *param, } if(!prefix){ - prefix = calloc(1, sizeof(prefix_t)); + prefix = XCALLOC(1, prefix_t); BIND_PREFIX(edge->from.prefix[LEVEL1], prefix); } else{ @@ -1909,7 +1910,7 @@ config_dynamic_topology(param_t *param, prefix = edge_end->prefix[LEVEL1]; if(!prefix){ - prefix = calloc(1, sizeof(prefix_t)); + prefix = XCALLOC(1, prefix_t); BIND_PREFIX(edge_end->prefix[LEVEL1], prefix); } else{