Write your own memory allocation program for the C + + standard library container

Source: Internet
Author: User
Tags bool exit int size

According to the SGI STL two-level allocation algorithm rewrite the memory pool allocation program, as long as a slight modification can be implemented shared memory mode of management, using the C + + standard storage device in the Map,set,multimap,multiset test pass, vector test pass, The reason is that in memory recycling time to consider the relatively simple, vector each allocation of memory number is not fixed, recycling is not fixed, so the program needs to continue to improve.

The source of the memory pool management program is as follows:

#ifndef My_allocator_h_
#define My_allocator_h_
#include "stdafx.h"
#include <limits>
#include <iostream>
Namespace Happyever
{
enum {nodenums = 2};
Union _obj
{
Union _obj* M_free_list_link;
Char m_client_data[1];
} ;
typedef union _OBJ OBJ;
struct _cookie
{
int Ishmkey; /* Shared Memory key value * *
int ishmid; /* Ishmkey corresponding Shmid * *
int Isemkey; /* Lock Signal key value * *
int isemid; /* Lock Signal identification * *
int itotalsize; * * Total container capacity * *
void* Pstartall; /* Shared Memory own address * *
char* Pstartfree; /* Start address of free space * *
char* Pendfree; /* Free space of the end address * *
int iusenum[nodenums];
/* The size*/for storing nodes in Free_list
Short Sfreelistindex[nodenums];
/* The linked list for allocating memory nodes/*
obj* Ufreelist[nodenums];
};
typedef struct _COOKIE Cookies;
OBJ;
Cookies;
static Cookie *phead = NULL;
Template <class t>
Class Myalloc
{
Private
static const int ALIGN = sizeof (OBJ);
int round_up (int bytes);
int freelist_index (int bytes);
int freelist_getindex (int bytes);
char* chunk_alloc (int size, int *nobjs);
void* refill (int num,int n);
Public
Type definitions
typedef T VALUE_TYPE;
typedef t* Pointer;
typedef const T* Const_pointer;
typedef t& Reference;
typedef const t& Const_reference;
typedef std::size_t SIZE_TYPE;
typedef std::p trdiff_t difference_type;
Template <class u>
struct rebind
{
typedef myalloc<u> Other;
};
Pointer address (reference value) const
{
Return &value;
}
Const_pointer address (const_reference value) const
{
Return &value;
}
Myalloc () throw ()
{
std::cout<< "Myalloc" <<std::endl;
}
Myalloc (const myalloc& x) throw ()
{
std::cout<< "Const Myalloc" <<std::endl;
}
Template <class u>
Myalloc (const myalloc<u>& x) throw ()
{
std::cout<< "Const myalloc<u>" <<std::endl;
}
~myalloc () throw ()
{
std::cout<< "~myalloc" <<std::endl;
}
Size_type max_size () const throw ()
{
return Std::numeric_limits<std::size_t>::max ()/sizeof (t);
}
void Printfreelistandcookie ();
Pointer allocate (size_type num, const void* = 0)
{
pointer ret = 0;
obj** my_free_list;
obj* result;
int index;
Print and allocate memory with global new
Std::cerr << "allocate" << num << "element (s)"
<< "of size" << sizeof (T) << Std::endl;
index = freelist_index (sizeof (T));
if (index >= nodenums)
{
return NULL;
}
My_free_list = phead->ufreelist + index;
Lock (Semid,lock_num);
result = *my_free_list;
if (result = = 0)
{
ret = (pointer) refill (int) num, round_up (sizeof (T)));
}
Else
{
*my_free_list = result->m_free_list_link;
ret = (pointer) result;
}
UnLock (Semid,lock_num);
Phead->iusenum[index] = Phead->iusenum[index] + (int) num;
if (0 = ret)
{
Std::cerr << "Alloc memory fail!" << Std::endl;
Exit (1);
}
Std::cerr << "allocated at:" << (void*) ret << Std::endl;
Printfreelistandcookie ();
return ret;
}
void construct (pointer p, const t& value)
{
Initialize memory with placement new
New ((void*) p) T (value);
}
void Destroy (pointer p)
{
Destroy objects by calling their destructor
P->~t ();
}
void deallocate (pointer p, size_type num)
{
obj** my_free_list;
obj* Q;
int index;
index = freelist_getindex (sizeof (T));
if (index >= nodenums)
{
Std::cerr << "deallocate memory fail!" << Std::endl;
Exit (1);
}
My_free_list = phead->ufreelist + index;
Q = (obj*) p;
Lock (Semid,lock_num);
* * This place may have a problem.
for (int i=0;i< (int) num; i++)
{
Q->m_free_list_link = *my_free_list;
*my_free_list = q;
}
UnLock (Semid,lock_num);
Phead->iusenum[index] = Phead->iusenum[index]-(int) num;
Std::cerr << "deallocate" << num << "element (s)"
<< "of size" << sizeof (T)
<< "at:" << (void*) p << Std::endl;
Printfreelistandcookie ();
}
};
Template <class t>
int myalloc<t>::round_up (int bytes)
{
int i;
i = bytes;
if (bytes < ALIGN)
{
i = ALIGN;
}
std::cout<< "round_up:bytes=" <<bytes<< ", return=" <<i<<std::endl;
return i;
};
Template <class t>
int myalloc<t>::freelist_index (int bytes)
{
int i;
for (i=0; i< nodenums; i++)
{
if (phead->sfreelistindex[i] = = bytes)
Break
}
if (i >= nodenums)
{
for (i=0; i< nodenums; i++)
{
if (phead->sfreelistindex[i] = = 0)
{
Phead->sfreelistindex[i] = bytes;
std::cout<< "freelist_index:bytes=" <<bytes<< ", return=" <<i<<std::endl;
return i;
}
}
}
std::cout<< "freelist_index:bytes=" <<bytes<< ", return=" <<i<<std::endl;
return i;
};
Template <class t>
int myalloc<t>::freelist_getindex (int bytes)
{
int i;
for (i=0; i< nodenums; i++)
{
if (phead->sfreelistindex[i] = = bytes)
Break
}
std::cout<< "freelist_getindex:bytes=" <<bytes<< ", return=" <<i<<std::endl;
return i;
};
Template <class t>
char* myalloc<t>::chunk_alloc (int size, int *nobjs)
{
char* result;
int counts = *NOBJS;
int total_bytes = size * counts;
int bytes_left = int (phead->pendfree-phead->pstartfree);
std::cout<< "chunk_alloc:total_bytes =" <<total_bytes
<< ", Bytes_left =" <<bytes_left<<std::endl;
if (Bytes_left >= total_bytes)
{
result = phead->pstartfree;
Phead->pstartfree + = Total_bytes;
std::cout<< "chunk_alloc:total_bytes =" <<total_bytes
<< ", result =" <<*result<< ", Start_free =" <<& (phead->pstartfree) <<std::endl;
}
else if (bytes_left >= size)
{
counts = bytes_left/size;
total_bytes = size * counts;
result = phead->pstartfree;
Phead->pstartfree + = Total_bytes;
*nobjs = counts;
std::cout<< "chunk_alloc:total_bytes =" <<total_bytes<< ", Nobjs =" <<nobjs
<< ", result =" <<*result<< ", Start_free =" <<& (phead->pstartfree) <<std::endl;
}
Else
{
/* Also need to process the recovery of other free freelist inside the space * *
result = NULL;
}
return (result);
};
Template <class t>
void* myalloc<t>::refill (int num,int N)
{
int counts = num;
int *NOBJS = &counts;
char* Chunk;
obj** my_free_list;
obj* result;
obj* Current_obj;
obj* Next_obj;
int i;
Chunk = Chunk_alloc (n, NOBJS);
if (chunk = NULL)
{
return (chunk);
}
counts = *NOBJS;
if (1 = counts)
{
return (chunk);
}
My_free_list = phead->ufreelist + freelist_index (n);
result = (obj*) chunk;
*my_free_list = Next_obj = (obj*) (chunk + n*num);
for (i = 1;; i++)
{
Current_obj = Next_obj;
Next_obj = (obj*) ((char*) Next_obj + N);
if (counts-1 = i)
{
Current_obj->m_free_list_link = 0;
Break
}
Else
{
Current_obj->m_free_list_link = Next_obj;
}
}
return (result);
};
/* This function can be changed to write its own shared memory allocation function * *
static void Initshm ()
{
int i,size=1000;
Phead = (cookie*) malloc (sizeof (Cookie) +size);
phead->itotalsize = sizeof (Cookie) +size;
Phead->pstartall = Phead;
Phead->pstartfree = (char*) phead + sizeof (Cookie);
Phead->pendfree = (char*) Phead + phead->itotalsize;
For (i=0 i <nodenums; i++)
{
phead->sfreelistindex[i]=0;
phead->ufreelist[i]=0;
phead->iusenum[i]=0;
}
}
static void Printfreelistandcookie ()
{
int i,j;
obj* my_free_list;
std::cout<< "Cookie info:" <<std::endl;
std::cout<< "sizeof (struct cookie) =" <<sizeof (cookie) <<std::endl;
std::cout<< "TotalSize =" <<pHead->iTotalsize<<std::endl;
std::cout<< "usedsize =" <<int (phead->pstartfree-(char*) phead) <<std::endl;
std::cout<< "freepoolsize =" <<int (phead->pendfree-phead->pstartfree) <<std::endl;
std::cout<< "Startall =" <<& (phead->pstartall) <<std::endl;
std::cout<< "Startfree =" <<& (phead->pstartfree) <<std::endl;
std::cout<< "Endfree =" <<& (phead->pendfree) <<std::endl;
std::cout<< "Nfreelist info:" <<std::endl;
for (i=0; i<nodenums; i++)
{
j=0;
std::cout<< "iusenum[" <<i<< "] =" <<pHead->iUseNum[i]<<std::endl;
std::cout<< "freelistindex[" <<i<< "] =" <<pHead->sFreelistIndex[i]<<std::endl;
My_free_list = phead->ufreelist[i];
if (my_free_list->m_client_data!= 0)
{
while (my_free_list->m_client_data!= 0)
{
j + +;
My_free_list = my_free_list->m_free_list_link;
}
std::cout<< "free_list[" <<i<< "]; Node counts= "<<j<<std::endl;
}
}
}
Template <class T1, class t2>
BOOL operator== (const myalloc<t1>&,const myalloc<t2>&) throw ()
{
return true;
}
Template <class T1, class t2>
BOOL Operator!= (const myalloc<t1>&,const myalloc<t2>&) throw ()
{
return false;
}
}
#endif/*my_allocator_h_*/

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.