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__
查看全文
相关阅读:
一款前端文件上传工具
聊一聊最近找工作的感受
神秘的计算机网络----(1)
月下无限连?拒绝无休止switch!
计算机网络---序
验证码识别
两数之和
Sanic框架基础之解决CORS跨域
Sanic框架进阶之实现异步缓存组件
asyncio异步模块的21个协程编写实例
原文地址:https://www.cnblogs.com/len3d/p/988562.html
最新文章
Java 如何查找文件目录下的所有文件夹和文件
Java锁_读写锁
redis笔记
Ajax&Json笔记
JQuery高级笔记
JQuery基础笔记
Filter&Listener笔记
各种性能测试的侧重点
创建临时表
彻底卸载VMware
热门文章
dos连接mysql
用navicat给postgresql写一个简单存储
jmeter线程组cookie共享以及设置集合点做多线程性能测试
postman引入外部js文件
Linux上,最常用的一批命令解析(10年精选)
spring通过xml方式加载properties文件
DML,DDL,DCL的区别
移动端调试Web页面
IndexedDB的基础使用
关于 【顺序执行Promise】 的一些理解
Copyright © 2011-2022 走看看