1 // Copyright (C) 2014 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "android/base/Compiler.h"
18 #include "android/base/threads/AndroidThreadTypes.h"
19 #include "android/base/synchronization/AndroidLock.h"
20 
21 #ifdef _WIN32
22 #include <windows.h>
23 #else
24 #include <pthread.h>
25 #endif
26 
27 #include <inttypes.h>
28 
29 namespace android {
30 namespace base {
31 namespace guest {
32 
33 // Wrapper class for platform-specific threads.
34 // To create your own thread, define a sub-class of emugl::Thread
35 // and override its main() method.
36 //
37 // For example:
38 //
39 //    class MyThread : public emugl::Thread {
40 //    public:
41 //        MyThread() : Thread() {}
42 //
43 //        virtual intptr_t main() {
44 //            ... main thread loop implementation
45 //            return 0;
46 //        }
47 //    };
48 //
49 //    ...
50 //
51 //    // Create new instance, but does not start it.
52 //    MyThread* thread = new MyThread();
53 //
54 //    // Start the thread.
55 //    thread->start();
56 //
57 //    // Wait for thread completion, and gets result into |exitStatus|.
58 //    int exitStatus;
59 //    thread->wait(&exitStatus);
60 //
61 class Thread {
62     DISALLOW_COPY_ASSIGN_AND_MOVE(Thread);
63 
64 public:
65     // Public constructor.
66     Thread(ThreadFlags flags = ThreadFlags::MaskSignals, int stackSize = 0);
67 
68     // Virtual destructor.
69     virtual ~Thread();
70 
71     // Override this method in your own thread sub-classes. This will
72     // be called when start() is invoked on the Thread instance.
73     virtual intptr_t main() = 0;
74 
75     // Override this if you need to execute some code after thread has
76     // exited main() and is guaranteed not to access any of its members.
77     // E.g. if you need to delete a thread object from the same thread
78     // it has created
onExit()79     virtual void onExit() {}
80 
81     // Start a thread instance. Return true on success, false otherwise
82     // (e.g. if the thread was already started or terminated).
83     bool start();
84 
85     // Wait for thread termination and retrieve exist status into
86     // |*exitStatus|. Return true on success, false otherwise.
87     // NOTE: |exitStatus| can be NULL.
88     virtual bool  wait(intptr_t *exitStatus = nullptr);
89 
90     // Check whether a thread has terminated. On success, return true
91     // and sets |*exitStatus|. On failure, return false.
92     // NOTE: |exitStatus| can be NULL.
93     bool tryWait(intptr_t *exitStatus);
94 
95     // Mask all signals for the current thread
96     // This is needed for the qemu guest to run properly
97     // NB: noop for Win32
98     static void maskAllSignals();
99 
100     // Sleep for |n| milliseconds
101     static void sleepMs(unsigned n);
102 
103     // Sleep for |n| microseconds
104     static void sleepUs(unsigned n);
105 
106     // Yield the remaining part of current thread's CPU time slice to another
107     // thread that's ready to run.
108     static void yield();
109 
110 private:
111 #ifdef _WIN32
112     static DWORD WINAPI thread_main(void* arg);
113 
114     HANDLE mThread = nullptr;
115 #else // !WIN32
116     static void* thread_main(void* arg);
117 
118     pthread_t mThread;
119 #endif
120     Lock mLock;
121     // Access guarded by |mLock|.
122     intptr_t mExitStatus = 0;
123     int mStackSize;
124     const ThreadFlags mFlags;
125     bool mStarted = false;
126     // Access guarded by |mLock|.
127     bool mFinished = false;
128 #ifndef _WIN32
129     // Posix-only, remember if we've joined our non-detached thread already.
130     bool mJoined = false;
131 #endif
132 };
133 
134 // Helper function to obtain a printable id for the current thread.
135 unsigned long getCurrentThreadId();
136 
137 // Subclass of Thread covering interruptible threads.
138 class InterruptibleThread : public Thread {
139     DISALLOW_COPY_ASSIGN_AND_MOVE(InterruptibleThread);
140 public:
141     // Public constructor.
142     InterruptibleThread(ThreadFlags flags = ThreadFlags::MaskSignals, int stackSize = 0) :
Thread(flags,stackSize)143         Thread(flags, stackSize) { }
144 
145     virtual void interrupt() = 0;
146 };
147 
148 }  // namespace guest
149 }  // namespace base
150 }  // namespace android
151