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 |