Sunday, August 10, 2014

simple memory pool implementation


MEMORY POOL and Implementation in C language:

i have been searching the answer for this question long time and finally got the answer. Thanks to amskhar

Answer 1:

Memory pools

Allocation of a new memory is an expensive operation and large programs can contain thousands of calls of malloc() for a single computation, where every call allocates only a very small amount of the memory. This can result in an undesirable slowdown of the application. We can avoid this slowdown by decreasing the number of malloc() calls by using a memory pool.
A memory pool is a preallocated memory space with a fixed size. If we need to allocate new data we will take the desired amount of the memory from the pool instead of requesting a new memory from the system. This is done by creating a pointer that points inside the preallocated memory. Such a pool must not be reallocated as it would change its location - pointers that were pointing inside the pool would become invalid. Therefore, a memory pool requires a very good estimate of the required memory space.

Reference: https://talloc.samba.org/talloc/doc/html/libtalloc__pools.html

Answer 2:

In the code often developers allocate the memory using dynamic allocation macros such as MALLOC in case of C and NEW in case of C++. 
Suppose, you have packet receptor system which receives the packets from other device. And this receptor system responsibility to add a extra header to the received packet and sends the modified packet out to the end device. 
What happens when code allocates/dellocates memory using malloc/free for every packet. 
Do you think there is a performance degradation? Yes, obviously there is performance degradation. 
Then what is the solution? Solution is Memory pools.
   A more efficient solution is preallocating a number of memory blocks with the same size called the memory pool. The application can allocate, access, and free blocks represented by handles at run time.
What is Memory Pool?
   Memory pool is pre-allocation of fixed size of memory or it also defined as fixed size of memory allocated using MALLOC or New during initialization of the system.
Why it is required?
   To avoid the performance degradation in real time systems.
How it is implemented?
Step 1 :  Create a memory Pool. 
Application needs to initialize a pool. Application allocates the memory required during initialization time using MALLOC/NEW.
Step 2:    Get memory from Pool
Whenever a memory is required and the same memory would be fetched from the Pool.              
Step3:   Add memory to Pool
Once the Memory is no more used then add the same memory to Pool.
Step4:  Destroy/Deallocate memory Pool
And finally, before application quits, it should de-allocate the pool, to make sure that all memory blocks allocated by the factory are released back to the operating system. After this, of course no more memory pool allocation can be requested.




Simple Program for Memory Pool:


#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_MEMORY_POOL_NODES 10

/* Node */
typedef struct node
{
    int    data;
    int    nodeAllocated;
}NODE;

typedef struct Memorypool
{
    NODE       *array[MAX_MEMORY_POOL_NODES];
    int        nodeCounter;
}MEMORYPOOL;

MEMORYPOOL allocNode;

/*
 * initialiseMemoryPool()
 */
void initialiseMemoryPool()
{
   unsigned char uIndx;
   
   /* Initialise the Memory for the Nodes */      
   for(uIndx = 0; uIndx<MAX_MEMORY_POOL_NODES; uIndx++)
   {
      allocNode.array[uIndx]= (NODE *)malloc(sizeof(NODE));
      allocNode.array[uIndx]->nodeAllocated = 0;

      allocNode.nodeCounter++;
   }
}

NODE *getTheFreeNodeFromPool()
{
  int uIndx;
  
   /* Get the Memory from the Pool of Nodes */
   for(uIndx = 0; uIndx<MAX_MEMORY_POOL_NODES; uIndx++)
   {
      if(allocNode.array[uIndx]->nodeAllocated == 0) 
      {
          allocNode.array[uIndx]->nodeAllocated = 1;
          allocNode.nodeCounter--; 
          break;
      }
   }  

  if(uIndx == MAX_MEMORY_POOL_NODES) 
  {
     printf(" No Free Nodes are available \n");
     return NULL;
  }
  return allocNode.array[uIndx];
}

/* 
 *  Add the Node to Memory pool
 */
void addTheNodeToMemoryPool(unsigned char uIndx)
{
   /* Add the Node to Pool */
   if(allocNode.array[uIndx]->nodeAllocated == 1 )
   {
         allocNode.array[uIndx]->data = 0;
         allocNode.array[uIndx]->nodeAllocated = 0; 
         allocNode.nodeCounter++;
    }
   else
   {
      printf("No Nodes are there Add \n");
      return;
   }
}

/*
 * deallocateTheMemoryPool-  Deallocate the Memory Pool
 */
void deallocateTheMemoryPool(void)
{
  unsigned char uIndx;

  /* De-allocate the Memory Pool */
  for(uIndx = 0; uIndx<MAX_MEMORY_POOL_NODES; uIndx++)
    {
        free(allocNode.array[uIndx]);
    }
}
              
/* Main */
int main()
{
    unsigned char uIndx, index;
   
   // Step 1:
   /* Initialise the Memory Pool */
   initialiseMemoryPool();

   // Step 2:
   /* Get the Node from the Memory Pool */
   for(uIndx=0 ; uIndx< MAX_MEMORY_POOL_NODES; uIndx++)
   { 
      NODE *node= NULL; 
      int data;
      
      node = getTheFreeNodeFromPool();

      if(node)
      {
          printf("Enter the Data to be added in the Linklist \n");
          scanf("%d", &data);
    
          node->data = data;
      }
   }
  
   /* Display the Data */
   printf(" Display Data \n");
   for (uIndx=0 ; uIndx<MAX_MEMORY_POOL_NODES; uIndx++)
    {
      printf("%d\n", allocNode.array[uIndx]->data);
    }

   
   //Step 3:
   /* Add the Node to Memory Pool */   
   printf(" Enter the Node to be added to memory pool \n");
   scanf("%d", &index);
   
   addTheNodeToMemoryPool(index);

   /* Display the Data */
   printf(" Display Data after adding Node to Free Pool \n");
   for (uIndx=0 ; uIndx<MAX_MEMORY_POOL_NODES; uIndx++)
    {
      printf("%d\n", allocNode.array[uIndx]->data);
    }

   //Step 4:
   /* De Allocate the Memory Pool */
   deallocateTheMemoryPool();
   return 0;
}



Reference:

http://amsekharkernel.blogspot.in/2013/05/simple-memory-pool-implementation-for.html
www.embeddedlinux.org.cn/RTConforEmbSys/5107final/LiB0082.html

No comments:

Post a Comment