Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
d8b3acdf
Commit
d8b3acdf
authored
Feb 21, 2006
by
jonas@eel.(none)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ndb dd
- add resource limit to buddy allocator
parent
af6688dc
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
476 additions
and
145 deletions
+476
-145
storage/ndb/src/kernel/SimBlockList.cpp
storage/ndb/src/kernel/SimBlockList.cpp
+3
-2
storage/ndb/src/kernel/blocks/record_types.hpp
storage/ndb/src/kernel/blocks/record_types.hpp
+17
-11
storage/ndb/src/kernel/main.cpp
storage/ndb/src/kernel/main.cpp
+1
-1
storage/ndb/src/kernel/vm/Emulator.cpp
storage/ndb/src/kernel/vm/Emulator.cpp
+6
-0
storage/ndb/src/kernel/vm/Emulator.hpp
storage/ndb/src/kernel/vm/Emulator.hpp
+1
-0
storage/ndb/src/kernel/vm/Makefile.am
storage/ndb/src/kernel/vm/Makefile.am
+1
-1
storage/ndb/src/kernel/vm/Pool.cpp
storage/ndb/src/kernel/vm/Pool.cpp
+37
-0
storage/ndb/src/kernel/vm/Pool.hpp
storage/ndb/src/kernel/vm/Pool.hpp
+23
-5
storage/ndb/src/kernel/vm/SimBlockList.hpp
storage/ndb/src/kernel/vm/SimBlockList.hpp
+2
-2
storage/ndb/src/kernel/vm/SimulatedBlock.hpp
storage/ndb/src/kernel/vm/SimulatedBlock.hpp
+1
-0
storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
+363
-97
storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
+21
-26
No files found.
storage/ndb/src/kernel/SimBlockList.cpp
View file @
d8b3acdf
...
...
@@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "SimBlockList.hpp"
#include "EmulatorData.hpp"
#include <SimulatedBlock.hpp>
#include <Cmvmi.hpp>
#include <Ndbfs.hpp>
...
...
@@ -69,7 +70,7 @@ void * operator new (size_t sz, SIMBLOCKLIST_DUMMY dummy){
#endif
void
SimBlockList
::
load
(
Configuration
&
conf
){
SimBlockList
::
load
(
EmulatorData
&
data
){
noOfBlocks
=
NO_OF_BLOCKS
;
theList
=
new
SimulatedBlock
*
[
noOfBlocks
];
Dbdict
*
dbdict
=
0
;
...
...
@@ -79,7 +80,7 @@ SimBlockList::load(Configuration & conf){
Tsman
*
ts
=
0
;
Block_context
ctx
=
{
conf
,
*
(
Ndbd_mem_manager
*
)
0
};
{
*
data
.
theConfiguration
,
*
data
.
m_mem_manager
};
SimulatedBlock
*
fs
=
0
;
{
...
...
storage/ndb/src/kernel/blocks/record_types.hpp
View file @
d8b3acdf
...
...
@@ -17,17 +17,6 @@
#ifndef KERNEL_RECORDS_HPP
#define KERNEL_RECORDS_HPP
/**
* Record types
*/
#define PGMAN_PAGE_REQUEST 1
#define LGMAN_LOG_BUFFER_WAITER 2
#define LGMAN_LOG_SYNC_WAITER 3
#define DBTUP_PAGE_REQUEST 4
#define DBTUP_EXTENT_INFO 5
/**
* Resource groups
*/
...
...
@@ -47,4 +36,21 @@
*/
#define RG_DISK_RECORDS 2
/**
*
*/
#define RG_RESERVED 0
#define RG_COUNT 3
/**
* Record types
*/
#define PGMAN_PAGE_REQUEST MAKE_TID(1, RG_DISK_OPERATIONS)
#define LGMAN_LOG_BUFFER_WAITER MAKE_TID(2, RG_DISK_OPERATIONS)
#define LGMAN_LOG_SYNC_WAITER MAKE_TID(3, RG_DISK_OPERATIONS)
#define DBTUP_PAGE_REQUEST MAKE_TID(4, RG_DISK_OPERATIONS)
#define DBTUP_EXTENT_INFO MAKE_TID(5, RG_DISK_RECORDS)
#endif
storage/ndb/src/kernel/main.cpp
View file @
d8b3acdf
...
...
@@ -406,7 +406,7 @@ int main(int argc, char** argv)
systemInfo
(
*
theConfig
,
*
theConfig
->
m_logLevel
);
// Load blocks
globalEmulatorData
.
theSimBlockList
->
load
(
*
theConfig
);
globalEmulatorData
.
theSimBlockList
->
load
(
globalEmulatorData
);
// Set thread concurrency for Solaris' light weight processes
int
status
;
...
...
storage/ndb/src/kernel/vm/Emulator.cpp
View file @
d8b3acdf
...
...
@@ -28,6 +28,7 @@
#include "SimBlockList.hpp"
#include <NodeState.hpp>
#include "ndbd_malloc_impl.hpp"
#include <NdbMem.h>
#include <NdbMutex.h>
...
...
@@ -77,6 +78,7 @@ EmulatorData::EmulatorData(){
theSimBlockList
=
0
;
theShutdownMutex
=
0
;
m_socket_server
=
0
;
m_mem_manager
=
0
;
}
void
...
...
@@ -93,6 +95,7 @@ EmulatorData::create(){
theThreadConfig
=
new
ThreadConfig
();
theSimBlockList
=
new
SimBlockList
();
m_socket_server
=
new
SocketServer
();
m_mem_manager
=
new
Ndbd_mem_manager
();
theShutdownMutex
=
NdbMutex_Create
();
...
...
@@ -111,6 +114,9 @@ EmulatorData::destroy(){
delete
theSimBlockList
;
theSimBlockList
=
0
;
if
(
m_socket_server
)
delete
m_socket_server
;
m_socket_server
=
0
;
if
(
m_mem_manager
)
delete
m_mem_manager
;
m_mem_manager
=
0
;
NdbMem_Destroy
();
}
...
...
storage/ndb/src/kernel/vm/Emulator.hpp
View file @
d8b3acdf
...
...
@@ -56,6 +56,7 @@ struct EmulatorData {
class
ThreadConfig
*
theThreadConfig
;
class
SimBlockList
*
theSimBlockList
;
class
SocketServer
*
m_socket_server
;
class
Ndbd_mem_manager
*
m_mem_manager
;
/**
* Constructor
...
...
storage/ndb/src/kernel/vm/Makefile.am
View file @
d8b3acdf
...
...
@@ -19,7 +19,7 @@ libkernel_a_SOURCES = \
SectionReader.cpp
\
Mutex.cpp SafeCounter.cpp
\
Rope.cpp
\
ndbd_malloc.cpp ndbd_malloc_impl.cpp
ndbd_malloc.cpp ndbd_malloc_impl.cpp
Pool.cpp
INCLUDES_LOC
=
-I
$(top_srcdir)
/storage/ndb/src/mgmapi
...
...
storage/ndb/src/kernel/vm/Pool.cpp
0 → 100644
View file @
d8b3acdf
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "Pool.hpp"
#include "SimulatedBlock.hpp"
void
*
Pool_context
::
alloc_page
(
Uint32
type_id
,
Uint32
*
i
)
{
return
m_block
->
m_ctx
.
m_mm
.
alloc_page
(
type_id
,
i
);
}
void
Pool_context
::
release_page
(
Uint32
type_id
,
Uint32
i
,
void
*
p
)
{
m_block
->
m_ctx
.
m_mm
.
release_page
(
type_id
,
i
,
p
);
}
void
Pool_context
::
handle_abort
(
const
AbortArg
&
)
{
}
storage/ndb/src/kernel/vm/Pool.hpp
View file @
d8b3acdf
...
...
@@ -19,6 +19,22 @@
#include <kernel_types.h>
/**
* Type id is 11 bits record type, and 5 bits resource id
* -> 2048 different kind of records and 32 different resource groups
*
* Resource id is used to handle configuration parameters
*
* see blocks/records_types.hpp
*/
#define RG_BITS 5
#define RG_MASK ((1 << RG_BITS) - 1)
#define MAKE_TID(TID,RG) ((TID << RG_BITS) | RG)
/**
* Record_info
*
*/
struct
Record_info
{
Uint16
m_size
;
...
...
@@ -27,6 +43,9 @@ struct Record_info
Uint16
m_offset_magic
;
};
/**
* Resource_limit
*/
struct
Resource_limit
{
Uint32
m_min
;
...
...
@@ -38,7 +57,6 @@ struct Resource_limit
struct
Pool_context
{
class
SimulatedBlock
*
m_block
;
struct
Resource_limit
*
m_resource_limit
;
/**
* Alloc consekutive pages
...
...
@@ -48,7 +66,7 @@ struct Pool_context
*
* Will handle resource limit
*/
void
*
alloc_page
(
Uint32
*
i
);
void
*
alloc_page
(
Uint32
type_id
,
Uint32
*
i
);
/**
* Release pages
...
...
@@ -56,7 +74,7 @@ struct Pool_context
* @param i : in : i value of first page
* @param p : in : pointer to first page
*/
void
release_page
(
Uint32
i
,
void
*
p
);
void
release_page
(
Uint32
type_id
,
Uint32
i
,
void
*
p
);
/**
* Alloc consekutive pages
...
...
@@ -70,7 +88,7 @@ struct Pool_context
*
* Will handle resource limit
*/
void
*
alloc_pages
(
Uint32
*
i
,
Uint32
*
cnt
,
Uint32
min
=
1
);
void
*
alloc_pages
(
Uint32
type_id
,
Uint32
*
i
,
Uint32
*
cnt
,
Uint32
min
=
1
);
/**
* Release pages
...
...
@@ -79,7 +97,7 @@ struct Pool_context
* @param p : in : pointer to first page
* @param cnt : in : no of pages to release
*/
void
release_pages
(
Uint32
i
,
void
*
p
,
Uint32
cnt
);
void
release_pages
(
Uint32
type_id
,
Uint32
i
,
void
*
p
,
Uint32
cnt
);
/**
* Pool abort
...
...
storage/ndb/src/kernel/vm/SimBlockList.hpp
View file @
d8b3acdf
...
...
@@ -19,7 +19,7 @@
#include <SimulatedBlock.hpp>
class
Configuration
;
class
EmulatorData
;
class
SimBlockList
{
...
...
@@ -27,7 +27,7 @@ public:
SimBlockList
();
~
SimBlockList
();
void
load
(
Configuration
&
conf
);
void
load
(
EmulatorData
&
);
void
unload
();
private:
int
noOfBlocks
;
...
...
storage/ndb/src/kernel/vm/SimulatedBlock.hpp
View file @
d8b3acdf
...
...
@@ -91,6 +91,7 @@ class SimulatedBlock {
friend
class
Page_cache_client
;
friend
class
Lgman
;
friend
class
Logfile_client
;
friend
struct
Pool_context
;
public:
friend
class
BlockComponent
;
virtual
~
SimulatedBlock
();
...
...
storage/ndb/src/kernel/vm/ndbd_malloc_impl.cpp
View file @
d8b3acdf
...
...
@@ -18,6 +18,92 @@
#include "ndbd_malloc_impl.hpp"
#include <ndb_global.h>
#include <EventLogger.hpp>
#ifndef UNIT_TEST
extern
EventLogger
g_eventLogger
;
#else
extern
EventLogger
g_eventLogger
;
#endif
#ifdef NDBD_MALLOC_METHOD
#if NDBD_MALLOC_METHOD == sbrk
static
const
char
*
f_method
=
"sbrk"
;
#else
static
const
char
*
f_method
=
"malloc"
;
#endif
#elif SIZEOF_CHARP == 8
static
const
char
*
f_method
=
"sbrk"
;
#else
static
const
char
*
f_method
=
"malloc"
;
#endif
#define MAX_CHUNKS 10
struct
InitChunk
{
Uint32
m_cnt
;
Uint32
m_start
;
Alloc_page
*
m_ptr
;
};
#include <NdbOut.hpp>
static
bool
do_malloc
(
Uint32
pages
,
InitChunk
*
chunk
)
{
void
*
ptr
;
pages
+=
1
;
Uint32
sz
=
pages
;
if
(
strcmp
(
f_method
,
"sbrk"
)
==
0
)
{
ptr
=
0
;
while
(
ptr
==
0
)
{
ptr
=
sbrk
(
sizeof
(
Alloc_page
)
*
sz
);
if
(
ptr
==
(
void
*
)
-
1
)
{
ptr
=
0
;
sz
=
1
+
(
9
*
sz
)
/
10
;
if
(
pages
>=
32
&&
sz
<
32
)
{
sz
=
pages
;
f_method
=
"malloc"
;
g_eventLogger
.
info
(
"sbrk(%lld) failed, trying malloc"
,
(
Uint64
)(
sizeof
(
Alloc_page
)
*
sz
));
break
;
}
}
}
}
if
(
strcmp
(
f_method
,
"malloc"
)
==
0
)
{
ptr
=
0
;
while
(
ptr
==
0
)
{
ptr
=
malloc
(
sizeof
(
Alloc_page
)
*
sz
);
if
(
ptr
==
0
)
{
sz
=
1
+
(
9
*
sz
)
/
10
;
if
(
pages
>=
32
&&
sz
<
32
)
{
return
false
;
}
}
}
}
chunk
->
m_cnt
=
sz
;
chunk
->
m_ptr
=
(
Alloc_page
*
)
ptr
;
const
UintPtr
align
=
sizeof
(
Alloc_page
)
-
1
;
if
(
UintPtr
(
ptr
)
&
align
)
{
chunk
->
m_cnt
--
;
chunk
->
m_ptr
=
(
Alloc_page
*
)((
UintPtr
(
ptr
)
+
align
)
&
~
align
);
}
return
true
;
}
Uint32
Ndbd_mem_manager
::
log2
(
Uint32
input
)
...
...
@@ -33,67 +119,196 @@ Ndbd_mem_manager::log2(Uint32 input)
return
output
;
}
Ndbd_mem_manager
::
Ndbd_mem_manager
(
Uint32
default_grow
)
Ndbd_mem_manager
::
Ndbd_mem_manager
()
{
m_grow_size
=
default_grow
;
bzero
(
m_buddy_lists
,
sizeof
(
m_buddy_lists
));
m_base
=
0
;
m_base_page
=
0
;
m_pages_alloc
=
0
;
m_pages_used
=
0
;
bzero
(
m_buddy_lists
,
sizeof
(
m_buddy_lists
));
bzero
(
m_resource_limit
,
sizeof
(
m_resource_limit
));
if
(
sizeof
(
Free_page_data
)
!=
(
4
*
(
1
<<
FPD_2LOG
)))
{
g_eventLogger
.
error
(
"Invalid build, ndbd_malloc_impl.cpp:%d"
,
__LINE__
);
abort
();
}
}
void
Ndbd_mem_manager
::
set_resource_limit
(
const
Resource_limit
&
rl
)
{
Uint32
id
=
rl
.
m_resource_id
;
assert
(
id
<
XX_RL_COUNT
);
Uint32
reserve
=
id
?
rl
.
m_min
:
0
;
Uint32
current_reserved
=
m_resource_limit
[
0
].
m_min
;
m_resource_limit
[
id
]
=
rl
;
m_resource_limit
[
id
].
m_curr
=
0
;
m_resource_limit
[
0
].
m_min
=
current_reserved
+
reserve
;
}
bool
Ndbd_mem_manager
::
init
(
Uint32
pages
)
Ndbd_mem_manager
::
init
(
bool
alloc_less_memory
)
{
assert
(
m_base
==
0
);
assert
(
m_base_page
==
0
);
assert
(
m_pages_alloc
==
0
);
pages
=
pages
?
pages
:
m_grow_size
;
Uint32
pages
=
0
;
Uint32
max_page
=
0
;
if
(
m_resource_limit
[
0
].
m_max
)
{
pages
=
m_resource_limit
[
0
].
m_max
;
}
else
{
pages
=
m_resource_limit
[
0
].
m_min
;
// reserved
}
assert
(
pages
);
g_eventLogger
.
info
(
"Ndbd_mem_manager::init(%d) min: %dMb initial: %dMb"
,
alloc_less_memory
,
(
sizeof
(
Alloc_page
)
*
m_resource_limit
[
0
].
m_min
)
>>
20
,
(
sizeof
(
Alloc_page
)
*
m_resource_limit
[
0
].
m_max
)
>>
20
);
/**
* Do malloc
*/
Uint32
cnt
=
0
;
struct
InitChunk
chunks
[
MAX_CHUNKS
];
bzero
(
chunks
,
sizeof
(
chunks
));
Uint32
allocated
=
0
;
while
(
cnt
<
MAX_CHUNKS
&&
allocated
<
pages
)
{
InitChunk
chunk
;
Uint32
remaining
=
pages
-
allocated
;
if
(
do_malloc
(
pages
-
allocated
,
&
chunk
))
{
Uint32
i
=
0
;
for
(;
i
<
cnt
;
i
++
)
{
if
(
chunk
.
m_ptr
<
chunks
[
i
].
m_ptr
)
{
for
(
Uint32
j
=
cnt
;
j
>
i
;
j
--
)
chunks
[
j
]
=
chunks
[
j
-
1
];
break
;
}
}
cnt
++
;
chunks
[
i
]
=
chunk
;
allocated
+=
chunk
.
m_cnt
;
}
else
{
break
;
}
}
m_base
=
malloc
((
2
+
pages
)
*
sizeof
(
Alloc_page
));
UintPtr
ptr
=
(
UintPtr
)
m_base
;
UintPtr
rem
=
ptr
%
sizeof
(
Alloc_page
);
if
(
rem
)
if
(
allocated
<
m_resource_limit
[
0
].
m_min
)
{
ptr
+=
sizeof
(
Alloc_page
)
-
rem
;
g_eventLogger
.
error
(
"Unable to alloc min memory from OS: min: %lldMb "
" allocated: %lldMb"
,
(
Uint64
)(
sizeof
(
Alloc_page
)
*
m_resource_limit
[
0
].
m_min
)
>>
20
,
(
Uint64
)(
sizeof
(
Alloc_page
)
*
allocated
)
>>
20
);
return
false
;
}
else
else
if
(
allocated
<
pages
)
{
pages
++
;
g_eventLogger
.
warning
(
"Unable to alloc requested memory from OS: min: %lldMb"
" requested: %lldMb allocated: %lldMb"
,
(
Uint64
)(
sizeof
(
Alloc_page
)
*
m_resource_limit
[
0
].
m_min
)
>>
20
,
(
Uint64
)(
sizeof
(
Alloc_page
)
*
m_resource_limit
[
0
].
m_max
)
>>
20
,
(
Uint64
)(
sizeof
(
Alloc_page
)
*
allocated
)
>>
20
);
if
(
!
alloc_less_memory
)
return
false
;
}
m_base_page
=
(
Alloc_page
*
)
ptr
;
m_pages_alloc
+=
pages
;
m_pages_used
+=
pages
;
m_base_page
=
chunks
[
0
].
m_ptr
;
for
(
Uint32
i
=
0
;
i
<
cnt
;
i
++
)
{
UintPtr
start
=
UintPtr
(
chunks
[
i
].
m_ptr
)
-
UintPtr
(
m_base_page
);
start
>>=
(
2
+
BMW_2LOG
);
UintPtr
last
=
start
+
chunks
[
i
].
m_cnt
;
chunks
[
i
].
m_start
=
start
;
assert
((
Uint64
(
start
)
>>
32
)
==
0
);
if
(
last
>
max_page
)
max_page
=
last
;
}
m_resource_limit
[
0
].
m_resource_id
=
max_page
;
for
(
Uint32
i
=
0
;
i
<
cnt
;
i
++
)
{
grow
(
chunks
[
i
].
m_start
,
chunks
[
i
].
m_cnt
);
}
return
true
;
}
#include <NdbOut.hpp>
Uint32
bmp
=
(
pages
+
(
1
<<
BPP_2LOG
)
-
1
)
>>
BPP_2LOG
;
for
(
Uint32
i
=
0
;
i
<
bmp
;
i
++
)
void
Ndbd_mem_manager
::
grow
(
Uint32
start
,
Uint32
cnt
)
{
assert
(
cnt
);
Uint32
start_bmp
=
start
>>
BPP_2LOG
;
Uint32
last_bmp
=
(
start
+
cnt
-
1
)
>>
BPP_2LOG
;
#if SIZEOF_CHARP == 4
assert
(
start_bmp
==
0
&&
last_bmp
==
0
);
#endif
if
(
start_bmp
!=
last_bmp
)
{
Uint32
tmp
=
((
start_bmp
+
1
)
<<
BPP_2LOG
)
-
start
;
grow
(
start
,
tmp
);
grow
((
start_bmp
+
1
)
<<
BPP_2LOG
,
cnt
-
tmp
);
return
;
}
if
((
start
+
cnt
)
==
((
start_bmp
+
1
)
<<
BPP_2LOG
))
{
cnt
--
;
// last page is always marked as empty
}
if
(
!
m_used_bitmap_pages
.
get
(
start_bmp
))
{
Uint32
start
=
i
*
(
1
<<
BPP_2LOG
);
Uint32
end
=
start
+
(
1
<<
BPP_2LOG
);
end
=
end
>
m_pages_alloc
?
m_pages_alloc
:
end
-
1
;
Alloc_page
*
ptr
=
m_base_page
+
start
;
BitmaskImpl
::
clear
(
BITMAP_WORDS
,
ptr
->
m_data
);
if
(
start
!=
(
start_bmp
<<
BPP_2LOG
))
{
ndbout_c
(
"ndbd_malloc_impl.cpp:%d:grow(%d, %d) %d!=%d"
" - Unable to use due to bitmap pages missaligned!!"
,
__LINE__
,
start
,
cnt
,
start
,
(
start_bmp
<<
BPP_2LOG
));
g_eventLogger
.
error
(
"ndbd_malloc_impl.cpp:%d:grow(%d, %d)"
" - Unable to use due to bitmap pages missaligned!!"
,
__LINE__
,
start
,
cnt
);
return
;
}
release
(
start
+
1
,
end
-
1
-
start
);
Alloc_page
*
bmp
=
m_base_page
+
start
;
memset
(
bmp
,
0
,
sizeof
(
Alloc_page
));
m_used_bitmap_pages
.
set
(
start_bmp
);
cnt
--
;
start
++
;
}
return
true
;
if
(
cnt
)
{
m_resource_limit
[
0
].
m_curr
+=
cnt
;
m_resource_limit
[
0
].
m_max
+=
cnt
;
release
(
start
,
cnt
);
}
}
void
Ndbd_mem_manager
::
release
(
Uint32
start
,
Uint32
cnt
)
{
assert
(
m_
pages_used
>=
cnt
);
assert
(
m_
resource_limit
[
0
].
m_curr
>=
cnt
);
assert
(
start
);
m_
pages_used
-=
cnt
;
m_
resource_limit
[
0
].
m_curr
-=
cnt
;
set
(
start
,
start
+
cnt
-
1
);
release_impl
(
start
,
cnt
);
...
...
@@ -131,7 +346,8 @@ Ndbd_mem_manager::release_impl(Uint32 start, Uint32 cnt)
void
Ndbd_mem_manager
::
alloc
(
Uint32
*
ret
,
Uint32
*
pages
,
Uint32
min
)
{
Uint32
start
,
i
;
Int32
i
;
Uint32
start
;
Uint32
cnt
=
*
pages
;
Uint32
list
=
log2
(
cnt
-
1
);
...
...
@@ -160,8 +376,8 @@ Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
clear
(
start
,
start
+
cnt
-
1
);
}
*
ret
=
start
;
m_
pages_used
+=
cnt
;
assert
(
m_
pages_used
<=
m_pages_alloc
);
m_
resource_limit
[
0
].
m_curr
+=
cnt
;
assert
(
m_
resource_limit
[
0
].
m_curr
<=
m_resource_limit
[
0
].
m_max
);
return
;
}
}
...
...
@@ -171,7 +387,7 @@ Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
* search in other lists...
*/
Ui
nt32
min_list
=
log2
(
min
-
1
);
I
nt32
min_list
=
log2
(
min
-
1
);
assert
(
list
>=
min_list
);
for
(
i
=
list
-
1
;
i
>=
min_list
;
i
--
)
{
...
...
@@ -192,33 +408,14 @@ Ndbd_mem_manager::alloc(Uint32* ret, Uint32 *pages, Uint32 min)
*
ret
=
start
;
*
pages
=
sz
;
m_
pages_used
+=
sz
;
assert
(
m_
pages_used
<=
m_pages_alloc
);
m_
resource_limit
[
0
].
m_curr
+=
sz
;
assert
(
m_
resource_limit
[
0
].
m_curr
<=
m_resource_limit
[
0
].
m_max
);
return
;
}
}
*
pages
=
0
;
}
void
*
Ndbd_mem_manager
::
alloc
(
Uint32
*
pages
,
Uint32
min
)
{
Uint32
ret
;
alloc
(
&
ret
,
pages
,
min
);
if
(
pages
)
{
return
m_base_page
+
ret
;
}
return
0
;
}
void
Ndbd_mem_manager
::
release
(
void
*
ptr
,
Uint32
cnt
)
{
Uint32
page
=
((
Alloc_page
*
)
ptr
)
-
m_base_page
;
release
(
page
,
cnt
);
}
void
Ndbd_mem_manager
::
insert_free_list
(
Uint32
start
,
Uint32
size
)
{
...
...
@@ -284,25 +481,6 @@ Ndbd_mem_manager::remove_free_list(Uint32 start, Uint32 list)
return
size
;
}
Uint32
Ndbd_mem_manager
::
get_no_allocated_pages
()
const
{
return
m_pages_alloc
;
}
Uint32
Ndbd_mem_manager
::
get_no_used_pages
()
const
{
return
m_pages_used
;
}
Uint32
Ndbd_mem_manager
::
get_no_free_pages
()
const
{
return
m_pages_alloc
-
m_pages_used
;
}
void
Ndbd_mem_manager
::
dump
()
const
{
...
...
@@ -321,31 +499,105 @@ Ndbd_mem_manager::dump() const
}
}
void
*
Ndbd_mem_manager
::
alloc_page
(
Uint32
type
,
Uint32
*
i
)
{
Uint32
idx
=
type
&
RG_MASK
;
assert
(
idx
&&
idx
<
XX_RL_COUNT
);
Resource_limit
tot
=
m_resource_limit
[
0
];
Resource_limit
rl
=
m_resource_limit
[
idx
];
Uint32
add
=
(
rl
.
m_curr
<
rl
.
m_min
)
?
0
:
1
;
// Over min ?
Uint32
limit
=
(
rl
.
m_max
==
0
||
rl
.
m_curr
<
rl
.
m_max
)
?
0
:
1
;
// Over limit
Uint32
free
=
(
tot
.
m_min
+
tot
.
m_curr
<
tot
.
m_max
)
?
1
:
0
;
// Has free
if
(
likely
(
add
==
0
||
(
limit
==
0
&&
free
==
1
)))
{
Uint32
cnt
=
1
;
alloc
(
i
,
&
cnt
,
1
);
assert
(
cnt
);
m_resource_limit
[
0
].
m_curr
=
tot
.
m_curr
+
add
;
m_resource_limit
[
idx
].
m_curr
=
rl
.
m_curr
+
1
;
return
m_base_page
+
*
i
;
}
return
0
;
}
void
Ndbd_mem_manager
::
release_page
(
Uint32
type
,
Uint32
i
,
void
*
p
)
{
Uint32
idx
=
type
&
RG_MASK
;
assert
(
idx
&&
idx
<
XX_RL_COUNT
);
Resource_limit
tot
=
m_resource_limit
[
0
];
Resource_limit
rl
=
m_resource_limit
[
idx
];
Uint32
sub
=
(
rl
.
m_curr
<
rl
.
m_min
)
?
0
:
1
;
// Over min ?
release
(
i
,
1
);
m_resource_limit
[
0
].
m_curr
=
tot
.
m_curr
-
sub
;
}
#ifdef UNIT_TEST
#include <Vector.hpp>
#include <NdbTick.h>
struct
Chunk
{
Uint32
pageId
;
Uint32
pageCount
;
};
struct
Timer
{
Uint64
sum
;
Uint32
cnt
;
Timer
()
{
sum
=
cnt
=
0
;}
void
add
(
Uint64
diff
)
{
sum
+=
diff
;
cnt
++
;}
void
print
(
const
char
*
title
)
const
{
printf
(
"%s %lld %d -> %d/s
\n
"
,
title
,
sum
,
cnt
,
Uint32
(
1000
*
cnt
/
sum
));
}
};
int
main
(
void
)
{
char
buf
[
255
];
Timer
timer
[
4
];
printf
(
"Startar modul test av Page Manager
\n
"
);
g_eventLogger
.
createConsoleHandler
();
g_eventLogger
.
setCategory
(
"keso"
);
g_eventLogger
.
enable
(
Logger
::
LL_ON
,
Logger
::
LL_INFO
);
g_eventLogger
.
enable
(
Logger
::
LL_ON
,
Logger
::
LL_CRITICAL
);
g_eventLogger
.
enable
(
Logger
::
LL_ON
,
Logger
::
LL_ERROR
);
g_eventLogger
.
enable
(
Logger
::
LL_ON
,
Logger
::
LL_WARNING
);
#define DEBUG 0
Ndbd_mem_manager
mem
;
mem
.
init
(
32000
);
Resource_limit
rl
;
rl
.
m_min
=
0
;
rl
.
m_max
=
2
*
32768
+
2
*
16384
;
rl
.
m_curr
=
0
;
rl
.
m_resource_id
=
0
;
mem
.
set_resource_limit
(
rl
);
rl
.
m_min
=
32768
;
rl
.
m_max
=
0
;
rl
.
m_resource_id
=
1
;
mem
.
set_resource_limit
(
rl
);
mem
.
init
();
mem
.
dump
();
printf
(
"pid: %d press enter to continue
\n
"
,
getpid
());
fgets
(
buf
,
sizeof
(
buf
),
stdin
);
Vector
<
Chunk
>
chunks
;
const
Uint32
LOOPS
=
100000
;
const
Uint32
LOOPS
=
100000
0
;
for
(
Uint32
i
=
0
;
i
<
LOOPS
;
i
++
){
//mem.dump();
// Case
Uint32
c
=
(
rand
()
%
100
);
const
Uint32
free
=
mem
.
get_no_allocated_pages
()
-
mem
.
get_no_used_pages
();
if
(
c
<
60
)
{
c
=
0
;
...
...
@@ -359,17 +611,8 @@ main(void)
c
=
2
;
}
Uint32
alloc
=
0
;
if
(
free
<=
1
)
{
c
=
0
;
alloc
=
1
;
}
else
{
alloc
=
1
+
(
rand
()
%
(
free
-
1
));
}
Uint32
alloc
=
1
+
rand
()
%
3200
;
if
(
chunks
.
size
()
==
0
&&
c
==
0
)
{
c
=
1
+
rand
()
%
2
;
...
...
@@ -382,38 +625,52 @@ main(void)
const
int
ch
=
rand
()
%
chunks
.
size
();
Chunk
chunk
=
chunks
[
ch
];
chunks
.
erase
(
ch
);
Uint64
start
=
NdbTick_CurrentMillisecond
();
mem
.
release
(
chunk
.
pageId
,
chunk
.
pageCount
);
Uint64
stop
=
NdbTick_CurrentMillisecond
();
timer
[
0
].
add
(
stop
-
start
);
if
(
DEBUG
)
printf
(
" release %d %d
\n
"
,
chunk
.
pageId
,
chunk
.
pageCount
);
}
break
;
case
2
:
{
// Seize(n) - fail
alloc
+=
free
;
alloc
+=
32000
;
// Fall through
}
case
1
:
{
// Seize(n) (success)
Chunk
chunk
;
chunk
.
pageCount
=
alloc
;
if
(
DEBUG
)
{
printf
(
" alloc %d -> "
,
alloc
);
fflush
(
stdout
);
}
Uint64
start
=
NdbTick_CurrentMillisecond
();
mem
.
alloc
(
&
chunk
.
pageId
,
&
chunk
.
pageCount
,
1
);
Uint64
stop
=
NdbTick_CurrentMillisecond
();
if
(
DEBUG
)
printf
(
"
alloc %d -> %d %d"
,
alloc
,
chunk
.
pageId
,
chunk
.
pageCount
);
printf
(
"
%d %d"
,
chunk
.
pageId
,
chunk
.
pageCount
);
assert
(
chunk
.
pageCount
<=
alloc
);
if
(
chunk
.
pageCount
!=
0
){
chunks
.
push_back
(
chunk
);
if
(
chunk
.
pageCount
!=
alloc
)
{
timer
[
2
].
add
(
stop
-
start
);
if
(
DEBUG
)
printf
(
" - Tried to allocate %d - only allocated %d - free: %d"
,
alloc
,
chunk
.
pageCount
,
free
);
alloc
,
chunk
.
pageCount
,
0
);
}
else
{
timer
[
1
].
add
(
stop
-
start
);
}
}
else
{
timer
[
3
].
add
(
stop
-
start
);
if
(
DEBUG
)
printf
(
" Failed to alloc %d pages with %d pages free"
,
alloc
,
free
);
alloc
,
0
);
}
if
(
DEBUG
)
printf
(
"
\n
"
);
if
(
alloc
==
1
&&
free
>
0
)
assert
(
chunk
.
pageCount
==
alloc
);
}
break
;
}
...
...
@@ -424,6 +681,15 @@ main(void)
mem
.
release
(
chunk
.
pageId
,
chunk
.
pageCount
);
chunks
.
erase
(
chunks
.
size
()
-
1
);
}
const
char
*
title
[]
=
{
"release "
,
"alloc full"
,
"alloc part"
,
"alloc fail"
};
for
(
Uint32
i
=
0
;
i
<
4
;
i
++
)
timer
[
i
].
print
(
title
[
i
]);
}
template
class
Vector
<
Chunk
>;
...
...
storage/ndb/src/kernel/vm/ndbd_malloc_impl.hpp
View file @
d8b3acdf
...
...
@@ -20,6 +20,7 @@
#include <kernel_types.h>
#include <Bitmask.hpp>
#include <assert.h>
#include "Pool.hpp"
/**
* 13 -> 8192 words -> 32768 bytes
...
...
@@ -51,25 +52,22 @@ struct Free_page_data
class
Ndbd_mem_manager
{
public:
Ndbd_mem_manager
(
Uint32
default_grow
=
32
);
Ndbd_mem_manager
();
void
set_resource_limit
(
const
Resource_limit
&
rl
);
bool
init
(
bool
allow_alloc_less_than_requested
=
true
);
void
grow
(
Uint32
start
,
Uint32
cnt
);
void
*
get_memroot
()
const
{
return
(
void
*
)
m_base_page
;}
void
alloc
(
Uint32
*
ret
,
Uint32
*
pages
,
Uint32
min_requested
);
void
release
(
Uint32
start
,
Uint32
cnt
);
Uint32
get_no_allocated_pages
()
const
;
Uint32
get_no_used_pages
()
const
;
Uint32
get_no_free_pages
()
const
;
bool
init
(
Uint32
pages
=
0
);
bool
grow
(
Uint32
pages
=
0
);
void
dump
()
const
;
void
*
get_memroot
()
const
{
return
(
void
*
)
m_base_page
;}
void
*
alloc
(
Uint32
*
pages
,
Uint32
min_requested
);
void
release
(
void
*
ptr
,
Uint32
cnt
);
void
*
alloc_page
(
Uint32
type
,
Uint32
*
i
);
void
release_page
(
Uint32
type
,
Uint32
i
,
void
*
p
);
/**
* Compute 2log of size
* @note size = 0 -> 0
...
...
@@ -78,18 +76,15 @@ public:
static
Uint32
log2
(
Uint32
size
);
private:
#define XX_RL_COUNT 3
/**
* Return pointer to free page data on page
*/
static
Free_page_data
*
get_free_page_data
(
Alloc_page
*
,
Uint32
idx
);
Bitmask
<
1
>
m_used_bitmap_pages
;
Uint32
m_pages_alloc
;
Uint32
m_pages_used
;
Uint32
m_grow_size
;
Uint32
m_buddy_lists
[
16
];
void
*
m_base
;
Resource_limit
m_resource_limit
[
XX_RL_COUNT
];
// RG_COUNT in record_types.hpp
Alloc_page
*
m_base_page
;
void
release_impl
(
Uint32
start
,
Uint32
cnt
);
...
...
@@ -121,7 +116,7 @@ Ndbd_mem_manager::set(Uint32 first, Uint32 last)
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
Uint32
bmp
=
first
&
~
((
1
<<
BPP_2LOG
)
-
1
);
assert
((
first
>>
BPP_2LOG
)
==
(
last
>>
BPP_2LOG
));
assert
(
bmp
<
m_
pages_alloc
);
assert
(
bmp
<
m_
resource_limit
[
0
].
m_resource_id
);
first
-=
bmp
;
last
-=
bmp
;
...
...
@@ -139,7 +134,7 @@ Ndbd_mem_manager::clear(Uint32 first, Uint32 last)
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
Uint32
bmp
=
first
&
~
((
1
<<
BPP_2LOG
)
-
1
);
assert
((
first
>>
BPP_2LOG
)
==
(
last
>>
BPP_2LOG
));
assert
(
bmp
<
m_
pages_alloc
);
assert
(
bmp
<
m_
resource_limit
[
0
].
m_resource_id
);
first
-=
bmp
;
last
-=
bmp
;
...
...
@@ -157,7 +152,7 @@ Ndbd_mem_manager::clear_and_set(Uint32 first, Uint32 last)
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
Uint32
bmp
=
first
&
~
((
1
<<
BPP_2LOG
)
-
1
);
assert
((
first
>>
BPP_2LOG
)
==
(
last
>>
BPP_2LOG
));
assert
(
bmp
<
m_
pages_alloc
);
assert
(
bmp
<
m_
resource_limit
[
0
].
m_resource_id
);
first
-=
bmp
;
last
-=
bmp
;
...
...
@@ -177,7 +172,7 @@ Ndbd_mem_manager::check(Uint32 first, Uint32 last)
#if ((SPACE_PER_BMP_2LOG < 32) && (SIZEOF_CHARP == 4)) || (SIZEOF_CHARP == 8)
Uint32
bmp
=
first
&
~
((
1
<<
BPP_2LOG
)
-
1
);
assert
((
first
>>
BPP_2LOG
)
==
(
last
>>
BPP_2LOG
));
assert
(
bmp
<
m_
pages_alloc
);
assert
(
bmp
<
m_
resource_limit
[
0
].
m_resource_id
);
first
-=
bmp
;
last
-=
bmp
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment