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

Side by Side Diff: src/v8threads.cc

Issue 14483: Fix issue 142 (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 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
OLDNEW
1 // Copyright 2008 the V8 project authors. All rights reserved. 1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 for (ThreadState* state = ThreadState::FirstInUse(); 262 for (ThreadState* state = ThreadState::FirstInUse();
263 state != NULL; 263 state != NULL;
264 state = state->Next()) { 264 state = state->Next()) {
265 char* data = state->data(); 265 char* data = state->data();
266 data += HandleScopeImplementer::ArchiveSpacePerThread(); 266 data += HandleScopeImplementer::ArchiveSpacePerThread();
267 Top::MarkCompactEpilogue(data); 267 Top::MarkCompactEpilogue(data);
268 } 268 }
269 } 269 }
270 270
271 271
272 // This is the ContextSwitcher singleton. There is at most a single thread
273 // running which delivers preemption events to V8 threads.
274 ContextSwitcher* ContextSwitcher::singleton_ = NULL;
275
276
272 ContextSwitcher::ContextSwitcher(int every_n_ms) 277 ContextSwitcher::ContextSwitcher(int every_n_ms)
273 : preemption_semaphore_(OS::CreateSemaphore(0)), 278 : keep_going_(true),
274 keep_going_(true),
275 sleep_ms_(every_n_ms) { 279 sleep_ms_(every_n_ms) {
276 } 280 }
277 281
278 282
279 static v8::internal::ContextSwitcher* switcher; 283 // Set the scheduling interval of V8 threads. This function starts the
280 284 // ContextSwitcher thread if needed.
281
282 void ContextSwitcher::StartPreemption(int every_n_ms) { 285 void ContextSwitcher::StartPreemption(int every_n_ms) {
283 ASSERT(Locker::IsLocked()); 286 ASSERT(Locker::IsLocked());
284 if (switcher == NULL) { 287 if (singleton_ == NULL) {
285 switcher = new ContextSwitcher(every_n_ms); 288 // If the ContextSwitcher thread is not running at the moment start it now.
286 switcher->Start(); 289 singleton_ = new ContextSwitcher(every_n_ms);
290 singleton_->Start();
287 } else { 291 } else {
288 switcher->sleep_ms_ = every_n_ms; 292 // ContextSwitcher thread is already running, so we just change the
293 // scheduling interval.
294 singleton_->sleep_ms_ = every_n_ms;
289 } 295 }
290 } 296 }
291 297
292 298
299 // Disable preemption of V8 threads. If multiple threads want to use V8 they
300 // must cooperatively schedule amongst them from this point on.
293 void ContextSwitcher::StopPreemption() { 301 void ContextSwitcher::StopPreemption() {
294 ASSERT(Locker::IsLocked()); 302 ASSERT(Locker::IsLocked());
295 if (switcher != NULL) { 303 if (singleton_ != NULL) {
296 switcher->Stop(); 304 // The ContextSwitcher thread is running. We need to stop it and release
297 delete(switcher); 305 // its resources.
298 switcher = NULL; 306 singleton_->keep_going_ = false;
307 singleton_->Join(); // Wait for the ContextSwitcher thread to exit.
308 // Thread has exited, now we can delete it.
309 delete(singleton_);
310 singleton_ = NULL;
Erik Corry 2008/12/17 14:30:07 Perhaps here we should clear a pending preemption.
iposva 2008/12/17 17:39:24 I disagree. To the running thread a pending preemp
299 } 311 }
300 } 312 }
301 313
302 314
315 // Main loop of the ContextSwitcher thread: Preempt the currently running V8
316 // thread at regular intervals.
303 void ContextSwitcher::Run() { 317 void ContextSwitcher::Run() {
304 while (keep_going_) { 318 while (keep_going_) {
305 OS::Sleep(sleep_ms_); 319 OS::Sleep(sleep_ms_);
306 StackGuard::Preempt(); 320 StackGuard::Preempt();
307 WaitForPreemption();
308 } 321 }
309 } 322 }
310 323
311 324
312 void ContextSwitcher::Stop() { 325 // Acknowledge the preemption by the receiving thread.
326 void ContextSwitcher::PreemptionReceived() {
313 ASSERT(Locker::IsLocked()); 327 ASSERT(Locker::IsLocked());
314 keep_going_ = false; 328 // There is currently no accounting being done for this. But could be in the
315 preemption_semaphore_->Signal(); 329 // future, which is why we leave this in.
316 Join();
317 } 330 }
318 331
319 332
320 void ContextSwitcher::WaitForPreemption() {
321 preemption_semaphore_->Wait();
322 }
323
324
325 void ContextSwitcher::PreemptionReceived() {
326 ASSERT(Locker::IsLocked());
327 switcher->preemption_semaphore_->Signal();
328 }
329
330
331 } // namespace internal 333 } // namespace internal
332 } // namespace v8 334 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698