mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-03 17:35:28 +03:00
8acadb17c2
Ports and channels have been moved to the kernel pool, since they've been known to outlive their associated task. This probably isn't the right thing to do, the life cycle needs fixed instead. Some refactorying in memory_region.cpp. Added a helper function to increment and decrement the allocation counter. This makes it easier to switch between atomic and non-atomic increments. Using atomic increments for now, although this still does not fix the problem.
127 lines
3.5 KiB
C++
127 lines
3.5 KiB
C++
#include "rust_internal.h"
|
|
#include "memory_region.h"
|
|
|
|
// NB: please do not commit code with this uncommented. It's
|
|
// hugely expensive and should only be used as a last resort.
|
|
//
|
|
// #define TRACK_ALLOCATIONS
|
|
|
|
memory_region::memory_region(rust_srv *srv, bool synchronized) :
|
|
_srv(srv), _parent(NULL), _live_allocations(0),
|
|
_detailed_leaks(getenv("RUST_DETAILED_LEAKS") != NULL),
|
|
_synchronized(synchronized) {
|
|
}
|
|
|
|
memory_region::memory_region(memory_region *parent) :
|
|
_srv(parent->_srv), _parent(parent), _live_allocations(0),
|
|
_detailed_leaks(parent->_detailed_leaks),
|
|
_synchronized(parent->_synchronized) {
|
|
// Nop.
|
|
}
|
|
|
|
void memory_region::add_alloc() {
|
|
//_live_allocations++;
|
|
sync::increment(_live_allocations);
|
|
}
|
|
|
|
void memory_region::dec_alloc() {
|
|
//_live_allocations--;
|
|
sync::decrement(_live_allocations);
|
|
}
|
|
|
|
void memory_region::free(void *mem) {
|
|
// printf("free: ptr 0x%" PRIxPTR" region=%p\n", (uintptr_t) mem, this);
|
|
if (!mem) { return; }
|
|
if (_synchronized) { _lock.lock(); }
|
|
#ifdef TRACK_ALLOCATIONS
|
|
if (_allocation_list.replace(mem, NULL) == false) {
|
|
printf("free: ptr 0x%" PRIxPTR " is not in allocation_list\n",
|
|
(uintptr_t) mem);
|
|
_srv->fatal("not in allocation_list", __FILE__, __LINE__, "");
|
|
}
|
|
#endif
|
|
if (_live_allocations < 1) {
|
|
_srv->fatal("live_allocs < 1", __FILE__, __LINE__, "");
|
|
}
|
|
dec_alloc();
|
|
_srv->free(mem);
|
|
if (_synchronized) { _lock.unlock(); }
|
|
}
|
|
|
|
void *
|
|
memory_region::realloc(void *mem, size_t size) {
|
|
if (_synchronized) { _lock.lock(); }
|
|
if (!mem) {
|
|
add_alloc();
|
|
}
|
|
void *newMem = _srv->realloc(mem, size);
|
|
#ifdef TRACK_ALLOCATIONS
|
|
if (_allocation_list.replace(mem, newMem) == false) {
|
|
printf("realloc: ptr 0x%" PRIxPTR " is not in allocation_list\n",
|
|
(uintptr_t) mem);
|
|
_srv->fatal("not in allocation_list", __FILE__, __LINE__, "");
|
|
}
|
|
#endif
|
|
if (_synchronized) { _lock.unlock(); }
|
|
return newMem;
|
|
}
|
|
|
|
void *
|
|
memory_region::malloc(size_t size) {
|
|
if (_synchronized) { _lock.lock(); }
|
|
add_alloc();
|
|
void *mem = _srv->malloc(size);
|
|
#ifdef TRACK_ALLOCATIONS
|
|
_allocation_list.append(mem);
|
|
#endif
|
|
// printf("malloc: ptr 0x%" PRIxPTR " region=%p\n",
|
|
// (uintptr_t) mem, this);
|
|
if (_synchronized) { _lock.unlock(); }
|
|
return mem;
|
|
}
|
|
|
|
void *
|
|
memory_region::calloc(size_t size) {
|
|
if (_synchronized) { _lock.lock(); }
|
|
add_alloc();
|
|
void *mem = _srv->malloc(size);
|
|
memset(mem, 0, size);
|
|
#ifdef TRACK_ALLOCATIONS
|
|
_allocation_list.append(mem);
|
|
#endif
|
|
if (_synchronized) { _lock.unlock(); }
|
|
return mem;
|
|
}
|
|
|
|
memory_region::~memory_region() {
|
|
if (_live_allocations == 0) {
|
|
return;
|
|
}
|
|
char msg[128];
|
|
snprintf(msg, sizeof(msg),
|
|
"leaked memory in rust main loop (%" PRIuPTR " objects)",
|
|
_live_allocations);
|
|
#ifdef TRACK_ALLOCATIONS
|
|
if (_detailed_leaks) {
|
|
for (size_t i = 0; i < _allocation_list.size(); i++) {
|
|
if (_allocation_list[i] != NULL) {
|
|
printf("allocation 0x%" PRIxPTR " was not freed\n",
|
|
(uintptr_t) _allocation_list[i]);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
_srv->fatal(msg, __FILE__, __LINE__, "%d objects", _live_allocations);
|
|
}
|
|
|
|
//
|
|
// Local Variables:
|
|
// mode: C++
|
|
// fill-column: 78;
|
|
// indent-tabs-mode: nil
|
|
// c-basic-offset: 4
|
|
// buffer-file-coding-system: utf-8-unix
|
|
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
|
|
// End:
|
|
//
|