Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Lots of changes around memory managment in the Runtime. Added memory …
…regions and fixed race caused by calling rust_srv::malloc() from multiple threads when sending messages.
- Loading branch information
Showing
13 changed files
with
303 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* | ||
*/ | ||
|
||
#ifndef MEMORY_H | ||
#define MEMORY_H | ||
|
||
|
||
inline void *operator new(size_t size, void *mem) { | ||
return mem; | ||
} | ||
|
||
inline void *operator new(size_t size, rust_dom *dom) { | ||
return dom->malloc(size, memory_region::LOCAL); | ||
} | ||
|
||
inline void *operator new[](size_t size, rust_dom *dom) { | ||
return dom->malloc(size, memory_region::LOCAL); | ||
} | ||
|
||
inline void *operator new(size_t size, rust_dom &dom) { | ||
return dom.malloc(size, memory_region::LOCAL); | ||
} | ||
|
||
inline void *operator new[](size_t size, rust_dom &dom) { | ||
return dom.malloc(size, memory_region::LOCAL); | ||
} | ||
|
||
inline void *operator new(size_t size, rust_dom *dom, | ||
memory_region::memory_region_type type) { | ||
return dom->malloc(size, type); | ||
} | ||
|
||
inline void *operator new[](size_t size, rust_dom *dom, | ||
memory_region::memory_region_type type) { | ||
return dom->malloc(size, type); | ||
} | ||
|
||
inline void *operator new(size_t size, rust_dom &dom, | ||
memory_region::memory_region_type type) { | ||
return dom.malloc(size, type); | ||
} | ||
|
||
inline void *operator new[](size_t size, rust_dom &dom, | ||
memory_region::memory_region_type type) { | ||
return dom.malloc(size, type); | ||
} | ||
|
||
inline void operator delete(void *mem, rust_dom *dom) { | ||
dom->free(mem, memory_region::LOCAL); | ||
return; | ||
} | ||
|
||
inline void operator delete(void *mem, rust_dom *dom, | ||
memory_region::memory_region_type type) { | ||
dom->free(mem, type); | ||
return; | ||
} | ||
|
||
#endif /* MEMORY_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* | ||
*/ | ||
|
||
#include "rust_internal.h" | ||
#include "memory_region.h" | ||
|
||
#define TRACK_ALLOCATIONS | ||
|
||
memory_region::memory_region(rust_srv *srv, bool synchronized) : | ||
_srv(srv), _parent(NULL), _live_allocations(0), | ||
_synchronized(synchronized) { | ||
// Nop. | ||
} | ||
|
||
memory_region::memory_region(memory_region *parent) : | ||
_srv(parent->_srv), _parent(parent), _live_allocations(0), | ||
_synchronized(parent->_synchronized) { | ||
// Nop. | ||
} | ||
|
||
void memory_region::free(void *mem) { | ||
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__, ""); | ||
} | ||
_live_allocations--; | ||
_srv->free(mem); | ||
if (_synchronized) { _lock.unlock(); } | ||
|
||
} | ||
|
||
void * | ||
memory_region::realloc(void *mem, size_t size) { | ||
if (_synchronized) { _lock.lock(); } | ||
if (!mem) { | ||
_live_allocations++; | ||
} | ||
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(); } | ||
_live_allocations++; | ||
void *mem = _srv->malloc(size); | ||
#ifdef TRACK_ALLOCATIONS | ||
_allocation_list.append(mem); | ||
#endif | ||
if (_synchronized) { _lock.unlock(); } | ||
return mem; | ||
} | ||
|
||
void * | ||
memory_region::calloc(size_t size) { | ||
if (_synchronized) { _lock.lock(); } | ||
_live_allocations++; | ||
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 | ||
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* The Rust runtime uses memory regions to provide a primitive level of | ||
* memory management and isolation between tasks, and domains. | ||
* | ||
* TODO: Implement a custom lock-free malloc / free instead of relying solely | ||
* on the standard malloc / free. | ||
*/ | ||
|
||
#ifndef MEMORY_REGION_H | ||
#define MEMORY_REGION_H | ||
|
||
#include "sync/spin_lock.h" | ||
|
||
class rust_srv; | ||
|
||
class memory_region { | ||
private: | ||
rust_srv *_srv; | ||
memory_region *_parent; | ||
size_t _live_allocations; | ||
array_list<void *> _allocation_list; | ||
const bool _synchronized; | ||
spin_lock _lock; | ||
public: | ||
enum memory_region_type { | ||
LOCAL = 0x1, SYNCHRONIZED = 0x2 | ||
}; | ||
memory_region(rust_srv *srv, bool synchronized); | ||
memory_region(memory_region *parent); | ||
void *malloc(size_t size); | ||
void *calloc(size_t size); | ||
void *realloc(void *mem, size_t size); | ||
void free(void *mem); | ||
virtual ~memory_region(); | ||
}; | ||
|
||
#endif /* MEMORY_REGION_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.