| 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 #ifndef VM_THREAD_REGISTRY_H_ | 5 #ifndef VM_THREAD_REGISTRY_H_ |
| 6 #define VM_THREAD_REGISTRY_H_ | 6 #define VM_THREAD_REGISTRY_H_ |
| 7 | 7 |
| 8 #include "vm/globals.h" | 8 #include "vm/globals.h" |
| 9 #include "vm/growable_array.h" | 9 #include "vm/growable_array.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| 11 #include "vm/lockers.h" | 11 #include "vm/lockers.h" |
| 12 #include "vm/thread.h" | 12 #include "vm/thread.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 // Unordered collection of threads relating to a particular isolate. | 16 // Unordered collection of threads relating to a particular isolate. |
| 17 class ThreadRegistry { | 17 class ThreadRegistry { |
| 18 public: | 18 public: |
| 19 ThreadRegistry() : mutex_(), entries_() {} | 19 ThreadRegistry() : mutex_(new Mutex()), entries_() {} |
| 20 | 20 |
| 21 bool RestoreStateTo(Thread* thread, Thread::State* state) { | 21 bool RestoreStateTo(Thread* thread, Thread::State* state) { |
| 22 MutexLocker ml(&mutex_); | 22 MutexLocker ml(mutex_); |
| 23 Entry* entry = FindEntry(thread); | 23 Entry* entry = FindEntry(thread); |
| 24 if (entry != NULL) { | 24 if (entry != NULL) { |
| 25 Thread::State st = entry->state; | 25 Thread::State st = entry->state; |
| 26 // TODO(koda): Support same thread re-entering same isolate with | 26 // TODO(koda): Support same thread re-entering same isolate with |
| 27 // Dart frames in between. For now, just assert it doesn't happen. | 27 // Dart frames in between. For now, just assert it doesn't happen. |
| 28 if (st.top_exit_frame_info != thread->top_exit_frame_info()) { | 28 if (st.top_exit_frame_info != thread->top_exit_frame_info()) { |
| 29 ASSERT(thread->top_exit_frame_info() == 0 || | 29 ASSERT(thread->top_exit_frame_info() == 0 || |
| 30 thread->top_exit_frame_info() > st.top_exit_frame_info); | 30 thread->top_exit_frame_info() > st.top_exit_frame_info); |
| 31 } | 31 } |
| 32 ASSERT(!entry->scheduled); | 32 ASSERT(!entry->scheduled); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 43 new_entry.scheduled = true; | 43 new_entry.scheduled = true; |
| 44 #if defined(DEBUG) | 44 #if defined(DEBUG) |
| 45 // State field is not in use, so zap it. | 45 // State field is not in use, so zap it. |
| 46 memset(&new_entry.state, 0xda, sizeof(new_entry.state)); | 46 memset(&new_entry.state, 0xda, sizeof(new_entry.state)); |
| 47 #endif | 47 #endif |
| 48 entries_.Add(new_entry); | 48 entries_.Add(new_entry); |
| 49 return false; | 49 return false; |
| 50 } | 50 } |
| 51 | 51 |
| 52 void SaveStateFrom(Thread* thread, const Thread::State& state) { | 52 void SaveStateFrom(Thread* thread, const Thread::State& state) { |
| 53 MutexLocker ml(&mutex_); | 53 MutexLocker ml(mutex_); |
| 54 Entry* entry = FindEntry(thread); | 54 Entry* entry = FindEntry(thread); |
| 55 ASSERT(entry != NULL); | 55 ASSERT(entry != NULL); |
| 56 ASSERT(entry->scheduled); | 56 ASSERT(entry->scheduled); |
| 57 entry->scheduled = false; | 57 entry->scheduled = false; |
| 58 entry->state = state; | 58 entry->state = state; |
| 59 } | 59 } |
| 60 | 60 |
| 61 bool Contains(Thread* thread) { | 61 bool Contains(Thread* thread) { |
| 62 MutexLocker ml(&mutex_); | 62 MutexLocker ml(mutex_); |
| 63 return (FindEntry(thread) != NULL); | 63 return (FindEntry(thread) != NULL); |
| 64 } | 64 } |
| 65 | 65 |
| 66 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 66 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 67 MutexLocker ml(&mutex_); | 67 MutexLocker ml(mutex_); |
| 68 for (int i = 0; i < entries_.length(); ++i) { | 68 for (int i = 0; i < entries_.length(); ++i) { |
| 69 const Entry& entry = entries_[i]; | 69 const Entry& entry = entries_[i]; |
| 70 Zone* zone = entry.scheduled ? entry.thread->zone() : entry.state.zone; | 70 Zone* zone = entry.scheduled ? entry.thread->zone() : entry.state.zone; |
| 71 if (zone != NULL) { | 71 if (zone != NULL) { |
| 72 zone->VisitObjectPointers(visitor); | 72 zone->VisitObjectPointers(visitor); |
| 73 } | 73 } |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 77 private: | 77 private: |
| 78 struct Entry { | 78 struct Entry { |
| 79 Thread* thread; | 79 Thread* thread; |
| 80 bool scheduled; | 80 bool scheduled; |
| 81 Thread::State state; | 81 Thread::State state; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 // Returns Entry corresponding to thread in registry or NULL. | 84 // Returns Entry corresponding to thread in registry or NULL. |
| 85 // Note: Lock should be taken before this function is called. | 85 // Note: Lock should be taken before this function is called. |
| 86 Entry* FindEntry(Thread* thread) { | 86 Entry* FindEntry(Thread* thread) { |
| 87 DEBUG_ASSERT(mutex_.IsOwnedByCurrentThread()); | 87 DEBUG_ASSERT(mutex_->IsOwnedByCurrentThread()); |
| 88 for (int i = 0; i < entries_.length(); ++i) { | 88 for (int i = 0; i < entries_.length(); ++i) { |
| 89 if (entries_[i].thread == thread) { | 89 if (entries_[i].thread == thread) { |
| 90 return &entries_[i]; | 90 return &entries_[i]; |
| 91 } | 91 } |
| 92 } | 92 } |
| 93 return NULL; | 93 return NULL; |
| 94 } | 94 } |
| 95 | 95 |
| 96 Mutex mutex_; | 96 Mutex* mutex_; |
| 97 MallocGrowableArray<Entry> entries_; | 97 MallocGrowableArray<Entry> entries_; |
| 98 | 98 |
| 99 | 99 |
| 100 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); | 100 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); |
| 101 }; | 101 }; |
| 102 | 102 |
| 103 } // namespace dart | 103 } // namespace dart |
| 104 | 104 |
| 105 #endif // VM_THREAD_REGISTRY_H_ | 105 #endif // VM_THREAD_REGISTRY_H_ |
| OLD | NEW |