Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 154 lines (123 sloc) 3.026 kB
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
1 #include "vm.hpp"
2 #include "fiber_stack.hpp"
3 #include "fiber_data.hpp"
4
794333e @evanphx Make stack pool and size configurable
evanphx authored
5 #include "configuration.hpp"
6
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
7 #include "bug.hpp"
8
ae50198 @evanphx Move lowlevel Fiber marking to the Thread level
evanphx authored
9 #include "gc/gc.hpp"
10
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
11 #include <stdlib.h>
bb09356 @dbussink Ensure that we tell Valgrind about our fiber stacks
dbussink authored
12 #ifdef HAVE_VALGRIND_H
13 #include <valgrind/valgrind.h>
14 #endif
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
15
16 namespace rubinius {
17
18 FiberStack::FiberStack(size_t size)
19 : address_(0)
20 , size_(size)
21 , refs_(0)
22 , user_(0)
a9359ec @dbussink Style improvements for VM code
dbussink authored
23 #ifdef HAVE_VALGRIND_H
24 , valgrind_id_(0)
25 #endif
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
26 {}
27
28 void FiberStack::allocate() {
29 assert(!address_);
30 address_ = malloc(size_);
bb09356 @dbussink Ensure that we tell Valgrind about our fiber stacks
dbussink authored
31 #ifdef HAVE_VALGRIND_H
32 valgrind_id_ = VALGRIND_STACK_REGISTER(address_, (char *)address_ + size_);
33 #endif
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
34 }
35
36 void FiberStack::free() {
37 if(!address_) return;
bb09356 @dbussink Ensure that we tell Valgrind about our fiber stacks
dbussink authored
38 #ifdef HAVE_VALGRIND_H
39 VALGRIND_STACK_DEREGISTER(valgrind_id_);
40 #endif
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
41 ::free(address_);
42 address_ = 0;
43 }
44
45 void FiberStack::flush(STATE) {
46 if(!user_) return;
47
48 // TODO assumes higher to lower stack growth.
49 user_->copy_to_heap(state);
50 }
51
52 void FiberStack::orphan(STATE, FiberData* user) {
75dce8b @evanphx Work out the kinks in the fiber stack setup
evanphx authored
53 if(user == user_) {
54 user_ = 0;
55 }
56
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
57 dec_ref();
58 }
59
c690b3c @evanphx Kill Fibers when their Thread dies
evanphx authored
60 FiberStacks::FiberStacks(VM* thread, SharedState& shared)
794333e @evanphx Make stack pool and size configurable
evanphx authored
61 : max_stacks_(shared.config.fiber_stacks)
62 , stack_size_(shared.config.fiber_stack_size)
c690b3c @evanphx Kill Fibers when their Thread dies
evanphx authored
63 , thread_(thread)
794333e @evanphx Make stack pool and size configurable
evanphx authored
64 , trampoline_(0)
65 {}
66
c690b3c @evanphx Kill Fibers when their Thread dies
evanphx authored
67 FiberStacks::~FiberStacks() {
68 for(Datas::iterator i = datas_.begin();
69 i != datas_.end();
70 ++i)
71 {
1d2e229 @dbussink Revert "Plug memory leak in fibers"
dbussink authored
72 (*i)->die();
c690b3c @evanphx Kill Fibers when their Thread dies
evanphx authored
73 }
74
75 for(Stacks::iterator i = stacks_.begin();
76 i != stacks_.end();
77 ++i)
78 {
79 i->free();
80 }
81 }
82
ae50198 @evanphx Move lowlevel Fiber marking to the Thread level
evanphx authored
83 void FiberStacks::gc_scan(GarbageCollector* gc) {
84 for(Datas::iterator i = datas_.begin();
85 i != datas_.end();
86 ++i)
87 {
88 FiberData* data = *i;
89 if(data->dead_p()) continue;
90
91 AddressDisplacement dis(data->data_offset(),
92 data->data_lower_bound(),
93 data->data_upper_bound());
94
95 if(CallFrame* cf = data->call_frame()) {
96 gc->walk_call_frame(cf, &dis);
97 }
98
99 gc->scan(data->variable_root_buffers(), false, &dis);
100 }
101 }
102
c98174b @evanphx Track the root fiber properly. Fixes #1568
evanphx authored
103 FiberData* FiberStacks::new_data(bool root) {
104 FiberData* data = new FiberData(thread_, root);
c690b3c @evanphx Kill Fibers when their Thread dies
evanphx authored
105 datas_.push_back(data);
106
107 return data;
108 }
109
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
110 FiberStack* FiberStacks::allocate() {
111 for(Stacks::iterator i = stacks_.begin();
112 i != stacks_.end();
113 ++i)
114 {
115 if(i->unused_p()) {
116 i->inc_ref();
117 return &*i;
118 }
119 }
120
121 FiberStack* stack = 0;
122
794333e @evanphx Make stack pool and size configurable
evanphx authored
123 if(stacks_.size() < max_stacks_) {
124 stacks_.push_back(FiberStack(stack_size_));
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
125 stack = &stacks_.back();
126
127 stack->allocate();
128 } else {
129 for(Stacks::iterator i = stacks_.begin();
130 i != stacks_.end();
131 ++i)
132 {
133 if(!stack || i->refs() < stack->refs()) {
134 stack = &*i;
135 }
136 }
137
138 assert(stack);
139 }
140
141 stack->inc_ref();
142
143 return stack;
144 }
75dce8b @evanphx Work out the kinks in the fiber stack setup
evanphx authored
145
146 void* FiberStacks::trampoline() {
147 if(trampoline_ == 0) {
148 trampoline_ = malloc(cTrampolineSize);
149 }
150
151 return trampoline_;
152 }
e38045b @evanphx Restructure how fiber stacks are allocated
evanphx authored
153 }
Something went wrong with that request. Please try again.