-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Warn when running out of memory instead of segfaulting #251
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -121,11 +121,23 @@ class Sorter { | |
_reads_capa = 1024; | ||
auto sz = BamRead.sizeof * _reads_capa; | ||
_reads = cast(BamRead*)std.c.stdlib.malloc(sz); | ||
if (_reads is null) { | ||
throw new Exception("alloc failed: no space for read pointers"); | ||
} | ||
} | ||
|
||
void clear() { | ||
_used = 0; | ||
_n_reads = 0; | ||
if (_low_memory) { | ||
auto realloc_storage = cast(ubyte*)std.c.stdlib.realloc(read_storage, max_sz / 2); | ||
if (realloc_storage !is null) { | ||
max_sz /= 2; | ||
read_storage = realloc_storage; | ||
stderr.writeln("reduced maximum buffer size to ", max_sz); | ||
} | ||
_low_memory = false; | ||
} | ||
} | ||
|
||
void fill(R)(R* reads) { | ||
|
@@ -135,11 +147,18 @@ class Sorter { | |
if (len + _used > max_sz) | ||
break; | ||
|
||
std.c.string.memcpy(read_storage + _used, read.raw_data.ptr, len); | ||
if (_n_reads == _reads_capa) { | ||
_reads_capa *= 2; | ||
_reads = cast(BamRead*)std.c.stdlib.realloc(_reads, _reads_capa * BamRead.sizeof); | ||
auto realloc_reads = cast(BamRead*)std.c.stdlib.realloc(_reads, 2 * _reads_capa * BamRead.sizeof); | ||
if (realloc_reads is null) { | ||
_low_memory = true; | ||
stderr.writeln("realloc failed: system low on memory, limited to ", _reads_capa, " reads in buffer"); | ||
break; | ||
} else { | ||
_reads_capa *= 2; | ||
_reads = realloc_reads; | ||
} | ||
} | ||
std.c.string.memcpy(read_storage + _used, read.raw_data.ptr, len); | ||
_reads[_n_reads].raw_data = read_storage[_used .. _used + len]; | ||
_reads[_n_reads].associateWithReader(read.reader); | ||
|
||
|
@@ -154,7 +173,13 @@ class Sorter { | |
auto len = read.raw_data.length; | ||
assert(len > max_sz); | ||
_n_reads = 1; | ||
read_storage = cast(ubyte*)std.c.stdlib.realloc(read_storage, len); | ||
auto realloc_storage = cast(ubyte*)std.c.stdlib.realloc(read_storage, len); | ||
if (realloc_storage is null) { | ||
throw new Exception("realloc failed: not enough memory for read"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are already trying to grow the storage, think there's nothing we can do here if it fails, so throw. |
||
} else { | ||
read_storage = realloc_storage; | ||
max_sz = len; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
_used = len; | ||
read_storage[0 .. len] = read.raw_data[]; | ||
_reads[0].raw_data = read_storage[0 .. _used]; | ||
|
@@ -175,6 +200,7 @@ class Sorter { | |
|
||
ubyte* read_storage; | ||
size_t _used; | ||
bool _low_memory; | ||
} | ||
|
||
static BamRead[] sortChunk(size_t n, BamRead[] chunk, TaskPool task_pool) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically, this
realloc
can also fail (could reallocate via allocate/copy/free). I choose not to throw an exception here, but to keep printing errors. This is a situation in which we can proceed, but sub-optimally, and cannot automatically do anything to improve things. Spamming the user probably highlights the problem but results should still be correct.