• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_V8THREADS_H_
29 #define V8_V8THREADS_H_
30 
31 namespace v8 {
32 namespace internal {
33 
34 
35 class ThreadState {
36  public:
37   // Iterate over in-use states.
38   static ThreadState* FirstInUse();
39   // Returns NULL after the last one.
40   ThreadState* Next();
41 
42   enum List {FREE_LIST, IN_USE_LIST};
43 
44   void LinkInto(List list);
45   void Unlink();
46 
47   static ThreadState* GetFree();
48 
49   // Id of thread.
set_id(int id)50   void set_id(int id) { id_ = id; }
id()51   int id() { return id_; }
52 
53   // Should the thread be terminated when it is restored?
terminate_on_restore()54   bool terminate_on_restore() { return terminate_on_restore_; }
set_terminate_on_restore(bool terminate_on_restore)55   void set_terminate_on_restore(bool terminate_on_restore) {
56     terminate_on_restore_ = terminate_on_restore;
57   }
58 
59   // Get data area for archiving a thread.
data()60   char* data() { return data_; }
61  private:
62   ThreadState();
63 
64   void AllocateSpace();
65 
66   int id_;
67   bool terminate_on_restore_;
68   char* data_;
69   ThreadState* next_;
70   ThreadState* previous_;
71 
72   // In the following two lists there is always at least one object on the list.
73   // The first object is a flying anchor that is only there to simplify linking
74   // and unlinking.
75   // Head of linked list of free states.
76   static ThreadState* free_anchor_;
77   // Head of linked list of states in use.
78   static ThreadState* in_use_anchor_;
79 };
80 
81 
82 class ThreadManager : public AllStatic {
83  public:
84   static void Lock();
85   static void Unlock();
86 
87   static void ArchiveThread();
88   static bool RestoreThread();
89   static bool IsArchived();
90 
91   static void Iterate(ObjectVisitor* v);
92   static void MarkCompactPrologue(bool is_compacting);
93   static void MarkCompactEpilogue(bool is_compacting);
IsLockedByCurrentThread()94   static bool IsLockedByCurrentThread() { return mutex_owner_.IsSelf(); }
95 
96   static int CurrentId();
97   static void AssignId();
98   static bool HasId();
99 
100   static void TerminateExecution(int thread_id);
101 
102   static const int kInvalidId = -1;
103  private:
104   static void EagerlyArchiveThread();
105 
106   static int last_id_;  // V8 threads are identified through an integer.
107   static Mutex* mutex_;
108   static ThreadHandle mutex_owner_;
109   static ThreadHandle lazily_archived_thread_;
110   static ThreadState* lazily_archived_thread_state_;
111 };
112 
113 
114 // The ContextSwitcher thread is used to schedule regular preemptions to
115 // multiple running V8 threads. Generally it is necessary to call
116 // StartPreemption if there is more than one thread running. If not, a single
117 // JavaScript can take full control of V8 and not allow other threads to run.
118 class ContextSwitcher: public Thread {
119  public:
120   // Set the preemption interval for the ContextSwitcher thread.
121   static void StartPreemption(int every_n_ms);
122 
123   // Stop sending preemption requests to threads.
124   static void StopPreemption();
125 
126   // Preempted thread needs to call back to the ContextSwitcher to acknowledge
127   // the handling of a preemption request.
128   static void PreemptionReceived();
129 
130  private:
131   explicit ContextSwitcher(int every_n_ms);
132 
133   void Run();
134 
135   bool keep_going_;
136   int sleep_ms_;
137 
138   static ContextSwitcher* singleton_;
139 };
140 
141 } }  // namespace v8::internal
142 
143 #endif  // V8_V8THREADS_H_
144