zoukankan
html css js c++ java
MemMan 3 beta 4
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEMMAN__
#define
__MEMMAN__
#include
<
malloc.h
>
#include
<
vector
>
#include
<
algorithm
>
#include
<
iostream
>
#pragma pack(push,
1
)
namespace
mem
{
#define
mem_inline __forceinline
#define
mem_pool_pad 16
#define
mem_page_pad 48
#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
,
}
;
extern
time_type num_stream_out;
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()
const
{
return
available_size;
}
mem_inline
void
print()
{
std::cout
<<
std::endl;
std::cout
<<
"
========== heap Statistics ==========
"
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
"
=====================================
"
<<
std::endl;
std::cout
<<
std::endl;
}
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;
}
;
template
<
typename ALLOC
>
class
pool
{
private
:
class
page
{
public
:
mem_inline page( size_type _size, page
*
old )
{
base
=
get_base();
_next
=
old;
size
=
_size;
}
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()
const
{
return
size;
}
mem_inline
void
*
alloc( size_type _size )
{
byte
*
ptr
=
base
;
base
+=
_size;
size
-=
_size;
return
ptr;
}
mem_inline page
*
next()
{
return
_next;
}
private
:
mem_align union
{
struct
{
byte
*
base
;
page
*
_next;
size_type size;
}
;
byte
pad[mem_pool_pad];
}
;
}
;
class
chunk
{
public
:
mem_inline chunk( size_type _size, chunk
*
old )
{
next
=
old;
size
=
_size;
}
mem_inline size_type available()
const
{
return
size;
}
public
:
chunk
*
next;
size_type size;
}
;
public
:
mem_inline pool()
{
pages
=
NULL;
chunks
=
NULL;
allocated
=
0
;
}
mem_inline
~
pool()
{
destory();
}
mem_inline
void
destory()
{
page
*
p;
while
( ( p
=
pages )
!=
NULL )
{
pages
=
p
->
next();
al.dealloc( p, p
->
get_size() );
}
pages
=
NULL;
chunks
=
NULL;
}
mem_inline
bool
search_chunk(
void
*
&
ptr, size_type size )
{
if
( chunks
&&
( size
<=
chunks
->
available() ) )
{
ptr
=
(
void
*
) chunks;
chunks
=
chunks
->
next;
return
true
;
}
else
return
false
;
}
mem_inline
bool
search_page(
void
*
&
ptr, size_type size )
{
if
( pages
&&
( size
<=
pages
->
available() ) )
{
ptr
=
pages
->
alloc( size );
return
true
;
}
else
return
false
;
}
mem_inline
void
allocate_page( size_type size )
{
size_type asize
=
mem_max( size, mem_page_size );
pages
=
new
(al.alloc(
sizeof
(page)
+
asize )) page( asize, pages );
}
mem_inline
void
*
alloc( size_type size )
{
void
*
ptr;
++
allocated;
if
( search_chunk( ptr, size ) )
return
ptr;
else
if
( search_page( ptr, size ) )
return
ptr;
else
{
allocate_page( size );
if
( search_page( ptr, size ) )
return
ptr;
else
return
NULL;
}
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
--
allocated;
if
( size
>=
sizeof
(chunk) )
chunks
=
new
(ptr) chunk( size, chunks );
if
( allocated
==
0
)
destory();
}
mem_inline
void
print()
{
std::cout
<<
std::endl;
std::cout
<<
"
========== pool Statistics ==========
"
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
"
=====================================
"
<<
std::endl;
std::cout
<<
std::endl;
}
private
:
page
*
pages;
chunk
*
chunks;
size_type allocated;
ALLOC al;
}
;
template
<
typename ALLOC
>
class
cache
{
public
:
class
node;
class
entry
{
public
:
mem_inline entry()
{
priority
=
ENTRY_PRIORITY;
last_use_time
=
pl.get_current_time();
locked
=
false
;
node_ptr
=
NULL;
}
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
&
right )
const
{
if
( priority
==
right.priority )
return
( last_use_time
<
right.last_use_time );
else
return
( priority
<
right.priority );
}
public
:
virtual
void
stream_in()
=
0
;
virtual
size_type stream_size()
=
0
;
virtual
void
*
stream_out()
=
0
;
public
:
static
cache
<
ALLOC
>
pl;
prior_type priority;
time_type last_use_time;
bool
locked;
node
*
node_ptr;
}
;
class
node
{
public
:
mem_inline node( entry
*
obj, node
*
old, node
*
g_old, node
*
phead, node
*
g_phead )
{
ptr
=
obj;
obj
->
node_ptr
=
this
;
next
=
old;
prev
=
phead;
g_next
=
g_old;
g_prev
=
g_phead;
if
( next )
next
->
prev
=
this
;
if
( prev )
prev
->
next
=
this
;
if
( g_next )
g_next
->
g_prev
=
this
;
if
( g_prev )
g_prev
->
g_next
=
this
;
}
mem_inline node()
{
ptr
=
NULL;
next
=
NULL;
prev
=
NULL;
g_next
=
NULL;
g_prev
=
NULL;
}
mem_inline
~
node()
{
void
*
p
=
NULL;
stream_out( p );
}
mem_inline time_type get_last_use_time()
const
{
if
( ptr )
return
ptr
->
last_use_time;
else
return
0
;
}
mem_inline
bool
is_locked()
const
{
if
( ptr )
return
ptr
->
is_locked();
else
return
false
;
}
mem_inline size_type stream_size()
{
if
( ptr )
return
ptr
->
stream_size();
else
return
0
;
}
mem_inline
bool
stream_out(
void
*
&
p )
{
if
( ptr )
{
p
=
ptr
->
stream_out();
ptr
->
node_ptr
=
NULL;
++
num_stream_out;
return
true
;
}
else
return
false
;
}
mem_inline
void
detach()
{
if
( prev )
prev
->
next
=
next;
if
( next )
next
->
prev
=
prev;
}
mem_inline
void
g_detach()
{
if
( g_prev )
g_prev
->
g_next
=
g_next;
if
( g_next )
g_next
->
g_prev
=
g_prev;
}
public
:
entry
*
ptr;
node
*
next,
*
prev;
node
*
g_next,
*
g_prev;
}
;
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
;
num_nodes
=
0
;
}
mem_inline
~
page()
{
node
*
p
=
head.next;
while
( p )
{
head.next
=
p
->
next;
p
->
g_detach();
p
->~
node();
node_pool.dealloc( p,
sizeof
(node) );
p
=
head.next;
}
}
mem_inline
void
recycle( page
*
old )
{
node
*
p
=
head.next;
while
( p )
{
head.next
=
p
->
next;
p
->
g_detach();
p
->~
node();
node_pool.dealloc( p,
sizeof
(node) );
p
=
head.next;
}
head.next
=
NULL;
size
=
get_size();
base
=
get_base();
next
=
old;
prev
=
NULL;
if
( next )
next
->
prev
=
this
;
num_nodes
=
0
;
}
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()
const
{
return
size;
}
mem_inline
void
*
alloc( size_type req_size )
{
void
*
ptr
=
(
void
*
)
base
;
base
+=
req_size;
size
-=
req_size;
return
ptr;
}
mem_inline time_type priority()
const
{
time_type last_use_time
=
0
;
node
*
p
=
head.next;
while
( p )
{
last_use_time
+=
p
->
get_last_use_time();
p
=
p
->
next;
}
if
( num_nodes
!=
0
)
last_use_time
/=
static_cast
<
time_type
>
( num_nodes );
return
last_use_time;
}
mem_inline
bool
operator
<
(
const
page
&
right )
const
{
return
( priority()
<
right.priority() );
}
public
:
mem_align union
{
struct
{
byte
*
base
;
page
*
next;
page
*
prev;
size_type size;
node head;
size_type num_nodes;
}
;
byte
pad[mem_page_pad];
}
;
}
;
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()
const
{
return
size;
}
public
:
chunk
*
next;
chunk
*
prev;
size_type size;
}
;
public
:
mem_inline cache()
{
current_time
=
0
;
pages
=
NULL;
chunks
=
NULL;
allocated
=
0
;
g_num_nodes
=
0
;
}
mem_inline
~
cache()
{
destory();
}
mem_inline time_type get_current_time()
{
return
(
++
current_time );
}
mem_inline
void
*
alloc( size_type size, entry
*
obj )
{
void
*
ptr
=
NULL;
++
allocated;
obj
->
node_ptr
=
NULL;
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
{
std::cout
<<
"
fatal: failed to allocate memory!
"
<<
std::endl;
return
NULL;
}
}
}
else
{
allocate_page( size );
if
( search_page( ptr, size, obj ) )
return
ptr;
else
{
std::cout
<<
"
fatal: failed to allocate memory!
"
<<
std::endl;
return
NULL;
}
}
}
mem_inline
void
dealloc(
void
*
ptr, size_type size, entry
*
obj )
{
--
allocated;
if
( obj
->
node_ptr )
{
obj
->
node_ptr
->
detach();
obj
->
node_ptr
->
g_detach();
obj
->
node_ptr
->~
node();
node_pool.dealloc( obj
->
node_ptr,
sizeof
(node) );
obj
->
node_ptr
=
NULL;
--
g_num_nodes;
}
if
( size
>=
sizeof
(chunk) )
chunks
=
new
(ptr) chunk( size, chunks );
if
( allocated
==
0
)
destory();
}
mem_inline
void
print()
{
std::cout
<<
std::endl;
std::cout
<<
"
========== cache Statistics ==========
"
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
"
======================================
"
<<
std::endl;
std::cout
<<
std::endl;
}
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_num_nodes
=
0
;
}
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
*
obj )
{
page
*
p
=
pages;
while
( p )
{
if
( size
<=
p
->
available() )
{
ptr
=
p
->
alloc( size );
new
(node_pool.alloc(
sizeof
(node) )) node( obj, p
->
head.next, g_head.g_next,
&
p
->
head,
&
g_head );
++
p
->
num_nodes;
++
g_num_nodes;
return
true
;
}
p
=
p
->
next;
}
return
false
;
}
mem_inline
bool
search_entry(
void
*
&
ptr, size_type size, entry
*
obj )
{
node
*
old
=
NULL;
node
*
p
=
g_head.g_next;
while
( p )
{
if
(
!
p
->
is_locked()
&&
p
->
stream_size()
>=
size )
{
if
( old )
{
if
(
*
p
->
ptr
<
*
old
->
ptr )
old
=
p;
}
else
old
=
p;
}
p
=
p
->
g_next;
}
if
( old
&&
old
->
stream_out( ptr ) )
{
old
->
ptr
=
obj;
obj
->
node_ptr
=
old;
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
!=
pages )
{
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;
node g_head;
size_type g_num_nodes;
page
*
pages;
chunk
*
chunks;
static
pool
<
ALLOC
>
node_pool;
}
;
class
man
{
public
:
mem_inline man()
{
m_heap
=
NULL;
upl
=
NULL;
apl
=
NULL;
num_stream_out
=
0
;
}
mem_inline
~
man()
{
if
( apl )
delete apl;
if
( upl )
delete upl;
if
( m_heap )
delete m_heap;
}
mem_inline
void
begin( size_type heap_size )
{
m_heap
=
new
heap( heap_size );
upl
=
new
pool
<
allocator
>
;
apl
=
new
pool
<
aligned_allocator
>
;
num_stream_out
=
0
;
}
mem_inline
void
end()
{
delete apl;
apl
=
NULL;
delete upl;
upl
=
NULL;
delete m_heap;
m_heap
=
NULL;
}
mem_inline
void
*
alloc( size_type size )
{
return
upl
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
return
upl
->
dealloc( ptr, size );
}
mem_inline
void
*
aligned_alloc( size_type size )
{
return
apl
->
alloc( size );
}
mem_inline
void
aligned_dealloc(
void
*
ptr, size_type size )
{
return
apl
->
dealloc( ptr, size );
}
mem_inline
void
print()
{
std::cout
<<
std::endl;
std::cout
<<
"
********** MemMan Statistics **********
"
<<
std::endl;
std::cout
<<
std::endl;
if
( m_heap )
m_heap
->
print();
if
( upl )
upl
->
print();
if
( apl )
apl
->
print();
cache
<
mem::man::allocator
>
::entry::pl.print();
cache
<
mem::man::aligned_allocator
>
::entry::pl.print();
std::cout
<<
std::endl;
std::cout
<<
"
number of stream_out:
"
<<
num_stream_out
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
std::endl;
std::cout
<<
"
***************************************
"
<<
std::endl;
std::cout
<<
std::endl;
}
public
:
static
heap
*
m_heap;
public
:
class
allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
m_heap
->
alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
m_heap
->
dealloc( ptr, size );
}
mem_inline size_type available()
const
{
return
m_heap
->
available();
}
}
;
class
aligned_allocator
{
public
:
mem_inline
void
*
alloc( size_type size )
{
return
m_heap
->
aligned_alloc( size );
}
mem_inline
void
dealloc(
void
*
ptr, size_type size )
{
m_heap
->
aligned_dealloc( ptr, size );
}
mem_inline size_type available()
const
{
return
m_heap
->
available();
}
}
;
public
:
pool
<
allocator
>
*
upl;
pool
<
aligned_allocator
>
*
apl;
}
;
typedef cache
<
man::allocator
>
::entry resource;
typedef cache
<
man::aligned_allocator
>
::entry aligned_resource;
}
//
namespace mem
extern
mem::man memman;
#pragma pack(pop)
#endif
//
__MEMMAN__
/**/
/*
*************************************************
*
* MemMan 3.0.0.0 beta
*
* Copyright (C) 2007 - 2008 by Len3d
* All rights reserved.
*
************************************************
*/
#ifndef __MEMMAN_DEF__
#define
__MEMMAN_DEF__
#include
"
memman3.h
"
mem::man memman;
mem::heap
*
mem::man::m_heap;
mem::pool
<
mem::man::allocator
>
mem::cache
<
mem::man::allocator
>
::node_pool;
mem::pool
<
mem::man::aligned_allocator
>
mem::cache
<
mem::man::aligned_allocator
>
::node_pool;
mem::time_type mem::num_stream_out;
mem::cache
<
mem::man::allocator
>
mem::cache
<
mem::man::allocator
>
::entry::pl;
mem::cache
<
mem::man::aligned_allocator
>
mem::cache
<
mem::man::aligned_allocator
>
::entry::pl;
#endif
//
__MEMMAN_DEF__
查看全文
相关阅读:
解决VS Code调试.NET Core应用遇到的坑
.NET Core第三方开源Web框架YOYOFx
【干货】”首个“ .NET Core 验证码组件
.NET Core爬坑记 1.0 项目文件
细说ASP.NET Core与OWIN的关系
dock基本使用
在VS中使用TinyFox调试OWIN应用(转)
正则表达式的匹配
构建乘积数组
数组中重复的数字
原文地址:https://www.cnblogs.com/len3d/p/992295.html
最新文章
浅谈对象的创建、内存布局和访问定位
Java内存区域
elk安装和使用
JS数组中级+高级技巧
anjular2以及微信小程序的一点比较
angular2.0学习日记1
将sass快速引入到移动端项目中加速开发
前端自动化之sass实时编译及自动刷新浏览器
前端神器!!gulp livereload实现浏览器自动刷新
记录一下前端ajax实现增删改功能的步骤
热门文章
git pull时出现vim窗口的解决办法
阻止默认行为和冒泡
细说ASP.NET Core静态文件的缓存方式
Debugging into .NET Core源代码的两种方式
在ASP.NET Core使用Middleware模拟Custom Error Page功能
.NET Core中ADO.NET SqlClient的使用与常见问题
.NET Core中使用Razor模板引擎
ASP.NET Core 整合Autofac和Castle实现自动AOP拦截
在.NET Core程序中设置全局异常处理
.NET Core扩展IServiceCollection自动注册服务
Copyright © 2011-2022 走看看