blob: 6cc2135d6b82c38dd645a56206ca5116573fe2a2 [file] [log] [blame]
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: cshapiro@google.com (Carl Shapiro)
3
4#ifndef ART_SRC_THREAD_H_
5#define ART_SRC_THREAD_H_
6
Carl Shapirob5573532011-07-12 18:22:59 -07007#include <list>
8#include <pthread.h>
9
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070010#include "src/globals.h"
11#include "src/logging.h"
12#include "src/macros.h"
13
14namespace art {
15
16class Object;
Carl Shapirob5573532011-07-12 18:22:59 -070017class Runtime;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070018class Thread;
Carl Shapirob5573532011-07-12 18:22:59 -070019class ThreadList;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070020
21class Mutex {
22 public:
23 virtual ~Mutex() {}
24
Carl Shapirob5573532011-07-12 18:22:59 -070025 void Lock();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070026
Carl Shapirob5573532011-07-12 18:22:59 -070027 bool TryLock();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070028
Carl Shapirob5573532011-07-12 18:22:59 -070029 void Unlock();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070030
31 const char* GetName() { return name_; }
32
33 Thread* GetOwner() { return owner_; }
34
Carl Shapirob5573532011-07-12 18:22:59 -070035 static Mutex* Create(const char* name);
36
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070037 public: // TODO: protected
38 explicit Mutex(const char* name) : name_(name), owner_(NULL) {}
39
40 void SetOwner(Thread* thread) { owner_ = thread; }
41
42 private:
43 const char* name_;
44
45 Thread* owner_;
46
Carl Shapirob5573532011-07-12 18:22:59 -070047 pthread_mutex_t lock_impl_;
48
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070049 DISALLOW_COPY_AND_ASSIGN(Mutex);
50};
51
52class MutexLock {
53 public:
54 explicit MutexLock(Mutex *mu) : mu_(mu) {
55 mu_->Lock();
56 }
57 ~MutexLock() { mu_->Unlock(); }
58 private:
59 Mutex* const mu_;
60 DISALLOW_COPY_AND_ASSIGN(MutexLock);
61};
62
63class Thread {
64 public:
Carl Shapirob5573532011-07-12 18:22:59 -070065 enum State {
66 kUnknown = -1,
67 kNew,
68 kRunnable,
69 kBlocked,
70 kWaiting,
71 kTimedWaiting,
72 kTerminated,
73 };
74
75 static Thread* Create(const char* name);
76
77 static Thread* Current() {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070078 static Thread self;
79 return &self; // TODO
80 }
81
Carl Shapirob5573532011-07-12 18:22:59 -070082 uint32_t GetId() const {
83 return id_;
84 }
85
86 pid_t GetNativeId() const {
87 return native_id_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070088 }
89
90 bool IsExceptionPending() const {
91 return false; // TODO exception_ != NULL;
92 }
93
94 Object* GetException() const {
95 return exception_;
96 }
97
98 void SetException(Object* new_exception) {
99 CHECK(new_exception != NULL);
100 // TODO: CHECK(exception_ == NULL);
101 exception_ = new_exception; // TODO
102 }
103
104 void ClearException() {
105 exception_ = NULL;
106 }
107
Carl Shapirob5573532011-07-12 18:22:59 -0700108 void SetName(const char* name);
109
110 void Suspend();
111
112 bool IsSuspended();
113
114 void Resume();
115
116 static bool Init();
117
118 Thread* next_;
119
120 Thread* prev_;
121
122 State GetState() {
123 return state_;
124 }
125
126 void SetState(State new_state) {
127 state_ = new_state;
128 }
129
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700130 private:
Carl Shapirob5573532011-07-12 18:22:59 -0700131 Thread() : id_(1234), exception_(NULL) {}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700132 ~Thread() {}
133
Carl Shapirob5573532011-07-12 18:22:59 -0700134 State state_;
135
136 uint32_t id_;
137
138 pid_t native_id_;
139
140 pthread_t native_handle_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700141
142 Object* exception_;
143
Carl Shapirob5573532011-07-12 18:22:59 -0700144 static pthread_key_t pthread_key_self_;
145
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700146 DISALLOW_COPY_AND_ASSIGN(Thread);
147};
148
Carl Shapirob5573532011-07-12 18:22:59 -0700149class ThreadList {
150 public:
151 static const int kMaxThreadId = 0xFFFF;
152 static const int kMainThreadId = 1;
153
154 void Init(Runtime* runtime);
155
156 void Register(Thread* thread);
157
158 void Unregister(Thread* thread);
159
160 void SuspendAll();
161
162 void ResumeAll();
163
164 ~ThreadList();
165
166 void Lock() {
167 lock_->Lock();
168 }
169
170 void Unlock() {
171 lock_->Unlock();
172 };
173
174 private:
175 ThreadList();
176
177 std::list<Thread*> list_;
178
179 Mutex* lock_;
180
181 DISALLOW_COPY_AND_ASSIGN(ThreadList);
182};
183
184class ThreadListLock {
185 public:
186 ThreadListLock(ThreadList* thread_list, Thread* current_thread)
187 : thread_list_(thread_list) {
188 if (current_thread == NULL) { // try to get it from TLS
189 current_thread = Thread::Current();
190 }
191 Thread::State old_state;
192 if (current_thread != NULL) {
193 old_state = current_thread->GetState();
194 current_thread->SetState(Thread::kWaiting); // TODO: VMWAIT
195 } else {
196 // happens during VM shutdown
197 old_state = Thread::kUnknown; // TODO: something else
198 }
199 thread_list_->Lock();
200 if (current_thread != NULL) {
201 current_thread->SetState(old_state);
202 }
203 }
204
205 ~ThreadListLock() {
206 thread_list_->Unlock();
207 }
208
209 // Allocates
210 int AllocThreadId();
211
212 void FreeThreadId(int thread_id);
213
214 private:
215 ThreadList* thread_list_;
216
217 DISALLOW_COPY_AND_ASSIGN(ThreadListLock);
218};
219
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700220} // namespace art
221
222#endif // ART_SRC_THREAD_H_