Skip to content

HTTPS clone URL

Subversion checkout URL

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