19OSThread* OSThread::thread_list_head_ =
nullptr;
20Mutex* OSThread::thread_list_lock_ =
nullptr;
21bool OSThread::creation_enabled_ =
false;
23#if defined(SUPPORT_TIMELINE)
24inline void UpdateTimelineTrackMetadata(
const OSThread& thread) {
25 RecorderSynchronizationLockScope ls;
29 TimelineEventRecorder* recorder = Timeline::recorder();
30 if (recorder !=
nullptr) {
31 recorder->AddTrackMetadataBasedOnThread(
40 id_(OSThread::GetCurrentThreadId()),
42 trace_id_(OSThread::GetCurrentThreadTraceId()),
44 name_(OSThread::GetCurrentThreadName()),
45 timeline_block_lock_(),
46 log_(new class
Log()) {
48 if (!GetCurrentStackBounds(&stack_limit_, &stack_base_)) {
49 FATAL(
"Failed to retrieve stack bounds");
52 stack_headroom_ = CalculateHeadroom(stack_base_ - stack_limit_);
56 ASSERT(stack_base_ > stack_limit_);
57 ASSERT(stack_base_ > GetCurrentStackPointer());
58 ASSERT(stack_limit_ < GetCurrentStackPointer());
61#if defined(SUPPORT_TIMELINE)
62 UpdateTimelineTrackMetadata(*
this);
67 ASSERT(thread_list_lock_ !=
nullptr);
69 if (!creation_enabled_) {
73 AddThreadToListLocked(os_thread);
77OSThread::~OSThread() {
78 if (!is_os_thread()) {
82 FATAL(
"Thread exited without calling Dart_ExitIsolate");
84 RemoveThreadFromList(
this);
87#if defined(SUPPORT_TIMELINE)
88 RecorderSynchronizationLockScope ls;
89 TimelineEventRecorder* recorder = Timeline::recorder();
90 if (recorder !=
nullptr && !ls.IsShuttingDown()) {
99 MutexLocker recorder_lock_locker(&Timeline::recorder()->lock_);
100 MutexLocker timeline_block_lock_locker(timeline_block_lock());
101 Timeline::recorder()->FinishBlock(timeline_block_);
104 timeline_block_ =
nullptr;
107 if (prepared_for_interrupts_) {
108 ThreadInterrupter::CleanupCurrentThreadState(thread_interrupter_state_);
109 thread_interrupter_state_ =
nullptr;
110 prepared_for_interrupts_ =
false;
118 if (name_ !=
nullptr) {
122 ASSERT(OSThread::Current() ==
this);
124 name_ = Utils::StrDup(
name);
126#if defined(SUPPORT_TIMELINE)
127 UpdateTimelineTrackMetadata(*
this);
132uword OSThread::GetCurrentStackPointer() {
134 return reinterpret_cast<uword>(_AddressOfReturnAddress());
136 return reinterpret_cast<uword>(__builtin_frame_address(0));
143void OSThread::DisableThreadInterrupts() {
144 ASSERT(OSThread::Current() ==
this);
145 thread_interrupt_disabled_.fetch_add(1u);
148void OSThread::EnableThreadInterrupts() {
149 ASSERT(OSThread::Current() ==
this);
150 uintptr_t old = thread_interrupt_disabled_.fetch_sub(1u);
151 if (FLAG_profiler && (old == 1)) {
154 if (!prepared_for_interrupts_) {
155 thread_interrupter_state_ = ThreadInterrupter::PrepareCurrentThread();
156 prepared_for_interrupts_ =
true;
158 ThreadInterrupter::WakeUp();
163 FATAL(
"Invalid call to OSThread::EnableThreadInterrupts()");
167bool OSThread::ThreadInterruptsEnabled() {
168 return thread_interrupt_disabled_ == 0;
174 delete reinterpret_cast<OSThread*
>(thread);
179 if (thread_list_lock_ ==
nullptr) {
180 thread_list_lock_ =
new Mutex();
182 ASSERT(thread_list_lock_ !=
nullptr);
191 EnableOSThreadCreation();
194 OSThread* os_thread = CreateOSThread();
195 ASSERT(os_thread !=
nullptr);
196 OSThread::SetCurrent(os_thread);
197 os_thread->
SetName(
"Dart_Initialize");
204 if (thread_list_lock_ !=
nullptr) {
207 DeleteThreadLocal(thread_key_);
211 ASSERT(thread_list_lock_ !=
nullptr);
212 delete thread_list_lock_;
213 thread_list_lock_ =
nullptr;
218OSThread* OSThread::CreateAndSetUnknownThread() {
219 ASSERT(OSThread::GetCurrentTLS() ==
nullptr);
220 OSThread* os_thread = CreateOSThread();
221 if (os_thread !=
nullptr) {
222 OSThread::SetCurrent(os_thread);
223 if (os_thread->name() ==
nullptr) {
224 os_thread->SetName(
"Unknown");
231 if (
id == OSThread::kInvalidThreadId) {
236 ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
247void OSThread::DisableOSThreadCreation() {
249 creation_enabled_ =
false;
252void OSThread::EnableOSThreadCreation() {
254 creation_enabled_ =
true;
262void OSThread::AddThreadToListLocked(OSThread* thread) {
263 ASSERT(thread !=
nullptr);
264 ASSERT(thread_list_lock_ !=
nullptr);
265 ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
266 ASSERT(creation_enabled_);
267 ASSERT(thread->thread_list_next_ ==
nullptr);
272 OSThread* current = thread_list_head_;
273 while (current !=
nullptr) {
274 ASSERT(current != thread);
275 current = current->thread_list_next_;
281 thread->thread_list_next_ = thread_list_head_;
282 thread_list_head_ = thread;
285void OSThread::RemoveThreadFromList(OSThread* thread) {
286 bool final_thread =
false;
288 ASSERT(thread !=
nullptr);
289 ASSERT(thread_list_lock_ !=
nullptr);
290 MutexLocker ml(thread_list_lock_);
291 OSThread* current = thread_list_head_;
292 OSThread* previous =
nullptr;
295 while (current !=
nullptr) {
296 if (current == thread) {
298 if (previous ==
nullptr) {
299 thread_list_head_ = thread->thread_list_next_;
301 previous->thread_list_next_ = current->thread_list_next_;
303 thread->thread_list_next_ =
nullptr;
304 final_thread = !creation_enabled_ && (thread_list_head_ ==
nullptr);
308 current = current->thread_list_next_;
320 SetThreadLocal(thread_key_,
reinterpret_cast<uword>(
value));
323 if ((
value !=
nullptr) && !
value->is_os_thread()) {
326 current_vm_thread_ =
nullptr;
330OSThreadIterator::OSThreadIterator() {
331 ASSERT(OSThread::thread_list_lock_ !=
nullptr);
333 OSThread::thread_list_lock_->Lock();
334 next_ = OSThread::thread_list_head_;
337OSThreadIterator::~OSThreadIterator() {
338 ASSERT(OSThread::thread_list_lock_ !=
nullptr);
340 OSThread::thread_list_lock_->Unlock();
343bool OSThreadIterator::HasNext()
const {
344 ASSERT(OSThread::thread_list_lock_ !=
nullptr);
345 ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
346 return next_ !=
nullptr;
350 ASSERT(OSThread::thread_list_lock_ !=
nullptr);
351 ASSERT(OSThread::thread_list_lock_->IsOwnedByCurrentThread());
353 next_ = next_->thread_list_next_;
#define RELEASE_ASSERT(cond)
void SetName(const char *name)
static intptr_t ThreadIdToIntPtr(ThreadId id)
static intptr_t ProcessId()
OSThread * os_thread() const
#define MSAN_UNPOISON(ptr, len)
void Log(const char *format,...) SK_PRINTF_LIKE(1
static void DeleteThread(void *thread)
pthread_key_t ThreadLocalKey
static const ThreadLocalKey kUnsetThreadLocalKey
static void SetName(Thread *thread, JSONStream *js)
DEF_SWITCHES_START aot vmservice shared library name