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

Side by Side Diff: Source/heap/ThreadState.cpp

Issue 100433005: [oilpan] Rename PauseScope to SafePointScope (Closed) Base URL: svn://svn.chromium.org/blink/branches/oilpan
Patch Set: Created 7 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 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr _t*); 52 typedef void (*PushAllRegistersCallback)(SafePointBarrier*, ThreadState*, intptr _t*);
53 extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegiste rsCallback); 53 extern "C" void pushAllRegisters(SafePointBarrier*, ThreadState*, PushAllRegiste rsCallback);
54 54
55 static Mutex& threadAttachMutex() 55 static Mutex& threadAttachMutex()
56 { 56 {
57 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); 57 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
58 return mutex; 58 return mutex;
59 } 59 }
60 60
61 static void parkAfterPushRegisters(SafePointBarrier*, ThreadState*, intptr_t* st ackEnd); 61 static void parkAfterPushRegisters(SafePointBarrier*, ThreadState*, intptr_t* st ackEnd);
62 static void notifyPausedAfterPushRegisters(SafePointBarrier*, ThreadState*, intp tr_t* stackEnd); 62 static void enterSafePointAfterPushRegisters(SafePointBarrier*, ThreadState*, in tptr_t* stackEnd);
63 63
64 class SafePointBarrier { 64 class SafePointBarrier {
65 public: 65 public:
66 SafePointBarrier() 66 SafePointBarrier()
67 { 67 {
68 NoBarrier_Store(&m_unparkedThreadCount, 0); 68 NoBarrier_Store(&m_unparkedThreadCount, 0);
69 Release_Store(&m_canResume, 1); 69 Release_Store(&m_canResume, 1);
70 } 70 }
71 71
72 ~SafePointBarrier() 72 ~SafePointBarrier()
73 { 73 {
74 } 74 }
75 75
76 // Request other attached and non-paused threads to park themselves on safep oints. 76 // Request other attached and not-in-safe-point threads to park themselves o n safepoints.
Mads Ager (chromium) 2013/12/05 09:22:24 Request other attached threads that are not at saf
haraken 2013/12/05 09:37:40 Done.
77 void parkOthers(ThreadState::StackState stackState) 77 void parkOthers(ThreadState::StackState stackState)
78 { 78 {
79 // Mark current thread as paused before attempting to lock the threadAtt achMutex(). This will 79 // Enter safe point before attempting to lock the threadAttachMutex(). T his will
80 // allow to avoid dead-lock if two threads arrive into parkOthers() simu ltaneously. 80 // allow to avoid dead-lock if two threads arrive into parkOthers() simu ltaneously.
81 ThreadState::Current()->paused(stackState); 81 ThreadState::Current()->enterSafePoint(stackState);
82 82
83 // Lock threadAttachMutex() to prevent threads from attaching. 83 // Lock threadAttachMutex() to prevent threads from attaching.
84 threadAttachMutex().lock(); 84 threadAttachMutex().lock();
85 85
86 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThre ads(); 86 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThre ads();
87 87
88 MutexLocker locker(m_mutex); 88 MutexLocker locker(m_mutex);
89 NoBarrier_AtomicIncrement(&m_unparkedThreadCount, threads.size()); 89 NoBarrier_AtomicIncrement(&m_unparkedThreadCount, threads.size());
90 Release_Store(&m_canResume, 0); 90 Release_Store(&m_canResume, 0);
91 91
92 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) { 92 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
93 if ((*it)->interruptor()) 93 if ((*it)->interruptor())
94 (*it)->interruptor()->requestInterrupt(); 94 (*it)->interruptor()->requestInterrupt();
95 } 95 }
96 96
97 while (NoBarrier_Load(&m_unparkedThreadCount) > 0) 97 while (NoBarrier_Load(&m_unparkedThreadCount) > 0)
98 m_parked.wait(m_mutex); 98 m_parked.wait(m_mutex);
99 } 99 }
100 100
101 void resumeOthers() 101 void resumeOthers()
102 { 102 {
103 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThre ads(); 103 ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThre ads();
104 NoBarrier_AtomicIncrement(&m_unparkedThreadCount, -threads.size()); 104 NoBarrier_AtomicIncrement(&m_unparkedThreadCount, -threads.size());
105 Release_Store(&m_canResume, 1); 105 Release_Store(&m_canResume, 1);
106 { 106 {
107 // FIXME(oilpan) resumed threads will all contend for 107 // FIXME(oilpan): Resumed threads will all contend for
108 // m_mutex just to unlock it later which is a waste of 108 // m_mutex just to unlock it later which is a waste of
109 // resources. 109 // resources.
110 MutexLocker locker(m_mutex); 110 MutexLocker locker(m_mutex);
111 m_resume.broadcast(); 111 m_resume.broadcast();
112 } 112 }
113 113
114 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) { 114 for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
115 if ((*it)->interruptor()) 115 if ((*it)->interruptor())
116 (*it)->interruptor()->clearInterrupt(); 116 (*it)->interruptor()->clearInterrupt();
117 } 117 }
118 118
119 threadAttachMutex().unlock(); 119 threadAttachMutex().unlock();
120 ThreadState::Current()->resumed(); 120 ThreadState::Current()->leaveSafePoint();
121 } 121 }
122 122
123 void doPark(ThreadState* state, intptr_t* stackEnd) 123 void doPark(ThreadState* state, intptr_t* stackEnd)
124 { 124 {
125 state->recordStackEnd(stackEnd); 125 state->recordStackEnd(stackEnd);
126 MutexLocker locker(m_mutex); 126 MutexLocker locker(m_mutex);
127 if (!NoBarrier_AtomicIncrement(&m_unparkedThreadCount, -1)) 127 if (!NoBarrier_AtomicIncrement(&m_unparkedThreadCount, -1))
128 m_parked.signal(); 128 m_parked.signal();
129 while (!NoBarrier_Load(&m_canResume)) 129 while (!NoBarrier_Load(&m_canResume))
130 m_resume.wait(m_mutex); 130 m_resume.wait(m_mutex);
131 NoBarrier_AtomicIncrement(&m_unparkedThreadCount, 1); 131 NoBarrier_AtomicIncrement(&m_unparkedThreadCount, 1);
132 } 132 }
133 133
134 void checkAndPark(ThreadState* state) 134 void checkAndPark(ThreadState* state)
135 { 135 {
136 ASSERT(!state->isSweepInProgress()); 136 ASSERT(!state->isSweepInProgress());
137 if (!Acquire_Load(&m_canResume)) { 137 if (!Acquire_Load(&m_canResume)) {
138 pushAllRegisters(this, state, parkAfterPushRegisters); 138 pushAllRegisters(this, state, parkAfterPushRegisters);
139 state->executePendingAction(); 139 state->executePendingAction();
140 } 140 }
141 } 141 }
142 142
143 void doNotifyPaused(ThreadState* state, intptr_t* stackEnd) 143 void doEnterSafePoint(ThreadState* state, intptr_t* stackEnd)
144 { 144 {
145 state->recordStackEnd(stackEnd); 145 state->recordStackEnd(stackEnd);
146 if (!NoBarrier_AtomicIncrement(&m_unparkedThreadCount, -1)) { 146 if (!NoBarrier_AtomicIncrement(&m_unparkedThreadCount, -1)) {
147 MutexLocker locker(m_mutex); 147 MutexLocker locker(m_mutex);
148 m_parked.signal(); // Safe point reached. 148 m_parked.signal(); // Safe point reached.
149 } 149 }
150 } 150 }
151 151
152 void notifyPaused(ThreadState* state) 152 void enterSafePoint(ThreadState* state)
153 { 153 {
154 ASSERT(!state->isSweepInProgress()); 154 ASSERT(!state->isSweepInProgress());
155 pushAllRegisters(this, state, notifyPausedAfterPushRegisters); 155 pushAllRegisters(this, state, enterSafePointAfterPushRegisters);
156 } 156 }
157 157
158 void notifyResumed(ThreadState* state) 158 void leaveSafePoint(ThreadState* state)
159 { 159 {
160 if (NoBarrier_AtomicIncrement(&m_unparkedThreadCount, 1) > 0) 160 if (NoBarrier_AtomicIncrement(&m_unparkedThreadCount, 1) > 0)
161 checkAndPark(state); 161 checkAndPark(state);
162 state->executePendingAction(); 162 state->executePendingAction();
163 } 163 }
164 164
165 private: 165 private:
166 volatile Atomic32 m_canResume; 166 volatile Atomic32 m_canResume;
167 volatile Atomic32 m_unparkedThreadCount; 167 volatile Atomic32 m_unparkedThreadCount;
168 Mutex m_mutex; 168 Mutex m_mutex;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 { 204 {
205 MutexLocker locker(threadAttachMutex()); 205 MutexLocker locker(threadAttachMutex());
206 ThreadState* state = new ThreadState(); 206 ThreadState* state = new ThreadState();
207 state->create(startOfStack); 207 state->create(startOfStack);
208 attachedThreads().add(state); 208 attachedThreads().add(state);
209 } 209 }
210 210
211 void ThreadState::detach() 211 void ThreadState::detach()
212 { 212 {
213 ThreadState* current = Current(); 213 ThreadState* current = Current();
214 // Mark current thread as paused before trying to acquire threadAttachMutex 214 // Enter safe point before trying to acquire threadAttachMutex
215 // to avoid dead lock if another thread is preparing for GC, has acquired 215 // to avoid dead lock if another thread is preparing for GC, has acquired
216 // threadAttachMutex and waiting for other threads to pause or reach a 216 // threadAttachMutex and waiting for other threads to pause or reach a
217 // safepoint. 217 // safepoint.
218 if (!current->isPaused()) 218 if (!current->isInSafePoint())
219 current->paused(NoHeapPointersOnStack); 219 current->enterSafePoint(NoHeapPointersOnStack);
220 MutexLocker locker(threadAttachMutex()); 220 MutexLocker locker(threadAttachMutex());
221 current->resumed(); 221 current->leaveSafePoint();
222 current->destroy(); 222 current->destroy();
223 attachedThreads().remove(current); 223 attachedThreads().remove(current);
224 delete current; 224 delete current;
225 } 225 }
226 226
227 void ThreadState::create(intptr_t* startOfStack) 227 void ThreadState::create(intptr_t* startOfStack)
228 { 228 {
229 ASSERT(!**s_threadSpecific); 229 ASSERT(!**s_threadSpecific);
230 m_thread = currentThread(); 230 m_thread = currentThread();
231 **s_threadSpecific = this; 231 **s_threadSpecific = this;
(...skipping 28 matching lines...) Expand all
260 checkThread(); 260 checkThread();
261 delete m_heaps[GeneralHeap]; 261 delete m_heaps[GeneralHeap];
262 for (int i = GeneralHeap + 1; i < NumberOfHeaps; i++) 262 for (int i = GeneralHeap + 1; i < NumberOfHeaps; i++)
263 delete m_heaps[i]; 263 delete m_heaps[i];
264 delete m_persistents; 264 delete m_persistents;
265 m_persistents = 0; 265 m_persistents = 0;
266 delete m_interruptor; 266 delete m_interruptor;
267 m_interruptor = 0; 267 m_interruptor = 0;
268 } 268 }
269 269
270 void ThreadState::paused(StackState stackState) 270 void ThreadState::enterSafePoint(StackState stackState)
271 { 271 {
272 if (stackState == NoHeapPointersOnStack && gcRequested()) 272 if (stackState == NoHeapPointersOnStack && gcRequested())
273 Heap::collectGarbage(NoHeapPointersOnStack); 273 Heap::collectGarbage(NoHeapPointersOnStack);
274 checkThread(); 274 checkThread();
275 ASSERT(!m_isPaused); 275 ASSERT(!m_inSafePoint);
276 m_isPaused = true; 276 m_inSafePoint = true;
277 m_stackState = stackState; 277 m_stackState = stackState;
278 s_safePointBarrier->notifyPaused(this); 278 s_safePointBarrier->enterSafePoint(this);
279 } 279 }
280 280
281 void ThreadState::resumed() 281 void ThreadState::leaveSafePoint()
282 { 282 {
283 checkThread(); 283 checkThread();
284 ASSERT(m_isPaused); 284 ASSERT(m_inSafePoint);
285 m_isPaused = false; 285 m_inSafePoint = false;
286 m_stackState = HeapPointersOnStack; 286 m_stackState = HeapPointersOnStack;
287 s_safePointBarrier->notifyResumed(this); 287 s_safePointBarrier->leaveSafePoint(this);
288 } 288 }
289 289
290 void ThreadState::visitRoots(Visitor* visitor) 290 void ThreadState::visitRoots(Visitor* visitor)
291 { 291 {
292 AttachedThreadStateSet& threads = attachedThreads(); 292 AttachedThreadStateSet& threads = attachedThreads();
293 for (AttachedThreadStateSet::iterator it = threads.begin(), end = threads.en d(); it != end; ++it) 293 for (AttachedThreadStateSet::iterator it = threads.begin(), end = threads.en d(); it != end; ++it)
294 (*it)->trace(visitor); 294 (*it)->trace(visitor);
295 } 295 }
296 296
297 void ThreadState::visitPersistents(Visitor* visitor) 297 void ThreadState::visitPersistents(Visitor* visitor)
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 return Acquire_Load(&m_gcRequested); 440 return Acquire_Load(&m_gcRequested);
441 } 441 }
442 442
443 void ThreadState::setGCRequested(bool gcRequested) 443 void ThreadState::setGCRequested(bool gcRequested)
444 { 444 {
445 Release_Store(&m_gcRequested, gcRequested); 445 Release_Store(&m_gcRequested, gcRequested);
446 } 446 }
447 447
448 void ThreadState::setInterruptor(Interruptor* interruptor) 448 void ThreadState::setInterruptor(Interruptor* interruptor)
449 { 449 {
450 bool wasPaused = false; 450 bool wasInSafePoint = false;
Mads Ager (chromium) 2013/12/05 09:22:24 wasAtSafePoint?
451 if (!isPaused()) { 451 if (!isInSafePoint()) {
452 paused(HeapPointersOnStack); 452 enterSafePoint(HeapPointersOnStack);
453 wasPaused = true; 453 wasInSafePoint = true;
454 } 454 }
455 455
456 { 456 {
457 MutexLocker locker(threadAttachMutex()); 457 MutexLocker locker(threadAttachMutex());
458 delete m_interruptor; 458 delete m_interruptor;
459 m_interruptor = interruptor; 459 m_interruptor = interruptor;
460 } 460 }
461 461
462 if (wasPaused) 462 if (wasInSafePoint)
463 resumed(); 463 leaveSafePoint();
464 } 464 }
465 465
466 bool ThreadState::inFinalizeAll() 466 bool ThreadState::inFinalizeAll()
467 { 467 {
468 for (int i = 0; i < NumberOfHeaps; i++) { 468 for (int i = 0; i < NumberOfHeaps; i++) {
469 if (m_heaps[i]->inFinalizeAll()) 469 if (m_heaps[i]->inFinalizeAll())
470 return true; 470 return true;
471 } 471 }
472 return false; 472 return false;
473 } 473 }
(...skipping 20 matching lines...) Expand all
494 m_sweepInProgress = false; 494 m_sweepInProgress = false;
495 setGCRequested(false); 495 setGCRequested(false);
496 setSweepRequested(false); 496 setSweepRequested(false);
497 } 497 }
498 } 498 }
499 499
500 void ThreadState::Interruptor::onInterrupted() 500 void ThreadState::Interruptor::onInterrupted()
501 { 501 {
502 ThreadState* state = ThreadState::Current(); 502 ThreadState* state = ThreadState::Current();
503 ASSERT(state); 503 ASSERT(state);
504 ASSERT(!state->isPaused()); 504 ASSERT(!state->isInSafePoint());
505 state->safePoint(); 505 state->safePoint();
506 } 506 }
507 507
508 // Trigger on a 50% increase in size, but not for less than 2 pages. 508 // Trigger on a 50% increase in size, but not for less than 2 pages.
509 static bool increasedEnough(size_t newSize, size_t oldSize) 509 static bool increasedEnough(size_t newSize, size_t oldSize)
510 { 510 {
511 if (newSize < 2 * writablePageSize()) 511 if (newSize < 2 * writablePageSize())
512 return false; 512 return false;
513 return newSize > oldSize + (oldSize >> 1); 513 return newSize > oldSize + (oldSize >> 1);
514 } 514 }
(...skipping 24 matching lines...) Expand all
539 { 539 {
540 return m_totalAllocatedSpace == other.m_totalAllocatedSpace 540 return m_totalAllocatedSpace == other.m_totalAllocatedSpace
541 && m_totalObjectSpace == other.m_totalObjectSpace; 541 && m_totalObjectSpace == other.m_totalObjectSpace;
542 } 542 }
543 543
544 static void parkAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state , intptr_t* stackEnd) 544 static void parkAfterPushRegisters(SafePointBarrier* barrier, ThreadState* state , intptr_t* stackEnd)
545 { 545 {
546 barrier->doPark(state, stackEnd); 546 barrier->doPark(state, stackEnd);
547 } 547 }
548 548
549 static void notifyPausedAfterPushRegisters(SafePointBarrier* barrier, ThreadStat e* state, intptr_t* stackEnd) 549 static void enterSafePointAfterPushRegisters(SafePointBarrier* barrier, ThreadSt ate* state, intptr_t* stackEnd)
550 { 550 {
551 barrier->doNotifyPaused(state, stackEnd); 551 barrier->doEnterSafePoint(state, stackEnd);
552 } 552 }
553 553
554 554
555 } 555 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698