Skip to content

Instantly share code, notes, and snippets.

@buchgr
Created November 25, 2015 15:50
Show Gist options
  • Save buchgr/243b0aa9a2abeda2ac39 to your computer and use it in GitHub Desktop.
Save buchgr/243b0aa9a2abeda2ac39 to your computer and use it in GitHub Desktop.
#include <jemalloc/jemalloc.h>
#include <iostream>
class JeInit {
private:
static chunk_hooks_t old_hooks;
public:
JeInit() {
unsigned narenas;
size_t size;
size_t mib[3];
size_t hooks_len;
size = sizeof(narenas);
mallctl("arenas.narenas", &narenas, &size, nullptr, 0);
size = sizeof(mib) / sizeof(mib[0]);
mallctlnametomib("arena.0.chunk_hooks", mib, &size);
mib[1] = 0;
hooks_len = sizeof(chunk_hooks_t);
mallctlbymib(mib, size, &old_hooks, &hooks_len, nullptr, 0);
chunk_hooks_t new_hooks = {JeInit::chunk_alloc, JeInit::chunk_dalloc, JeInit::chunk_commit,
JeInit::chunk_decommit, JeInit::chunk_purge, JeInit::chunk_split, JeInit::chunk_merge};
for (unsigned arena = 0; arena < narenas; arena++) {
mib[1] = arena;
mallctlbymib(mib, size, nullptr, nullptr, &new_hooks, hooks_len);
}
}
private:
static void *chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit, unsigned arena_ind) {
void *ret = old_hooks.alloc(new_addr, size, alignment, zero, commit, arena_ind);
std::cout << "ALLOC: "
<< "new_addr " << new_addr << ", "
<< "size " << size << ", "
<< "alignment " << alignment << ", "
<< "zero " << *zero << ", "
<< "commit " << *commit << ", "
<< "arena_ind " << arena_ind << ", "
<< "ret " << ret << std::endl;
return ret;
}
static bool chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind) {
std::cout << "DALLOC: "
<< "chunk " << chunk << ", "
<< "size " << size << ", "
<< "committed " << committed << ", "
<< "arena_ind " << arena_ind << std::endl;
// opt out from dalloc
return true;
}
static bool chunk_commit(void *chunk, size_t size, size_t offset, size_t length, unsigned arena_ind) {
std::cout << "COMMIT: "
<< "chunk " << chunk << ", "
<< "size " << size << ", "
<< "offset " << offset << ", "
<< "length " << length << ", "
<< "arena_ind " << arena_ind << std::endl;
// commit should always succeed
return old_hooks.commit(chunk, size, offset, length, arena_ind);
}
static bool chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, unsigned arena_ind) {
std::cout << "DECOMMIT: "
<< "chunk " << chunk << ", "
<< "size " << size << ", "
<< "offset " << offset << ", "
<< "length " << length << ", "
<< "arena_ind " << arena_ind << std::endl;
return old_hooks.decommit(chunk, size, offset, length, arena_ind);
}
static bool chunk_purge(void *chunk, size_t size, size_t offset, size_t length, unsigned arena_ind) {
std::cout << "PURGE: "
<< "chunk " << chunk << ", "
<< "size " << size << ", "
<< "offset " << offset << ", "
<< "length " << length << ", "
<< "arena_ind " << arena_ind << std::endl;
return old_hooks.purge(chunk, size, offset, length, arena_ind);
}
static bool chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, bool committed, unsigned arena_ind) {
return old_hooks.split(chunk, size, size_a, size_b, committed, arena_ind);
}
static bool chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, bool committed, unsigned arena_ind) {
return old_hooks.merge(chunk_a, size_a, chunk_b, size_b, committed, arena_ind);
}
};
chunk_hooks_t JeInit::old_hooks = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
JeInit init;
int main(int argc, char** argv) {
// Allocate 1GB of virtual memory
void* p1 = malloc(1 << 30);
free(p1);
std::cout << "FREED" << std::endl;
// The 1GB virtually memory should be
// reused by jemalloc here.
void *p3 = malloc(1 << 22);
void *p4 = malloc(1 << 23);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment