2013-01-18 19:58:54 +04:00
|
|
|
#include "util/scoped.hh"
|
|
|
|
|
|
|
|
#include <cstdlib>
|
2013-05-19 18:12:06 +04:00
|
|
|
#if !defined(_WIN32) && !defined(_WIN64)
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#endif
|
2013-01-18 19:58:54 +04:00
|
|
|
|
|
|
|
namespace util {
|
|
|
|
|
|
|
|
MallocException::MallocException(std::size_t requested) throw() {
|
|
|
|
*this << "for " << requested << " bytes ";
|
|
|
|
}
|
|
|
|
|
|
|
|
MallocException::~MallocException() throw() {}
|
|
|
|
|
2013-05-19 18:12:06 +04:00
|
|
|
namespace {
|
|
|
|
void *InspectAddr(void *addr, std::size_t requested, const char *func_name) {
|
|
|
|
UTIL_THROW_IF_ARG(!addr && requested, MallocException, (requested), "in " << func_name);
|
|
|
|
// These routines are often used for large chunks of memory where huge pages help.
|
|
|
|
#if MADV_HUGEPAGE
|
|
|
|
madvise(addr, requested, MADV_HUGEPAGE);
|
|
|
|
#endif
|
|
|
|
return addr;
|
|
|
|
}
|
|
|
|
} // namespace
|
|
|
|
|
2013-01-18 19:58:54 +04:00
|
|
|
void *MallocOrThrow(std::size_t requested) {
|
2013-05-19 18:12:06 +04:00
|
|
|
return InspectAddr(std::malloc(requested), requested, "malloc");
|
2013-01-18 19:58:54 +04:00
|
|
|
}
|
|
|
|
|
2013-01-24 16:07:46 +04:00
|
|
|
void *CallocOrThrow(std::size_t requested) {
|
2013-05-19 18:12:06 +04:00
|
|
|
return InspectAddr(std::calloc(1, requested), requested, "calloc");
|
2013-01-24 16:07:46 +04:00
|
|
|
}
|
|
|
|
|
2013-01-18 19:58:54 +04:00
|
|
|
scoped_malloc::~scoped_malloc() {
|
|
|
|
std::free(p_);
|
|
|
|
}
|
|
|
|
|
2013-05-19 18:12:06 +04:00
|
|
|
void scoped_malloc::call_realloc(std::size_t requested) {
|
|
|
|
p_ = InspectAddr(std::realloc(p_, requested), requested, "realloc");
|
2013-01-18 19:58:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace util
|