zoukankan
html css js c++ java
MemMan 3 beta
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEM_MAN__
#define
__MEM_MAN__
#include
<
vector
>
#include
<
algorithm
>
#include
<
malloc.h
>
#pragma pack(push,
1
)
namespace
mem
{
#define
mem_inline __forceinline
#define
mem_page_size ( 1 << 18 )
#define
mem_align_size 16
#define
mem_align __declspec( align( mem_align_size ) )
typedef unsigned
int
prior_type;
typedef unsigned
long
time_type;
typedef unsigned
long
size_type;
typedef unsigned
char
byte
;
#define
mem_max( a, b ) ( ( (a) > (b) ) ? (a) : (b) )
#define
mem_min( a, b ) ( ( (a) < (b) ) ? (a) : (b) )
enum
{
ENTRY_PRIORITY
=
0
,
}
;
class
heap
{
public
:
mem_inline heap( size_type max_size )
{
allocated_size
=
0
;
available_size
=
max_size;
}
mem_inline
~
heap()
{
}
mem_inline
void
*
alloc( size_type size )
{
if
( size
==
0
)
return
NULL;
allocated_size
+=
size;
available_size
-=
size;
return
sys_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
if
( ptr
&&
size
!=
0
)
{
sys_dealloc( ptr );
allocated_size
-=
size;
available_size
+=
size;
}
}
mem_inline
void
*
aligned_alloc( size_type size )
{
if
( size
==
0
)
return
NULL;
allocated_size
+=
size;
available_size
-=
size;
return
sys_aligned_alloc( size );
}
mem_inline
void
aligned_dealloc(
void
*
ptr, size_type size )
{
if
( ptr
&&
size
!=
0
)
{
sys_aligned_dealloc( ptr );
allocated_size
-=
size;
available_size
+=
size;
}
}
mem_inline size_type available()
{
return
available_size;
}
private
:
mem_inline
void
*
sys_alloc( size_type size )
{
return
malloc( size );
}
mem_inline
void
sys_dealloc(
void
*
ptr )
{
free( ptr );
}
mem_inline
void
*
sys_aligned_alloc( size_type size )
{
return
_aligned_malloc( size, mem_align_size );
}
mem_inline
void
sys_aligned_dealloc(
void
*
ptr )
{
_aligned_free( ptr );
}
private
:
size_type allocated_size,
available_size;
}
;
extern
heap
*
g_heap;
class
allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
g_heap
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
g_heap
->
dealloc( ptr, size );
}
mem_inline size_type available()
{
return
g_heap
->
available();
}
}
;
class
aligned_allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
g_heap
->
aligned_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
g_heap
->
aligned_dealloc( ptr, size );
}
mem_inline size_type available()
{
return
g_heap
->
available();
}
}
;
template
<
typename ALLOC
=
allocator
>
class
pool;
template
<
typename ALLOC
=
allocator
>
class
entry
{
public
:
mem_inline entry()
{
priority
=
ENTRY_PRIORITY;
last_use_time
=
pl.get_current_time();
locked
=
false
;
}
mem_inline
virtual
~
entry()
{
}
mem_inline
void
*
alloc( size_type size )
{
return
pl.alloc( size,
this
);
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
pl.dealloc( ptr, size,
this
);
}
mem_inline
void
stream_begin()
{
locked
=
true
;
stream_in();
last_use_time
=
pl.get_current_time();
}
mem_inline
void
stream_end()
{
locked
=
false
;
}
mem_inline
bool
is_locked()
{
return
locked;
}
mem_inline
bool
operator
<
(
const
entry
<
ALLOC
>
&
right )
const
{
if
( priority
==
right.priority )
return
( last_use_time
<
right.last_use_time );
else
return
( priority
<
right.priority );
}
public
:
#ifdef _DEBUG
virtual
void
stream_in()
=
0
;
#endif
virtual
bool
stream_out(
void
*
&
ptr, size_type size )
=
0
;
public
:
static
pool
<
ALLOC
>
pl;
prior_type priority;
time_type last_use_time;
bool
locked;
}
;
template
<
typename ALLOC
>
mem_inline
bool
compare_entry(
const
entry
<
ALLOC
>
*
left,
const
entry
<
ALLOC
>
*
right )
{
return
(
*
left
<
*
right );
}
template
<
typename ALLOC
>
class
pool
{
private
:
class
page
{
public
:
mem_inline page( size_type _size, page
*
old )
{
size
=
_size;
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline
~
page()
{
}
mem_inline
void
recycle( page
*
old )
{
void
*
ptr
=
NULL;
for
( std::vector
<
entry
<
ALLOC
>
*
>
::iterator i
=
ents.begin();
i
!=
ents.end();
++
i )
{
(
*
i)
->
stream_out( ptr,
0
);
}
ents.clear();
size
=
get_size();
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline
byte
*
get_base()
{
return
(
byte
*
)
this
+
sizeof
(page);
}
mem_inline size_type get_size()
{
return
static_cast
<
size_type
>
(
base
-
get_base()
+
size );
}
mem_inline size_type available()
{
return
size;
}
mem_inline
void
*
alloc( size_type req_size, entry
<
ALLOC
>
*
obj )
{
void
*
ptr
=
(
void
*
)
base
;
base
+=
req_size;
size
-=
req_size;
ents.push_back( obj );
return
ptr;
}
mem_inline time_type priority()
const
{
time_type last_use_time
=
0
;
for
( std::vector
<
entry
<
ALLOC
>
*
>
::const_iterator i
=
ents.begin();
i
!=
ents.end();
++
i )
{
last_use_time
+=
(
*
i)
->
last_use_time;
}
last_use_time
/=
static_cast
<
time_type
>
( ents.size() );
return
last_use_time;
}
mem_inline
bool
operator
<
(
const
page
&
right )
const
{
return
( priority()
<
right.priority() );
}
public
:
mem_align
struct
{
byte
*
base
;
page
*
next;
page
*
prev;
size_type size;
std::vector
<
entry
<
ALLOC
>
*
>
ents;
}
;
}
;
class
chunk
{
public
:
mem_inline chunk( size_type _size, chunk
*
old )
{
size
=
_size;
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
}
mem_inline size_type available()
{
return
size;
}
public
:
chunk
*
next;
chunk
*
prev;
size_type size;
}
;
public
:
mem_inline pool()
{
current_time
=
0
;
pages
=
NULL;
chunks
=
NULL;
allocated
=
0
;
}
mem_inline
~
pool()
{
destory();
}
mem_inline time_type get_current_time()
{
return
(
++
current_time );
}
mem_inline
void
*
alloc( size_type size, entry
<
ALLOC
>
*
obj )
{
void
*
ptr
=
NULL;
++
allocated;
if
( search_chunk( ptr, size ) )
return
ptr;
else
if
( search_page( ptr, size, obj ) )
return
ptr;
else
if
( (size
+
sizeof
(page))
>
al.available() )
{
if
( search_entry( ptr, size, obj ) )
return
ptr;
else
{
recycle_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
return
NULL;
}
}
else
{
allocate_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
return
NULL;
}
}
mem_inline
void
dealloc(
void
*
ptr, size_type size, entry
<
ALLOC
>
*
obj )
{
--
allocated;
for
( std::vector
<
entry
<
ALLOC
>
*
>
::iterator i
=
g_ents.begin();
i
!=
g_ents.end();
++
i )
{
if
( obj
==
*
i )
{
g_ents.erase( i );
break
;
}
}
if
( size
>=
sizeof
(chunk) )
chunks
=
new
(ptr) chunk( size, chunks );
if
( allocated
==
0
)
destory();
}
private
:
mem_inline
void
destory()
{
page
*
p
=
pages;
while
( p )
{
pages
=
p
->
next;
p
->~
page();
al.dealloc( p, p
->
get_size() );
p
=
pages;
}
chunks
=
NULL;
g_ents.clear();
}
mem_inline
bool
search_chunk(
void
*
&
ptr, size_type size )
{
chunk
*
p
=
chunks;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
(
void
*
) p;
if
( p
->
prev )
p
->
prev
->
next
=
p
->
next;
if
( p
->
next )
p
->
next
->
prev
=
p
->
prev;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline
bool
search_page(
void
*
&
ptr, size_type size, entry
<
ALLOC
>
*
obj )
{
page
*
p
=
pages;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
p
->
alloc( size, obj );
g_ents.push_back( obj );
if
( p
->
prev )
p
->
prev
->
next
=
p
->
next;
if
( p
->
next )
p
->
next
->
prev
=
p
->
prev;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline
bool
search_entry(
void
*
&
ptr, size_type size, entry
<
ALLOC
>
*
obj )
{
std::sort( g_ents.begin(), g_ents.end(), compare_entry
<
ALLOC
>
);
for
( std::vector
<
entry
<
ALLOC
>
*
>
::iterator i
=
g_ents.begin();
i
!=
g_ents.end();
++
i )
{
if
(
!
(
*
i)
->
is_locked()
&&
(
*
i)
->
stream_out( ptr, size ) )
{
*
i
=
obj;
return
true
;
}
}
return
false
;
}
mem_inline
void
recycle_page( size_type size )
{
if
( pages )
{
page
*
p,
*
old;
old
=
pages;
p
=
pages
->
next;
while
( p )
{
if
(
*
p
<
*
old )
old
=
p;
p
=
p
->
next;
}
if
( old
->
prev )
old
->
prev
->
next
=
old
->
next;
if
( old
->
next )
old
->
next
->
prev
=
old
->
prev;
old
->
recycle( pages );
pages
=
old;
}
}
mem_inline
void
allocate_page( size_type size )
{
size_type asize
=
mem_min( mem_max(
sizeof
(page)
+
size, mem_page_size ), al.available() );
pages
=
new
(al.alloc( asize )) page( asize
-
sizeof
(page), pages );
}
private
:
time_type current_time;
time_type allocated;
ALLOC al;
std::vector
<
entry
<
ALLOC
>
*
>
g_ents;
page
*
pages;
chunk
*
chunks;
}
;
}
//
namespace mem
#pragma pack(pop)
#endif
//
__MEM_MAN__
查看全文
相关阅读:
Atitit.ati orm的设计and架构总结 适用于java c# php版
Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
Atitit.ati dwr的原理and设计 attilax 总结 java php 版本
Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
Atitit. 软件设计 模式 变量 方法 命名最佳实践 vp820 attilax总结命名表大全
Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
Atitit 插件机制原理与设计微内核 c# java 的实现attilax总结
atitit.基于 Commons CLI 的命令行原理与 开发
atitit.基于 Commons CLI 的命令行原理与 开发
atitit.js 与c# java交互html5化的原理与总结.doc
原文地址:https://www.cnblogs.com/len3d/p/988562.html
最新文章
关于启动调试时,总是启动多个web端口的问题
DBCC--CHECKIDENT
DBCC--EXTENTINFO/IND/PAGE--显示数据页信息
DBCC--CHECKDB--使用快照还是表锁
DBCC--CHECKDB--结果收集
DBCC--CHECKDB--不可被替代的原因
DBCC--CHECKDB
DBCC--SHRINKDATABASE
数据库选项--数据库状态
数据库选项--访问控制
热门文章
数据库选项--强制参数化
修改配置nginx,限制无良爬虫频率
uikit
php处理行业分类数据
2013年优秀jQuery插件
如何使用Xcode进行高保真原型设计?
linux安装php sphinx出错
atitit.软件设计模式大的总结attialx总结
atitit.软件设计模式大的总结attialx总结
Atitit.ati orm的设计and架构总结 适用于java c# php版
Copyright © 2011-2022 走看看