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

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

Issue 8588040: Add a mid-sized integration test for the Dart Embedding Api which (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 "vm/isolate.h" 7 #include "vm/isolate.h"
8 #include "vm/thread.h" 8 #include "vm/thread.h"
9 #include "vm/utils.h" 9 #include "vm/utils.h"
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 // TODO(iposva): Use an approved hashing function to have less predictable 68 // TODO(iposva): Use an approved hashing function to have less predictable
69 // port ids, or make them not accessible from Dart code or both. 69 // port ids, or make them not accessible from Dart code or both.
70 next_port_++; 70 next_port_++;
71 } while (FindPort(next_port_) >= 0); 71 } while (FindPort(next_port_) >= 0);
72 72
73 ASSERT(result != 0); 73 ASSERT(result != 0);
74 return result; 74 return result;
75 } 75 }
76 76
77 77
78 void PortMap::SetLive(Dart_Port port) {
79 MutexLocker ml(mutex_);
80 intptr_t index = FindPort(port);
81 ASSERT(index >= 0);
82 map_[index].live = true;
83 map_[index].isolate->increment_live_ports();
84 }
85
86
78 void PortMap::MaintainInvariants() { 87 void PortMap::MaintainInvariants() {
79 intptr_t empty = capacity_ - used_ - deleted_; 88 intptr_t empty = capacity_ - used_ - deleted_;
80 if (used_ > ((capacity_ / 4) * 3)) { 89 if (used_ > ((capacity_ / 4) * 3)) {
81 // Grow the port map. 90 // Grow the port map.
82 Rehash(capacity_ * 2); 91 Rehash(capacity_ * 2);
83 } else if (empty < deleted_) { 92 } else if (empty < deleted_) {
84 // Rehash without growing the table to flush the deleted slots out of the 93 // Rehash without growing the table to flush the deleted slots out of the
85 // map. 94 // map.
86 Rehash(capacity_); 95 Rehash(capacity_);
87 } 96 }
88 } 97 }
89 98
90 99
91 Dart_Port PortMap::CreatePort() { 100 Dart_Port PortMap::CreatePort() {
92 Isolate* isolate = Isolate::Current(); 101 Isolate* isolate = Isolate::Current();
93
94 MutexLocker ml(mutex_); 102 MutexLocker ml(mutex_);
95 103
96 Entry entry; 104 Entry entry;
97 entry.port = AllocatePort(); 105 entry.port = AllocatePort();
98 entry.isolate = isolate; 106 entry.isolate = isolate;
107 entry.live = false;
99 108
100 // Search for the first unused slot. Make use of the knowledge that here is 109 // Search for the first unused slot. Make use of the knowledge that here is
101 // currently no port with this id in the port map. 110 // currently no port with this id in the port map.
102 ASSERT(FindPort(entry.port) < 0); 111 ASSERT(FindPort(entry.port) < 0);
103 intptr_t index = entry.port % capacity_; 112 intptr_t index = entry.port % capacity_;
104 Entry cur = map_[index]; 113 Entry cur = map_[index];
105 // Stop the search at the first found unused (free or deleted) slot. 114 // Stop the search at the first found unused (free or deleted) slot.
106 while (cur.port != 0) { 115 while (cur.port != 0) {
107 index = (index + 1) % capacity_; 116 index = (index + 1) % capacity_;
108 cur = map_[index]; 117 cur = map_[index];
109 } 118 }
110 119
111 // Insert the newly created port at the index. 120 // Insert the newly created port at the index.
112 ASSERT(index >= 0); 121 ASSERT(index >= 0);
113 ASSERT(index < capacity_); 122 ASSERT(index < capacity_);
114 ASSERT(map_[index].port == 0); 123 ASSERT(map_[index].port == 0);
115 ASSERT((map_[index].isolate == NULL) || 124 ASSERT((map_[index].isolate == NULL) ||
116 (map_[index].isolate == deleted_entry_)); 125 (map_[index].isolate == deleted_entry_));
117 if (map_[index].isolate == deleted_entry_) { 126 if (map_[index].isolate == deleted_entry_) {
118 // Consuming a deleted entry. 127 // Consuming a deleted entry.
119 deleted_--; 128 deleted_--;
120 } 129 }
121 map_[index] = entry; 130 map_[index] = entry;
122 isolate->increment_active_ports(); 131 isolate->increment_num_ports();
123 132
124 // Increment number of used slots and grow if necessary. 133 // Increment number of used slots and grow if necessary.
125 used_++; 134 used_++;
126 MaintainInvariants(); 135 MaintainInvariants();
127 136
128 return entry.port; 137 return entry.port;
129 } 138 }
130 139
131 140
132 void PortMap::ClosePort(Dart_Port port) { 141 void PortMap::ClosePort(Dart_Port port) {
133 Isolate* isolate = Isolate::Current(); 142 Isolate* isolate = Isolate::Current();
134 { 143 {
135 MutexLocker ml(mutex_); 144 MutexLocker ml(mutex_);
136 intptr_t index = FindPort(port); 145 intptr_t index = FindPort(port);
137 if (index < 0) { 146 if (index < 0) {
138 return; 147 return;
139 } 148 }
140 ASSERT(index < capacity_); 149 ASSERT(index < capacity_);
141 ASSERT(map_[index].port != 0); 150 ASSERT(map_[index].port != 0);
142 ASSERT(map_[index].isolate == isolate); 151 ASSERT(map_[index].isolate == isolate);
143 // Before releasing the lock mark the slot in the map as deleted. This makes 152 // Before releasing the lock mark the slot in the map as deleted. This makes
144 // it possible to release the port map lock before flushing all of its 153 // it possible to release the port map lock before flushing all of its
145 // pending messages below. 154 // pending messages below.
146 map_[index].port = 0; 155 map_[index].port = 0;
147 map_[index].isolate = deleted_entry_; 156 map_[index].isolate = deleted_entry_;
148 isolate->decrement_active_ports(); 157 isolate->decrement_num_ports();
158 if (map_[index].live) {
159 isolate->decrement_live_ports();
160 }
149 161
150 used_--; 162 used_--;
151 deleted_++; 163 deleted_++;
152 MaintainInvariants(); 164 MaintainInvariants();
153 } 165 }
154 166
155 // Notify the embedder that this port is closed. 167 // Notify the embedder that this port is closed.
156 Dart_ClosePortCallback callback = isolate->close_port_callback(); 168 Dart_ClosePortCallback callback = isolate->close_port_callback();
157 ASSERT(callback); 169 ASSERT(callback);
158 ASSERT(port != kCloseAllPorts); 170 ASSERT(port != kCloseAllPorts);
159 (*callback)(isolate, port); 171 (*callback)(isolate, port);
160 } 172 }
161 173
162 174
163 void PortMap::ClosePorts() { 175 void PortMap::ClosePorts() {
164 Isolate* isolate = Isolate::Current(); 176 Isolate* isolate = Isolate::Current();
165 { 177 {
166 MutexLocker ml(mutex_); 178 MutexLocker ml(mutex_);
167 for (intptr_t i = 0; i < capacity_; i++) { 179 for (intptr_t i = 0; i < capacity_; i++) {
168 if (map_[i].isolate == isolate) { 180 if (map_[i].isolate == isolate) {
169 // Mark the slot as deleted. 181 // Mark the slot as deleted.
170 map_[i].port = 0; 182 map_[i].port = 0;
171 map_[i].isolate = deleted_entry_; 183 map_[i].isolate = deleted_entry_;
172 isolate->decrement_active_ports(); 184 isolate->decrement_num_ports();
173 185
174 used_--; 186 used_--;
175 deleted_++; 187 deleted_++;
176 } 188 }
177 } 189 }
178 MaintainInvariants(); 190 MaintainInvariants();
179 } 191 }
180 192
181 // Notify the embedder that all ports are closed. 193 // Notify the embedder that all ports are closed.
182 Dart_ClosePortCallback callback = isolate->close_port_callback(); 194 Dart_ClosePortCallback callback = isolate->close_port_callback();
183 ASSERT(callback); 195 ASSERT(callback);
184 (*callback)(isolate, kCloseAllPorts); 196 (*callback)(isolate, kCloseAllPorts);
185 } 197 }
186 198
187 199
188 bool PortMap::IsActivePort(Dart_Port port) {
189 MutexLocker ml(mutex_);
190 return (FindPort(port) >= 0);
191 }
192
193
194 bool PortMap::PostMessage(Dart_Port dest_port, 200 bool PortMap::PostMessage(Dart_Port dest_port,
195 Dart_Port reply_port, 201 Dart_Port reply_port,
196 Dart_Message message) { 202 Dart_Message message) {
197 mutex_->Lock(); 203 mutex_->Lock();
198 intptr_t index = FindPort(dest_port); 204 intptr_t index = FindPort(dest_port);
199 if (index < 0) { 205 if (index < 0) {
200 free(message); 206 free(message);
201 mutex_->Unlock(); 207 mutex_->Unlock();
202 return false; 208 return false;
203 } 209 }
(...skipping 21 matching lines...) Expand all
225 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity)); 231 ASSERT(Utils::IsPowerOfTwo(kInitialCapacity));
226 map_ = new Entry[kInitialCapacity]; 232 map_ = new Entry[kInitialCapacity];
227 memset(map_, 0, kInitialCapacity * sizeof(Entry)); 233 memset(map_, 0, kInitialCapacity * sizeof(Entry));
228 capacity_ = kInitialCapacity; 234 capacity_ = kInitialCapacity;
229 used_ = 0; 235 used_ = 0;
230 deleted_ = 0; 236 deleted_ = 0;
231 } 237 }
232 238
233 239
234 } // namespace dart 240 } // 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