Permalink
Browse files

More memory correctness

I was using auto_ptr<char> with new[] which is incorrect. So I switched
to a vector to manage the stack, but it seems that performance took a
hit here. That should be solved with pooling though.
  • Loading branch information...
1 parent 6a77a26 commit 911ecb22a962041292c62168060a536058f1a864 @laverdet committed Jan 18, 2011
Showing with 16 additions and 7 deletions.
  1. +1 −1 Makefile
  2. +8 −4 coroutine.cc
  3. +7 −2 coroutine.h
View
@@ -7,7 +7,7 @@ CPPFLAGS = -Wall -I$(NODE_PREFIX)/include -I$(NODE_PREFIX)/include/node
ifdef DEBUG
CPPFLAGS += -ggdb -O0
else
- CPPFLAGS += -g -O3
+ CPPFLAGS += -g -O3 -minline-all-stringops
endif
ifeq ($(NODE_BITS), 32)
View
@@ -9,7 +9,11 @@
#include <stack>
#include <vector>
-#define STACK_SIZE (1024 * 1024 * 2)
+// TODO: It's clear I'm missing something with respects to ResourceConstraints.set_stack_limit.
+// No matter what I give it, it seems the stack size is always the same. And then if the actual
+// amount of memory allocated for the stack is too small it seg faults. It seems 265k is as low as
+// I can go without fixing the underlying bug.
+#define STACK_SIZE (1024 * 265)
#include <iostream>
using namespace std;
@@ -157,10 +161,10 @@ Coroutine::Coroutine(Thread& t, size_t id) : thread(t), id(id) {}
Coroutine::Coroutine(Thread& t, size_t id, entry_t& entry, void* arg) :
thread(t),
id(id),
- stack(new char[STACK_SIZE]) {
+ stack(STACK_SIZE) {
getcontext(&context);
context.uc_stack.ss_size = STACK_SIZE;
- context.uc_stack.ss_sp = stack.get();
+ context.uc_stack.ss_sp = &stack[0];
makecontext(&context, (void(*)(void))trampoline, 3, this, entry, arg);
}
@@ -186,7 +190,7 @@ Coroutine& Coroutine::new_fiber(entry_t* entry, void* arg) {
}
void* Coroutine::bottom() const {
- return stack.get() - STACK_SIZE;
+ return (char*)&stack[0] - STACK_SIZE;
}
size_t Coroutine::size() const {
View
@@ -1,20 +1,25 @@
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif
+
#include <stdlib.h>
#include <ucontext.h>
-#include <memory>
+#include <ext/pool_allocator.h>
+#include <vector>
class Coroutine {
public:
friend class Thread;
typedef void(entry_t)(void*);
private:
+ // vector<char> will 0 out the memory first which is not necessary; this hack lets us get
+ // around that, as there is no constructor.
+ struct char_noinit { char x; };
class Thread& thread;
size_t id;
ucontext_t context;
- std::auto_ptr<char> stack;
+ std::vector<char_noinit, __gnu_cxx::__pool_alloc<char_noinit> > stack;
static void trampoline(Coroutine& that, entry_t& entry, void* arg);
~Coroutine() {}

0 comments on commit 911ecb2

Please sign in to comment.