| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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/thread.h" | 5 #include "vm/thread.h" |
| 6 | 6 |
| 7 #include "vm/growable_array.h" | 7 #include "vm/growable_array.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/lockers.h" | 9 #include "vm/lockers.h" |
| 10 #include "vm/log.h" | 10 #include "vm/log.h" |
| 11 #include "vm/native_entry.h" | 11 #include "vm/native_entry.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/os_thread.h" | 13 #include "vm/os_thread.h" |
| 14 #include "vm/profiler.h" | 14 #include "vm/profiler.h" |
| 15 #include "vm/runtime_entry.h" | 15 #include "vm/runtime_entry.h" |
| 16 #include "vm/stub_code.h" | 16 #include "vm/stub_code.h" |
| 17 #include "vm/symbols.h" | 17 #include "vm/symbols.h" |
| 18 #include "vm/thread_interrupter.h" | 18 #include "vm/thread_interrupter.h" |
| 19 #include "vm/thread_registry.h" | 19 #include "vm/thread_registry.h" |
| 20 | 20 |
| 21 namespace dart { | 21 namespace dart { |
| 22 | 22 |
| 23 // The single thread local key which stores all the thread local data | 23 // The single thread local key which stores all the thread local data |
| 24 // for a thread. | 24 // for a thread. |
| 25 ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey; | 25 ThreadLocalKey Thread::thread_key_ = OSThread::kUnsetThreadLocalKey; |
| 26 Thread* Thread::thread_list_head_ = NULL; | 26 Thread* Thread::thread_list_head_ = NULL; |
| 27 Mutex* Thread::thread_list_lock_; | 27 Mutex* Thread::thread_list_lock_ = NULL; |
| 28 | 28 |
| 29 // Remove |thread| from each isolate's thread registry. | 29 // Remove |thread| from each isolate's thread registry. |
| 30 class ThreadPruner : public IsolateVisitor { | 30 class ThreadPruner : public IsolateVisitor { |
| 31 public: | 31 public: |
| 32 explicit ThreadPruner(Thread* thread) | 32 explicit ThreadPruner(Thread* thread) |
| 33 : thread_(thread) { | 33 : thread_(thread) { |
| 34 ASSERT(thread_ != NULL); | 34 ASSERT(thread_ != NULL); |
| 35 } | 35 } |
| 36 | 36 |
| 37 void VisitIsolate(Isolate* isolate) { | 37 void VisitIsolate(Isolate* isolate) { |
| 38 ThreadRegistry* registry = isolate->thread_registry(); | 38 ThreadRegistry* registry = isolate->thread_registry(); |
| 39 ASSERT(registry != NULL); | 39 ASSERT(registry != NULL); |
| 40 registry->PruneThread(thread_); | 40 registry->PruneThread(thread_); |
| 41 } | 41 } |
| 42 private: | 42 private: |
| 43 Thread* thread_; | 43 Thread* thread_; |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 | 46 |
| 47 void Thread::AddThreadToList(Thread* thread) { | 47 void Thread::AddThreadToList(Thread* thread) { |
| 48 ASSERT(thread != NULL); | 48 ASSERT(thread != NULL); |
| 49 ASSERT(thread->isolate() == NULL); | 49 ASSERT(thread->isolate() == NULL); |
| 50 ASSERT(thread_list_lock_ != NULL); |
| 50 MutexLocker ml(thread_list_lock_); | 51 MutexLocker ml(thread_list_lock_); |
| 51 | 52 |
| 52 ASSERT(thread->thread_list_next_ == NULL); | 53 ASSERT(thread->thread_list_next_ == NULL); |
| 53 | 54 |
| 54 #if defined(DEBUG) | 55 #if defined(DEBUG) |
| 55 { | 56 { |
| 56 // Ensure that we aren't already in the list. | 57 // Ensure that we aren't already in the list. |
| 57 Thread* current = thread_list_head_; | 58 Thread* current = thread_list_head_; |
| 58 while (current != NULL) { | 59 while (current != NULL) { |
| 59 ASSERT(current != thread); | 60 ASSERT(current != thread); |
| 60 current = current->thread_list_next_; | 61 current = current->thread_list_next_; |
| 61 } | 62 } |
| 62 } | 63 } |
| 63 #endif | 64 #endif |
| 64 | 65 |
| 65 // Insert at head of list. | 66 // Insert at head of list. |
| 66 thread->thread_list_next_ = thread_list_head_; | 67 thread->thread_list_next_ = thread_list_head_; |
| 67 thread_list_head_ = thread; | 68 thread_list_head_ = thread; |
| 68 } | 69 } |
| 69 | 70 |
| 70 | 71 |
| 71 void Thread::RemoveThreadFromList(Thread* thread) { | 72 void Thread::RemoveThreadFromList(Thread* thread) { |
| 72 ASSERT(thread != NULL); | 73 ASSERT(thread != NULL); |
| 73 ASSERT(thread->isolate() == NULL); | 74 ASSERT(thread->isolate() == NULL); |
| 75 ASSERT(thread_list_lock_ != NULL); |
| 74 MutexLocker ml(thread_list_lock_); | 76 MutexLocker ml(thread_list_lock_); |
| 75 | 77 |
| 76 // Handle case where |thread| is head of list. | 78 // Handle case where |thread| is head of list. |
| 77 if (thread_list_head_ == thread) { | 79 if (thread_list_head_ == thread) { |
| 78 thread_list_head_ = thread->thread_list_next_; | 80 thread_list_head_ = thread->thread_list_next_; |
| 79 thread->thread_list_next_ = NULL; | 81 thread->thread_list_next_ = NULL; |
| 80 return; | 82 return; |
| 81 } | 83 } |
| 82 | 84 |
| 83 Thread* current = thread_list_head_; | 85 Thread* current = thread_list_head_; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 // Clear |this| from all isolate's thread registry. | 120 // Clear |this| from all isolate's thread registry. |
| 119 ThreadPruner pruner(this); | 121 ThreadPruner pruner(this); |
| 120 Isolate::VisitIsolates(&pruner); | 122 Isolate::VisitIsolates(&pruner); |
| 121 delete log_; | 123 delete log_; |
| 122 log_ = NULL; | 124 log_ = NULL; |
| 123 RemoveThreadFromList(this); | 125 RemoveThreadFromList(this); |
| 124 } | 126 } |
| 125 | 127 |
| 126 | 128 |
| 127 void Thread::InitOnceBeforeIsolate() { | 129 void Thread::InitOnceBeforeIsolate() { |
| 130 ASSERT(thread_list_lock_ == NULL); |
| 131 thread_list_lock_ = new Mutex(); |
| 132 ASSERT(thread_list_lock_ != NULL); |
| 128 ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey); | 133 ASSERT(thread_key_ == OSThread::kUnsetThreadLocalKey); |
| 129 thread_key_ = OSThread::CreateThreadLocal(DeleteThread); | 134 thread_key_ = OSThread::CreateThreadLocal(DeleteThread); |
| 130 ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey); | 135 ASSERT(thread_key_ != OSThread::kUnsetThreadLocalKey); |
| 131 ASSERT(Thread::Current() == NULL); | 136 ASSERT(Thread::Current() == NULL); |
| 132 thread_list_lock_ = new Mutex(); | |
| 133 // Allocate a new Thread and postpone initialization of VM constants for | 137 // Allocate a new Thread and postpone initialization of VM constants for |
| 134 // this first thread. | 138 // this first thread. |
| 135 Thread* thread = new Thread(false); | 139 Thread* thread = new Thread(false); |
| 136 // Verify that current thread was set. | 140 // Verify that current thread was set. |
| 137 ASSERT(Thread::Current() == thread); | 141 ASSERT(Thread::Current() == thread); |
| 138 } | 142 } |
| 139 | 143 |
| 140 | 144 |
| 141 void Thread::InitOnceAfterObjectAndStubCode() { | 145 void Thread::InitOnceAfterObjectAndStubCode() { |
| 142 Thread* thread = Thread::Current(); | 146 Thread* thread = Thread::Current(); |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 Thread* ThreadIterator::Next() { | 530 Thread* ThreadIterator::Next() { |
| 527 ASSERT(Thread::thread_list_lock_ != NULL); | 531 ASSERT(Thread::thread_list_lock_ != NULL); |
| 528 ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread()); | 532 ASSERT(Thread::thread_list_lock_->IsOwnedByCurrentThread()); |
| 529 Thread* current = next_; | 533 Thread* current = next_; |
| 530 next_ = next_->thread_list_next_; | 534 next_ = next_->thread_list_next_; |
| 531 return current; | 535 return current; |
| 532 } | 536 } |
| 533 | 537 |
| 534 | 538 |
| 535 } // namespace dart | 539 } // namespace dart |
| OLD | NEW |