1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_V8THREADS_H_
6 #define V8_V8THREADS_H_
7 
8 #include "src/isolate.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 
14 class ThreadState {
15  public:
16   // Returns NULL after the last one.
17   ThreadState* Next();
18 
19   enum List {FREE_LIST, IN_USE_LIST};
20 
21   void LinkInto(List list);
22   void Unlink();
23 
24   // Id of thread.
set_id(ThreadId id)25   void set_id(ThreadId id) { id_ = id; }
id()26   ThreadId id() { return id_; }
27 
28   // Should the thread be terminated when it is restored?
terminate_on_restore()29   bool terminate_on_restore() { return terminate_on_restore_; }
set_terminate_on_restore(bool terminate_on_restore)30   void set_terminate_on_restore(bool terminate_on_restore) {
31     terminate_on_restore_ = terminate_on_restore;
32   }
33 
34   // Get data area for archiving a thread.
data()35   char* data() { return data_; }
36 
37  private:
38   explicit ThreadState(ThreadManager* thread_manager);
39   ~ThreadState();
40 
41   void AllocateSpace();
42 
43   ThreadId id_;
44   bool terminate_on_restore_;
45   char* data_;
46   ThreadState* next_;
47   ThreadState* previous_;
48 
49   ThreadManager* thread_manager_;
50 
51   friend class ThreadManager;
52 };
53 
54 
55 // Defined in isolate.h.
56 class ThreadLocalTop;
57 
58 
59 class ThreadVisitor {
60  public:
61   // ThreadLocalTop may be only available during this call.
62   virtual void VisitThread(Isolate* isolate, ThreadLocalTop* top) = 0;
63 
64  protected:
~ThreadVisitor()65   virtual ~ThreadVisitor() {}
66 };
67 
68 
69 class ThreadManager {
70  public:
71   void Lock();
72   void Unlock();
73 
74   void ArchiveThread();
75   bool RestoreThread();
76   void FreeThreadResources();
77   bool IsArchived();
78 
79   void Iterate(ObjectVisitor* v);
80   void IterateArchivedThreads(ThreadVisitor* v);
IsLockedByCurrentThread()81   bool IsLockedByCurrentThread() {
82     return mutex_owner_.Equals(ThreadId::Current());
83   }
84 
85   ThreadId CurrentId();
86 
87   void TerminateExecution(ThreadId thread_id);
88 
89   // Iterate over in-use states.
90   ThreadState* FirstThreadStateInUse();
91   ThreadState* GetFreeThreadState();
92 
93  private:
94   ThreadManager();
95   ~ThreadManager();
96 
97   void DeleteThreadStateList(ThreadState* anchor);
98 
99   void EagerlyArchiveThread();
100 
101   base::Mutex mutex_;
102   ThreadId mutex_owner_;
103   ThreadId lazily_archived_thread_;
104   ThreadState* lazily_archived_thread_state_;
105 
106   // In the following two lists there is always at least one object on the list.
107   // The first object is a flying anchor that is only there to simplify linking
108   // and unlinking.
109   // Head of linked list of free states.
110   ThreadState* free_anchor_;
111   // Head of linked list of states in use.
112   ThreadState* in_use_anchor_;
113 
114   Isolate* isolate_;
115 
116   friend class Isolate;
117   friend class ThreadState;
118 };
119 
120 
121 }  // namespace internal
122 }  // namespace v8
123 
124 #endif  // V8_V8THREADS_H_
125