// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #ifndef RUNTIME_VM_THREAD_REGISTRY_H_ #define RUNTIME_VM_THREAD_REGISTRY_H_ #include "vm/globals.h" #include "vm/growable_array.h" #include "vm/isolate.h" #include "vm/lockers.h" #include "vm/stack_frame.h" #include "vm/thread.h" namespace dart { #ifndef PRODUCT class JSONStream; class JSONArray; #endif // Unordered collection of threads relating to a particular isolate. class ThreadRegistry { public: ThreadRegistry() : threads_lock_(), active_list_(NULL), free_list_(NULL), mutator_thread_(NULL) {} ~ThreadRegistry(); void VisitObjectPointers(ObjectPointerVisitor* visitor, ValidationPolicy validate_frames); void ReleaseStoreBuffers(); void AcquireMarkingStacks(); void ReleaseMarkingStacks(); Thread* mutator_thread() const { return mutator_thread_; } #ifndef PRODUCT void PrintJSON(JSONStream* stream) const; #endif // Calculates the sum of the max memory usage in bytes of each thread. uintptr_t ThreadHighWatermarksTotalLocked() const; intptr_t CountZoneHandles() const; intptr_t CountScopedHandles() const; private: Thread* active_list() const { return active_list_; } Monitor* threads_lock() const { return &threads_lock_; } Thread* GetFreeThreadLocked(Isolate* isolate, bool is_mutator); void ReturnThreadLocked(bool is_mutator, Thread* thread); void AddToActiveListLocked(Thread* thread); void RemoveFromActiveListLocked(Thread* thread); Thread* GetFromFreelistLocked(Isolate* isolate); void ReturnToFreelistLocked(Thread* thread); // This monitor protects the threads list for an isolate, it is used whenever // we need to iterate over threads (both active and free) in an isolate. mutable Monitor threads_lock_; Thread* active_list_; // List of active threads in the isolate. Thread* free_list_; // Free list of Thread objects that can be reused. // TODO(asiva): Currently we treat a mutator thread as a special thread // and always schedule execution of Dart code on the same mutator thread // object. The ApiLocalScope has been made thread specific but we still // have scenarios where we do a temporary exit of an Isolate with live // zones/handles in the API scope : // - Dart_RunLoop() // - IsolateSaver in Dart_NewNativePort // Similarly, tracking async_stack_trace requires that we always reschedule // on the same thread. // We probably need a mechanism to return to the specific thread only // for these specific cases. We should also determine if the embedder // should allow exiting an isolate with live state in zones/handles in // which case a new API for returning to the specific thread needs to be // added. Thread* mutator_thread_; friend class Isolate; friend class SafepointHandler; friend class Scavenger; DISALLOW_COPY_AND_ASSIGN(ThreadRegistry); }; } // namespace dart #endif // RUNTIME_VM_THREAD_REGISTRY_H_