thread.h revision 69759eaa6fd4386f1e6d8748052ad221087b3476
10e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved. 20e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro// Author: cshapiro@google.com (Carl Shapiro) 30e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 40e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#ifndef ART_SRC_THREAD_H_ 50e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#define ART_SRC_THREAD_H_ 60e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 7b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro#include <pthread.h> 8b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include <list> 9b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 100e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include "src/globals.h" 11df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers#include "src/jni_internal.h" 120e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include "src/logging.h" 130e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#include "src/macros.h" 1469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro#include "src/offsets.h" 1561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro#include "src/runtime.h" 160e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 17b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include "jni.h" 18b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 190e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapironamespace art { 200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Object; 22b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass Runtime; 23b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersclass StackHandleBlock; 240e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread; 25b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadList; 260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Mutex { 280e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 290e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro virtual ~Mutex() {} 300e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 31b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Lock(); 320e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 33b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro bool TryLock(); 340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 35b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Unlock(); 360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const char* GetName() { return name_; } 380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Thread* GetOwner() { return owner_; } 400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 41b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static Mutex* Create(const char* name); 42b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: // TODO: protected 440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro explicit Mutex(const char* name) : name_(name), owner_(NULL) {} 450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void SetOwner(Thread* thread) { owner_ = thread; } 470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro const char* name_; 500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Thread* owner_; 520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 53b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro pthread_mutex_t lock_impl_; 54b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 550e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(Mutex); 560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 570e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 580e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass MutexLock { 590e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 600e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro explicit MutexLock(Mutex *mu) : mu_(mu) { 610e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro mu_->Lock(); 620e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 630e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro ~MutexLock() { mu_->Unlock(); } 640e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 650e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Mutex* const mu_; 660e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(MutexLock); 670e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 680e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 69b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Stack handle blocks are allocated within the bridge frame between managed 70b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// and native code. 71b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersclass StackHandleBlock { 72b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers public: 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Number of references contained within this SHB 74b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t NumberOfReferences() { 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return number_of_references_; 76b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 77b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 78b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Link to previous SHB or NULL 79b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StackHandleBlock* Link() { 80b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return link_; 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 82b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of length within SHB, used by generated code 84b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static size_t NumberOfReferencesOffset() { 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return OFFSETOF_MEMBER(StackHandleBlock, number_of_references_); 86b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 87b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 88b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of link within SHB, used by generated code 89b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static size_t LinkOffset() { 90b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return OFFSETOF_MEMBER(StackHandleBlock, link_); 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 92b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers private: 94b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StackHandleBlock() {} 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 96b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t number_of_references_; 97b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StackHandleBlock* link_; 98b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers DISALLOW_COPY_AND_ASSIGN(StackHandleBlock); 100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers}; 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1020e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiroclass Thread { 1030e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro public: 104b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro enum State { 105b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kUnknown = -1, 106b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kNew, 107b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kRunnable, 108b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kBlocked, 109b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kWaiting, 110b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kTimedWaiting, 111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers kNative, 112b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro kTerminated, 113b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro }; 114b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 11561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const size_t kDefaultStackSize = 64 * KB; 11661e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 11761e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // Creates a new thread. 11861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static Thread* Create(size_t stack_size); 11961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 12061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro // Creates a new thread from the calling thread. 12161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static Thread* Attach(); 122b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 123b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static Thread* Current() { 124d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro void* thread = pthread_getspecific(Thread::pthread_key_self_); 125d0e7e777c412071a911dd2c008b20b7d879fd392Carl Shapiro return reinterpret_cast<Thread*>(thread); 1260e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1270e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 128b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro uint32_t GetId() const { 129b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro return id_; 130b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 131b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 132b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro pid_t GetNativeId() const { 133b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro return native_id_; 1340e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1350e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1360e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro bool IsExceptionPending() const { 1370e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro return false; // TODO exception_ != NULL; 1380e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1390e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1400e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Object* GetException() const { 1410e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro return exception_; 1420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1440e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void SetException(Object* new_exception) { 1450e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro CHECK(new_exception != NULL); 1460e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro // TODO: CHECK(exception_ == NULL); 1470e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro exception_ = new_exception; // TODO 1480e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1490e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 1500e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro void ClearException() { 1510e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro exception_ = NULL; 1520e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro } 1530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 154b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void SetName(const char* name); 155b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 156b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Suspend(); 157b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 158b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro bool IsSuspended(); 159b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 160b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Resume(); 161b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 162b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static bool Init(); 163b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 16469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Runtime* GetRuntime() const { 16569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro return runtime_; 16669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro } 16769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 168b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro State GetState() { 169b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro return state_; 170b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 171b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 172b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void SetState(State new_state) { 173b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro state_ = new_state; 174b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 175b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of state within Thread, used by generated code 177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static ThreadOffset StateOffset() { 178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, state_)); 179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // JNI methods 182df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers JniEnvironment* GetJniEnv() const { 183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return jni_env_; 184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of JNI environment within Thread, used by generated code 187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static ThreadOffset JniEnvOffset() { 188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, jni_env_)); 189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Offset of top stack handle block within Thread, used by generated code 192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers static ThreadOffset TopShbOffset() { 193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return ThreadOffset(OFFSETOF_MEMBER(Thread, top_shb_)); 194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Number of references allocated in StackHandleBlocks on this thread 197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t NumShbHandles() { 198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t count = 0; 199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers for (StackHandleBlock* cur = top_shb_; cur; cur = cur->Link()) { 200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers count += cur->NumberOfReferences(); 201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return count; 203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 2050e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro private: 206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Thread() : 20769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro id_(1234), top_shb_(NULL), exception_(NULL) { 208df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers jni_env_ = new JniEnvironment(); 209df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers } 21069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 211df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers ~Thread() { 212df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers delete jni_env_; 213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 2140e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers void InitCpu(); 216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 21769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // Managed thread id. 21869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro uint32_t id_; 219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Top of linked list of stack handle blocks or NULL for none 221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StackHandleBlock* top_shb_; 222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Every thread may have an associated JNI environment 224df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers JniEnvironment* jni_env_; 225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 226b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro State state_; 227b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 22869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // Native (kernel) thread id. 229b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro pid_t native_id_; 230b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 23169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // Native thread handle. 23261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro pthread_t handle_; 2330e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 23469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // Initialized to "this". On certain architectures (such as x86) reading 23569759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // off of Thread::Current is easy but getting the address of Thread::Current 23669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // is hard. This field can be read off of Thread::Current to give the address. 23769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Thread* self_; 23869759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 23969759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro Runtime* runtime_; 24069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 24169759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // The pending exception or NULL. 2420e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro Object* exception_; 2430e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 24469759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // The inclusive base of the control stack. 24561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro byte* stack_base_; 24669759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro 24769759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // The exclusive limit of the control stack. 24861e019d291583029c01b61b93bea750f2b663c37Carl Shapiro byte* stack_limit_; 24961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 25069759eaa6fd4386f1e6d8748052ad221087b3476Carl Shapiro // TLS key used to retrieve the VM thread object. 251b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro static pthread_key_t pthread_key_self_; 252b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 2530e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro DISALLOW_COPY_AND_ASSIGN(Thread); 2540e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro}; 255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersstd::ostream& operator<<(std::ostream& os, const Thread::State& state); 2560e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 257b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadList { 258b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro public: 25961e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const int kMaxId = 0xFFFF; 26061e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const int kInvalidId = 0; 26161e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static const int kMainId = 1; 26261e019d291583029c01b61b93bea750f2b663c37Carl Shapiro 26361e019d291583029c01b61b93bea750f2b663c37Carl Shapiro static ThreadList* Create(); 264b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 26561e019d291583029c01b61b93bea750f2b663c37Carl Shapiro ~ThreadList(); 266b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 267b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Register(Thread* thread); 268b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 269b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Unregister(Thread* thread); 270b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 271b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Lock() { 272b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro lock_->Lock(); 273b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 274b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 275b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro void Unlock() { 276b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro lock_->Unlock(); 277b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro }; 278b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 279b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro private: 280b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ThreadList(); 281b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 282b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro std::list<Thread*> list_; 283b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 284b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro Mutex* lock_; 285b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 286b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ThreadList); 287b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro}; 288b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 289b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiroclass ThreadListLock { 290b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro public: 291b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ThreadListLock(ThreadList* thread_list, Thread* current_thread) 292b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro : thread_list_(thread_list) { 293b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (current_thread == NULL) { // try to get it from TLS 294b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro current_thread = Thread::Current(); 295b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 296b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro Thread::State old_state; 297b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (current_thread != NULL) { 298b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro old_state = current_thread->GetState(); 299b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro current_thread->SetState(Thread::kWaiting); // TODO: VMWAIT 300b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } else { 301b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro // happens during VM shutdown 302b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro old_state = Thread::kUnknown; // TODO: something else 303b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 304b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro thread_list_->Lock(); 305b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro if (current_thread != NULL) { 306b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro current_thread->SetState(old_state); 307b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 308b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 309b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 310b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ~ThreadListLock() { 311b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro thread_list_->Unlock(); 312b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro } 313b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 314b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro private: 315b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro ThreadList* thread_list_; 316b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 317b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro DISALLOW_COPY_AND_ASSIGN(ThreadListLock); 318b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro}; 319b557353b22c728eecbd1c68593b482622c7782a8Carl Shapiro 3200e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro} // namespace art 3210e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro 3220e5d75d5ca2b8a44fab0c862276a466cbab39859Carl Shapiro#endif // ART_SRC_THREAD_H_ 323