Flutter Engine
The Flutter Engine
thread_registry.cc
Go to the documentation of this 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
3// BSD-style license that can be found in the LICENSE file.
4
6
7#include "vm/json_stream.h"
8#include "vm/lockers.h"
9
10namespace dart {
11
13 // Go over the free thread list and delete the thread objects.
14 {
16 // At this point the active list should be empty.
17 ASSERT(active_list_ == nullptr);
18
19 // Now delete all the threads in the free list.
20 while (free_list_ != nullptr) {
21 Thread* thread = free_list_;
22 free_list_ = thread->next_;
23 delete thread;
24 }
25 }
26}
27
28Thread* ThreadRegistry::GetFreeThreadLocked(bool is_vm_isolate) {
29 ASSERT(threads_lock()->IsOwnedByCurrentThread());
30 Thread* thread = GetFromFreelistLocked(is_vm_isolate);
31 ASSERT(thread->api_top_scope() == nullptr);
32 // Now add this Thread to the active list for the isolate.
33 AddToActiveListLocked(thread);
34 return thread;
35}
36
37void ThreadRegistry::ReturnThreadLocked(Thread* thread) {
38 ASSERT(threads_lock()->IsOwnedByCurrentThread());
39 // Remove thread from the active list for the isolate.
40 RemoveFromActiveListLocked(thread);
41 ReturnToFreelistLocked(thread);
42}
43
45 IsolateGroup* isolate_group_of_interest,
46 ObjectPointerVisitor* visitor,
47 ValidationPolicy validate_frames) {
49 Thread* thread = active_list_;
50 while (thread != nullptr) {
51 if (thread->isolate_group() == isolate_group_of_interest) {
52 // The mutator thread is visited by the isolate itself (see
53 // [IsolateGroup::VisitStackPointers]).
54 if (!thread->IsDartMutatorThread()) {
55 thread->VisitObjectPointers(visitor, validate_frames);
56 }
57 }
58 thread = thread->next_;
59 }
60}
61
63 std::function<void(Thread* thread)> callback) {
65 Thread* thread = active_list_;
66 while (thread != nullptr) {
67 callback(thread);
68 thread = thread->next_;
69 }
70}
71
74 Thread* thread = active_list_;
75 while (thread != nullptr) {
76 if (!thread->BypassSafepoints()) {
77 thread->ReleaseStoreBuffer();
78 }
79 thread = thread->next_;
80 }
81}
82
85 Thread* thread = active_list_;
86 while (thread != nullptr) {
87 if (!thread->BypassSafepoints()) {
88 thread->AcquireMarkingStacks();
89 }
90 thread = thread->next_;
91 }
92}
93
96 Thread* thread = active_list_;
97 while (thread != nullptr) {
98 if (!thread->BypassSafepoints()) {
99 thread->ReleaseMarkingStacks();
100 ASSERT(!thread->is_marking());
101 }
102 thread = thread->next_;
103 }
104}
105
108 Thread* thread = active_list_;
109 while (thread != nullptr) {
110 if (!thread->BypassSafepoints() && thread->is_marking()) {
111 thread->FlushMarkingStacks();
112 ASSERT(thread->is_marking());
113 }
114 thread = thread->next_;
115 }
116}
117
118void ThreadRegistry::AddToActiveListLocked(Thread* thread) {
119 ASSERT(thread != nullptr);
120 ASSERT(threads_lock()->IsOwnedByCurrentThread());
121 thread->next_ = active_list_;
122 active_list_ = thread;
123 active_isolates_count_.fetch_add(1);
124}
125
126void ThreadRegistry::RemoveFromActiveListLocked(Thread* thread) {
127 ASSERT(thread != nullptr);
128 ASSERT(threads_lock()->IsOwnedByCurrentThread());
129 Thread* prev = nullptr;
130 Thread* current = active_list_;
131 while (current != nullptr) {
132 if (current == thread) {
133 if (prev == nullptr) {
134 active_list_ = current->next_;
135 } else {
136 prev->next_ = current->next_;
137 }
138 active_isolates_count_.fetch_sub(1);
139 break;
140 }
141 prev = current;
142 current = current->next_;
143 }
144}
145
146Thread* ThreadRegistry::GetFromFreelistLocked(bool is_vm_isolate) {
147 ASSERT(threads_lock()->IsOwnedByCurrentThread());
148 Thread* thread = nullptr;
149 // Get thread structure from free list or create a new one.
150 if (free_list_ == nullptr) {
151 thread = new Thread(is_vm_isolate);
152 } else {
153 thread = free_list_;
154 free_list_ = thread->next_;
155 }
156 return thread;
157}
158
159void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) {
160 ASSERT(thread != nullptr);
161 ASSERT(thread->os_thread() == nullptr);
162 ASSERT(thread->isolate_ == nullptr);
163 ASSERT(thread->isolate_group_ == nullptr);
164 ASSERT(thread->field_table_values_ == nullptr);
165 ASSERT(thread->shared_field_table_values_ == nullptr);
166 ASSERT(threads_lock()->IsOwnedByCurrentThread());
167 // Add thread to the free list.
168 thread->next_ = free_list_;
169 free_list_ = thread;
170}
171
172} // namespace dart
static float prev(float f)
T fetch_add(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:35
T fetch_sub(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:38
void VisitObjectPointers(IsolateGroup *isolate_group_of_interest, ObjectPointerVisitor *visitor, ValidationPolicy validate_frames)
Monitor * threads_lock() const
void ForEachThread(std::function< void(Thread *thread)> callback)
ApiLocalScope * api_top_scope() const
Definition: thread.h:513
bool is_marking() const
Definition: thread.h:676
void VisitObjectPointers(ObjectPointerVisitor *visitor, ValidationPolicy validate_frames)
Definition: thread.cc:968
void ReleaseStoreBuffer()
Definition: thread.cc:677
bool IsDartMutatorThread() const
Definition: thread.h:551
bool BypassSafepoints() const
Definition: thread.h:1007
IsolateGroup * isolate_group() const
Definition: thread.h:541
#define ASSERT(E)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Dart_NativeFunction function
Definition: fuchsia.cc:51
Definition: dart_vm.cc:33
ValidationPolicy
Definition: thread.h:271