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/stack_frame.h" | 12 #include "vm/stack_frame.h" |
13 #include "vm/thread.h" | 13 #include "vm/thread.h" |
14 | 14 |
15 namespace dart { | 15 namespace dart { |
16 | 16 |
17 // Unordered collection of threads relating to a particular isolate. | 17 // Unordered collection of threads relating to a particular isolate. |
18 class ThreadRegistry { | 18 class ThreadRegistry { |
19 public: | 19 public: |
20 ThreadRegistry() | 20 ThreadRegistry() |
21 : monitor_(new Monitor()), | 21 : threads_lock_(new Monitor()), |
22 active_list_(NULL), | 22 active_list_(NULL), |
23 free_list_(NULL), | 23 free_list_(NULL), |
24 mutator_thread_(NULL), | 24 mutator_thread_(NULL) {} |
25 in_rendezvous_(false), | |
26 remaining_(0), | |
27 round_(0) {} | |
28 | |
29 ~ThreadRegistry(); | 25 ~ThreadRegistry(); |
30 | 26 |
31 Thread* active_list() const { return active_list_; } | |
32 | |
33 // Bring all threads in this isolate to a safepoint. The caller is | |
34 // expected to be implicitly at a safepoint. The threads will wait | |
35 // until ResumeAllThreads is called. First participates in any | |
36 // already pending rendezvous requested by another thread. Any | |
37 // thread that tries to enter this isolate during rendezvous will | |
38 // wait in RestoreStateTo. Nesting is not supported: the caller must | |
39 // call ResumeAllThreads before making further calls to | |
40 // SafepointThreads. | |
41 void SafepointThreads(); | |
42 | |
43 // Unblocks all threads participating in the rendezvous that was organized | |
44 // by a prior call to SafepointThreads. | |
45 // TODO(koda): Consider adding a scope helper to avoid omitting this call. | |
46 void ResumeAllThreads(); | |
47 | |
48 // Indicate that the current thread is at a safepoint, and offer to wait for | |
49 // any pending rendezvous request (if none, returns immediately). | |
50 void CheckSafepoint() { | |
51 MonitorLocker ml(monitor_); | |
52 CheckSafepointLocked(); | |
53 } | |
54 | |
55 bool AtSafepoint() const { return in_rendezvous_; } | |
56 Thread* Schedule(Isolate* isolate, bool is_mutator, bool bypass_safepoint); | |
57 void Unschedule(Thread* thread, bool is_mutator, bool bypass_safepoint); | |
58 void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames); | 27 void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames); |
59 void PrepareForGC(); | 28 void PrepareForGC(); |
60 | 29 |
61 private: | 30 private: |
62 void AddThreadToActiveList(Thread* thread); | 31 Thread* active_list() const { return active_list_; } |
63 void RemoveThreadFromActiveList(Thread* thread); | 32 Monitor* threads_lock() const { return threads_lock_; } |
64 Thread* GetThreadFromFreelist(Isolate* isolate); | |
65 void ReturnThreadToFreelist(Thread* thread); | |
66 | 33 |
67 // Note: Lock should be taken before this function is called. | 34 Thread* GetFreeThreadLocked(Isolate* isolate, bool is_mutator); |
68 void CheckSafepointLocked(); | 35 void ReturnThreadLocked(bool is_mutator, Thread* thread); |
| 36 void AddToActiveListLocked(Thread* thread); |
| 37 void RemoveFromActiveListLocked(Thread* thread); |
| 38 Thread* GetFromFreelistLocked(Isolate* isolate); |
| 39 void ReturnToFreelistLocked(Thread* thread); |
69 | 40 |
70 // Returns the number threads that are scheduled on this isolate. | 41 // This monitor protects the threads list for an isolate, it is used whenever |
71 // Note: Lock should be taken before this function is called. | 42 // we need to iterate over threads (both active and free) in an isolate. |
72 intptr_t CountScheduledLocked(); | 43 Monitor* threads_lock_; |
73 | |
74 Monitor* monitor_; // All access is synchronized through this monitor. | |
75 Thread* active_list_; // List of active threads in the isolate. | 44 Thread* active_list_; // List of active threads in the isolate. |
76 Thread* free_list_; // Free list of Thread objects that can be reused. | 45 Thread* free_list_; // Free list of Thread objects that can be reused. |
| 46 |
77 // TODO(asiva): Currently we treat a mutator thread as a special thread | 47 // TODO(asiva): Currently we treat a mutator thread as a special thread |
78 // and always schedule execution of Dart code on the same mutator thread | 48 // and always schedule execution of Dart code on the same mutator thread |
79 // object. The ApiLocalScope has been made thread specific but we still | 49 // object. The ApiLocalScope has been made thread specific but we still |
80 // have scenarios where we do a temporary exit of an Isolate with live | 50 // have scenarios where we do a temporary exit of an Isolate with live |
81 // zones/handles in the the API scope : | 51 // zones/handles in the the API scope : |
82 // - Dart_RunLoop() | 52 // - Dart_RunLoop() |
83 // - IsolateSaver in Dart_NewNativePort | 53 // - IsolateSaver in Dart_NewNativePort |
84 // - Isolate spawn (function/uri) under FLAG_i_like_slow_isolate_spawn | 54 // - Isolate spawn (function/uri) under FLAG_i_like_slow_isolate_spawn |
85 // We probably need a mechanism to return to the specific thread only | 55 // We probably need a mechanism to return to the specific thread only |
86 // for these specific cases. We should also determine if the embedder | 56 // for these specific cases. We should also determine if the embedder |
87 // should allow exiting an isolate with live state in zones/handles in | 57 // should allow exiting an isolate with live state in zones/handles in |
88 // which case a new API for returning to the specific thread needs to be | 58 // which case a new API for returning to the specific thread needs to be |
89 // added. | 59 // added. |
90 Thread* mutator_thread_; | 60 Thread* mutator_thread_; |
91 | 61 |
92 // Safepoint rendezvous state. | 62 friend class Isolate; |
93 bool in_rendezvous_; // A safepoint rendezvous request is in progress. | 63 friend class SafepointHandler; |
94 intptr_t remaining_; // Number of threads yet to reach their safepoint. | |
95 int64_t round_; // Counter, to prevent missing updates to remaining_ | |
96 // (see comments in CheckSafepointLocked). | |
97 | |
98 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); | 64 DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); |
99 }; | 65 }; |
100 | 66 |
101 } // namespace dart | 67 } // namespace dart |
102 | 68 |
103 #endif // VM_THREAD_REGISTRY_H_ | 69 #endif // VM_THREAD_REGISTRY_H_ |
OLD | NEW |