Getting ready to shift to dlmalloc
This commit is contained in:
@@ -65,6 +65,7 @@ LUA_OBJ_FILES=\
|
|||||||
CORE_OBJ_FILES=\
|
CORE_OBJ_FILES=\
|
||||||
obj/invocation.o\
|
obj/invocation.o\
|
||||||
obj/spookyv2.o\
|
obj/spookyv2.o\
|
||||||
|
obj/eng-malloc.o\
|
||||||
obj/debugcollector.o\
|
obj/debugcollector.o\
|
||||||
obj/drivenengine.o\
|
obj/drivenengine.o\
|
||||||
obj/dummycert.o\
|
obj/dummycert.o\
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "drivertests.hpp"
|
#include "drivertests.hpp"
|
||||||
#include "drivenengine.hpp"
|
#include "drivenengine.hpp"
|
||||||
#include "world.hpp"
|
#include "world.hpp"
|
||||||
|
#include "eng-malloc.hpp"
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
static void write_closed_message(Channel *ch, StreamBuffer *out) {
|
static void write_closed_message(Channel *ch, StreamBuffer *out) {
|
||||||
@@ -92,7 +93,7 @@ public:
|
|||||||
virtual void event_update() {
|
virtual void event_update() {
|
||||||
double clock = get_clock();
|
double clock = get_clock();
|
||||||
if (clock > last_clock_ + 0.5) {
|
if (clock > last_clock_ + 0.5) {
|
||||||
int ms = util::hash_of_mallocs();
|
int ms = dlmalloc_hash();
|
||||||
stdostream() << std::fixed << std::setprecision(2) << clock << " " << std::hex << ms << " ";
|
stdostream() << std::fixed << std::setprecision(2) << clock << " " << std::hex << ms << " ";
|
||||||
count_++;
|
count_++;
|
||||||
last_clock_ = clock;
|
last_clock_ = clock;
|
||||||
|
|||||||
64
luprex/core/cpp/eng-malloc.cpp
Normal file
64
luprex/core/cpp/eng-malloc.cpp
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
// We only use a custom allocator on linux (for now)
|
||||||
|
// The allocator we chose is 'dlmalloc' (doug lea's malloc).
|
||||||
|
// It's a good allocator for single-threaded programs.
|
||||||
|
// It needs to be configured by setting a bunch of defines.
|
||||||
|
//
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
// We need this to define dlmalloc, not malloc.
|
||||||
|
#define USE_DL_PREFIX 1
|
||||||
|
|
||||||
|
// We don't need mspaces.
|
||||||
|
#define ONLY_MSPACES 0
|
||||||
|
#define MSPACES 0
|
||||||
|
|
||||||
|
// We don't need mallinfo
|
||||||
|
#define NO_MALLINFO 1
|
||||||
|
|
||||||
|
// We don't need dlmalloc_inspect_all
|
||||||
|
#define MALLOC_INSPECT_ALL 0
|
||||||
|
|
||||||
|
// We don't need dlmalloc_stats.
|
||||||
|
#define NO_MALLOC_STATS 1
|
||||||
|
|
||||||
|
// Disable locking. The entire engine is single-threaded.
|
||||||
|
#define USE_LOCKS 0
|
||||||
|
|
||||||
|
// For now, we'll let the allocator use mmap to get memory.
|
||||||
|
// It's not clear if this is going to be deterministic.
|
||||||
|
#define HAVE_MMAP 1
|
||||||
|
|
||||||
|
// One way to force determinism would be to emulate sbrk
|
||||||
|
// using mmap and mremap, always putting the heap at a fixed
|
||||||
|
// address. For now, we're not doing that, we're just
|
||||||
|
// using mmap and relying on that being deterministic (we hope).
|
||||||
|
#define HAVE_MORECORE 0
|
||||||
|
#define MORECORE emulate_sbrk
|
||||||
|
|
||||||
|
// The properties of mmap under linux
|
||||||
|
#define MMAP_CLEARS 1
|
||||||
|
#define HAVE_MREMAP 1
|
||||||
|
|
||||||
|
// Don't generate random seeds, or time-based seeds.
|
||||||
|
#define USE_DEV_RANDOM 0
|
||||||
|
#define LACKS_TIME_H 1
|
||||||
|
|
||||||
|
#include "dlmalloc/dlmalloc.c"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int dlmalloc_hash() {
|
||||||
|
void *blocks[15];
|
||||||
|
int hash = 0;
|
||||||
|
for (int i = 0; i < 15; i++) {
|
||||||
|
void *blk = dlmalloc(1 << i);
|
||||||
|
blocks[i] = blk;
|
||||||
|
hash = (hash * 17) + (int)(intptr_t)(blk);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 15; i++) {
|
||||||
|
free(blocks[i]);
|
||||||
|
}
|
||||||
|
return (hash & 0x7FFFFFFF) | (0x40000000);
|
||||||
|
}
|
||||||
|
|
||||||
105
luprex/core/cpp/eng-malloc.hpp
Normal file
105
luprex/core/cpp/eng-malloc.hpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#ifndef ENG_MALLOC_HPP
|
||||||
|
#define ENG_MALLOC_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
// dlmalloc is only used on linux.
|
||||||
|
extern "C" {
|
||||||
|
#ifdef __linux__
|
||||||
|
void* dlmalloc(size_t x);
|
||||||
|
void dlfree(void *p);
|
||||||
|
void* dlrealloc(void*, size_t);
|
||||||
|
#else
|
||||||
|
void* dlmalloc(size_t x) { return malloc(x); }
|
||||||
|
void dlfree(void *p) { free(p); }
|
||||||
|
void* dlrealloc(void *p, size_t x) { return realloc(p,x); }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the current state of the dlmalloc allocator as a 30-bit hash.
|
||||||
|
extern int dlmalloc_hash();
|
||||||
|
|
||||||
|
// EngAllocator: a class meant to be used as an STL Allocator.
|
||||||
|
// Causes objects to be allocated using dlmalloc and dlfree.
|
||||||
|
template <class T>
|
||||||
|
class EngAllocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using value_type = T;
|
||||||
|
EngAllocator() noexcept {}
|
||||||
|
template <class U> EngAllocator(EngAllocator<U> const&) noexcept {}
|
||||||
|
|
||||||
|
value_type* allocate(std::size_t n)
|
||||||
|
{
|
||||||
|
return static_cast<value_type*>(dlmalloc(n*sizeof(value_type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(value_type* p, std::size_t) noexcept
|
||||||
|
{
|
||||||
|
dlfree(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
bool operator==(EngAllocator<T> const&, EngAllocator<U> const&) noexcept
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class U>
|
||||||
|
bool operator!=(EngAllocator<T> const&, EngAllocator<U> const&) noexcept
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace eng {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using hash = std::hash<T>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using less = std::less<T>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using equal_to = std::equal_to<T>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using char_traits = std::char_traits<T>;
|
||||||
|
|
||||||
|
template<class A, class B>
|
||||||
|
using pair = std::pair<A, B>;
|
||||||
|
|
||||||
|
template<class C, class T=char_traits<C>>
|
||||||
|
using basic_string = std::basic_string<C, T, EngAllocator<C>>;
|
||||||
|
|
||||||
|
template<class C, class T=char_traits<C>>
|
||||||
|
using basic_stringstream = std::basic_stringstream<C, T, EngAllocator<C>>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
using vector = std::vector<T, EngAllocator<T>>;
|
||||||
|
|
||||||
|
template<class K, class V, class C=less<K>>
|
||||||
|
using map = std::map<K, V, C, EngAllocator<pair<const K, V>>>;
|
||||||
|
|
||||||
|
template<class K, class V, class H=hash<K>, class E=equal_to<K>>
|
||||||
|
using unordered_map = std::unordered_map<K, V, H, E, EngAllocator<pair<const K, V>>>;
|
||||||
|
|
||||||
|
template<class K, class C=std::less<K>>
|
||||||
|
using set = std::set<K, C, EngAllocator<K>>;
|
||||||
|
|
||||||
|
template<class K, class H=hash<K>, class E=equal_to<K>>
|
||||||
|
using unordered_set = std::unordered_set<K, H, E, EngAllocator<K>>;
|
||||||
|
|
||||||
|
using string = basic_string<char>;
|
||||||
|
using stringstream = basic_stringstream<char>;
|
||||||
|
}
|
||||||
|
#endif // ENG_MALLOC_HPP
|
||||||
|
|
||||||
@@ -353,20 +353,6 @@ bool is_lua_comment(const std::string &s) {
|
|||||||
return s.substr(start, 2) == "--";
|
return s.substr(start, 2) == "--";
|
||||||
}
|
}
|
||||||
|
|
||||||
int hash_of_mallocs() {
|
|
||||||
void *blocks[15];
|
|
||||||
int hash = 0;
|
|
||||||
for (int i = 0; i < 15; i++) {
|
|
||||||
void *blk = malloc(1 << i);
|
|
||||||
blocks[i] = blk;
|
|
||||||
hash = (hash * 17) + (int)(ptrdiff_t)(blk);
|
|
||||||
}
|
|
||||||
for (int i = 0; i < 15; i++) {
|
|
||||||
free(blocks[i]);
|
|
||||||
}
|
|
||||||
return (hash & 0x7FFFFFFF) | (0x40000000);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string XYZ::debug_string() const {
|
std::string XYZ::debug_string() const {
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "(" << x << "," << y << "," << z << ")";
|
oss << "(" << x << "," << y << "," << z << ")";
|
||||||
|
|||||||
@@ -125,11 +125,6 @@ LuaSourcePtr make_lua_source(const std::string &code);
|
|||||||
// Return true if the line of code is a lua comment.
|
// Return true if the line of code is a lua comment.
|
||||||
bool is_lua_comment(const std::string &line);
|
bool is_lua_comment(const std::string &line);
|
||||||
|
|
||||||
// Malloc some blocks of RAM, and calculate a hash from
|
|
||||||
// their addresses. This can be used to determine if the malloc
|
|
||||||
// heap is in a deterministic state.
|
|
||||||
int hash_of_mallocs();
|
|
||||||
|
|
||||||
// Remove nullptrs from a vector of unique pointers.
|
// Remove nullptrs from a vector of unique pointers.
|
||||||
template<class T>
|
template<class T>
|
||||||
void remove_nullptrs(std::vector<std::unique_ptr<T>> &vec) {
|
void remove_nullptrs(std::vector<std::unique_ptr<T>> &vec) {
|
||||||
|
|||||||
6252
luprex/linuxlib/dlmalloc/dlmalloc.c
Normal file
6252
luprex/linuxlib/dlmalloc/dlmalloc.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user