Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(324)

Side by Side Diff: runtime/vm/port.cc

Issue 456983002: Refactor isolate startup code in preparation for making isolate spawning more truly non-blocking. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/port.h ('k') | runtime/vm/port_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/port.h" 5 #include "vm/port.h"
6 6
7 #include "platform/utils.h" 7 #include "platform/utils.h"
8 #include "vm/dart_api_impl.h" 8 #include "vm/dart_api_impl.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/lockers.h" 10 #include "vm/lockers.h"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 new_ports[new_index] = entry; 56 new_ports[new_index] = entry;
57 } 57 }
58 } 58 }
59 delete[] map_; 59 delete[] map_;
60 map_ = new_ports; 60 map_ = new_ports;
61 capacity_ = new_capacity; 61 capacity_ = new_capacity;
62 deleted_ = 0; 62 deleted_ = 0;
63 } 63 }
64 64
65 65
66 const char* PortMap::PortStateString(PortState kind) {
67 switch (kind) {
68 case kNewPort:
69 return "new";
70 case kLivePort:
71 return "live";
72 case kControlPort:
73 return "control";
74 default:
75 UNREACHABLE();
76 return "UNKNOWN";
77 }
78 }
79
80
66 Dart_Port PortMap::AllocatePort() { 81 Dart_Port PortMap::AllocatePort() {
67 const Dart_Port kMASK = 0x3fffffff; 82 const Dart_Port kMASK = 0x3fffffff;
68 Dart_Port result = prng_->NextUInt32() & kMASK; 83 Dart_Port result = prng_->NextUInt32() & kMASK;
69 84
70 // Keep getting new values while we have an illegal port number or the port 85 // Keep getting new values while we have an illegal port number or the port
71 // number is already in use. 86 // number is already in use.
72 while ((result == 0) || (FindPort(result) >= 0)) { 87 while ((result == 0) || (FindPort(result) >= 0)) {
73 result = prng_->NextUInt32() & kMASK; 88 result = prng_->NextUInt32() & kMASK;
74 } 89 }
75 90
76 ASSERT(result != 0); 91 ASSERT(result != 0);
77 ASSERT(FindPort(result) < 0); 92 ASSERT(FindPort(result) < 0);
78 return result; 93 return result;
79 } 94 }
80 95
81 96
82 void PortMap::SetLive(Dart_Port port) { 97 void PortMap::SetPortState(Dart_Port port, PortState state) {
83 MutexLocker ml(mutex_); 98 MutexLocker ml(mutex_);
84 intptr_t index = FindPort(port); 99 intptr_t index = FindPort(port);
85 ASSERT(index >= 0); 100 ASSERT(index >= 0);
86 map_[index].live = true; 101 PortState old_state = map_[index].state;
87 map_[index].handler->increment_live_ports(); 102 ASSERT(old_state == kNewPort);
103 map_[index].state = state;
104 if (state == kLivePort) {
105 map_[index].handler->increment_live_ports();
106 }
88 if (FLAG_trace_isolates) { 107 if (FLAG_trace_isolates) {
89 OS::Print("[^] Live port: \n" 108 OS::Print("[^] Port (%s) -> (%s): \n"
90 "\thandler: %s\n" 109 "\thandler: %s\n"
91 "\tport: %" Pd64 "\n", 110 "\tport: %" Pd64 "\n",
111 PortStateString(old_state), PortStateString(state),
92 map_[index].handler->name(), port); 112 map_[index].handler->name(), port);
93 } 113 }
94 } 114 }
95 115
96 116
97 void PortMap::MaintainInvariants() { 117 void PortMap::MaintainInvariants() {
98 intptr_t empty = capacity_ - used_ - deleted_; 118 intptr_t empty = capacity_ - used_ - deleted_;
99 if (used_ > ((capacity_ / 4) * 3)) { 119 if (used_ > ((capacity_ / 4) * 3)) {
100 // Grow the port map. 120 // Grow the port map.
101 Rehash(capacity_ * 2); 121 Rehash(capacity_ * 2);
102 } else if (empty < deleted_) { 122 } else if (empty < deleted_) {
103 // Rehash without growing the table to flush the deleted slots out of the 123 // Rehash without growing the table to flush the deleted slots out of the
104 // map. 124 // map.
105 Rehash(capacity_); 125 Rehash(capacity_);
106 } 126 }
107 } 127 }
108 128
109 129
110 Dart_Port PortMap::CreatePort(MessageHandler* handler) { 130 Dart_Port PortMap::CreatePort(MessageHandler* handler) {
111 ASSERT(handler != NULL); 131 ASSERT(handler != NULL);
112 MutexLocker ml(mutex_); 132 MutexLocker ml(mutex_);
113 #if defined(DEBUG) 133 #if defined(DEBUG)
114 handler->CheckAccess(); 134 handler->CheckAccess();
115 #endif 135 #endif
116 136
117 Entry entry; 137 Entry entry;
118 entry.port = AllocatePort(); 138 entry.port = AllocatePort();
119 entry.handler = handler; 139 entry.handler = handler;
120 entry.live = false; 140 entry.state = kNewPort;
121 141
122 // Search for the first unused slot. Make use of the knowledge that here is 142 // Search for the first unused slot. Make use of the knowledge that here is
123 // currently no port with this id in the port map. 143 // currently no port with this id in the port map.
124 ASSERT(FindPort(entry.port) < 0); 144 ASSERT(FindPort(entry.port) < 0);
125 intptr_t index = entry.port % capacity_; 145 intptr_t index = entry.port % capacity_;
126 Entry cur = map_[index]; 146 Entry cur = map_[index];
127 // Stop the search at the first found unused (free or deleted) slot. 147 // Stop the search at the first found unused (free or deleted) slot.
128 while (cur.port != 0) { 148 while (cur.port != 0) {
129 index = (index + 1) % capacity_; 149 index = (index + 1) % capacity_;
130 cur = map_[index]; 150 cur = map_[index];
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 192
173 handler = map_[index].handler; 193 handler = map_[index].handler;
174 #if defined(DEBUG) 194 #if defined(DEBUG)
175 handler->CheckAccess(); 195 handler->CheckAccess();
176 #endif 196 #endif
177 // Before releasing the lock mark the slot in the map as deleted. This makes 197 // Before releasing the lock mark the slot in the map as deleted. This makes
178 // it possible to release the port map lock before flushing all of its 198 // it possible to release the port map lock before flushing all of its
179 // pending messages below. 199 // pending messages below.
180 map_[index].port = 0; 200 map_[index].port = 0;
181 map_[index].handler = deleted_entry_; 201 map_[index].handler = deleted_entry_;
182 if (map_[index].live) { 202 if (map_[index].state == kLivePort) {
183 handler->decrement_live_ports(); 203 handler->decrement_live_ports();
184 } 204 }
185 205
186 used_--; 206 used_--;
187 deleted_++; 207 deleted_++;
188 MaintainInvariants(); 208 MaintainInvariants();
189 } 209 }
190 handler->ClosePort(port); 210 handler->ClosePort(port);
191 if (!handler->HasLivePorts() && handler->OwnedByPortMap()) { 211 if (!handler->HasLivePorts() && handler->OwnedByPortMap()) {
192 delete handler; 212 delete handler;
193 } 213 }
194 return true; 214 return true;
195 } 215 }
196 216
197 217
198 void PortMap::ClosePorts(MessageHandler* handler) { 218 void PortMap::ClosePorts(MessageHandler* handler) {
199 { 219 {
200 MutexLocker ml(mutex_); 220 MutexLocker ml(mutex_);
201 for (intptr_t i = 0; i < capacity_; i++) { 221 for (intptr_t i = 0; i < capacity_; i++) {
202 if (map_[i].handler == handler) { 222 if (map_[i].handler == handler) {
203 // Mark the slot as deleted. 223 // Mark the slot as deleted.
204 map_[i].port = 0; 224 map_[i].port = 0;
205 map_[i].handler = deleted_entry_; 225 map_[i].handler = deleted_entry_;
206 if (map_[i].live) { 226 if (map_[i].state == kLivePort) {
207 handler->decrement_live_ports(); 227 handler->decrement_live_ports();
208 } 228 }
209 used_--; 229 used_--;
210 deleted_++; 230 deleted_++;
211 } 231 }
212 } 232 }
213 MaintainInvariants(); 233 MaintainInvariants();
214 } 234 }
215 handler->CloseAllPorts(); 235 handler->CloseAllPorts();
216 } 236 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 // TODO(iposva): Verify whether we want to keep exponentially growing. 287 // TODO(iposva): Verify whether we want to keep exponentially growing.
268 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity)); 288 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity));
269 map_ = new Entry[kInitialCapacity]; 289 map_ = new Entry[kInitialCapacity];
270 memset(map_, 0, kInitialCapacity * sizeof(Entry)); 290 memset(map_, 0, kInitialCapacity * sizeof(Entry));
271 capacity_ = kInitialCapacity; 291 capacity_ = kInitialCapacity;
272 used_ = 0; 292 used_ = 0;
273 deleted_ = 0; 293 deleted_ = 0;
274 } 294 }
275 295
276 } // namespace dart 296 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/port.h ('k') | runtime/vm/port_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698