我们看一下Thread的run函数的实现:
1 status_t Thread::run(const char* name, int32_t priority, size_t stack)
2 {
3 Mutex::Autolock _l(mLock);
4
5 if (mRunning) {
6 // thread already started
7 return INVALID_OPERATION;
8 }
9
10 // reset status and exitPending to their default value, so we can
11 // try again after an error happened (either below, or in readyToRun())
12 mStatus = NO_ERROR;
13 mExitPending = false;
14 mThread = thread_id_t(-1);
15
16 // hold a strong reference on ourself
17 mHoldSelf = this;
18
19 mRunning = true;
20
21 bool res;
22 if (mCanCallJava) {
23 res = createThreadEtc(_threadLoop,
24 this, name, priority, stack, &mThread);
25 } else {
26 res = androidCreateRawThreadEtc(_threadLoop,
27 this, name, priority, stack, &mThread);
28 }
29
30 if (res == false) {
31 mStatus = UNKNOWN_ERROR; // something happened!
32 mRunning = false;
33 mThread = thread_id_t(-1);
34 mHoldSelf.clear(); // "this" may have gone away after this.
35
36 return UNKNOWN_ERROR;
37 }
38
39 // Do not refer to mStatus here: The thread is already running (may, in fact
40 // already have exited with a valid mStatus result). The NO_ERROR indication
41 // here merely indicates successfully starting the thread and does not
42 // imply successful termination/execution.
43 return NO_ERROR;
44
45 // Exiting scope of mLock is a memory barrier and allows new thread to run
46 }
第22-24行(Thread->run)会调用createThreadEtc函数来创建一个
第25-28行(Thread->run)会调用androidCreateRawThreadEtc函数来创建一个线程. 关于androidCreateRawThreadEtc函数的详细分析可以参考page7文件.
当创建完一个新线程之后, 这个线程就会以_threadLoop函数作为入口来执行, 关于Thread的_threadLoop函数的详细分析可以参考page8文件.
由_threadLoop函数的分析可以知道, 这里会首先调用SurfaceFlinger的readyToRun函数, 关于SurfaceFlinger的readyToRun函数的详细分析可以参考page9文件.
page7
在这里, 我们看一下Thread的androidCreateRawThreadEtc函数的实现:
1 int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
2 void *userData,
3 const char* threadName,
4 int32_t threadPriority,
5 size_t threadStackSize,
6 android_thread_id_t *threadId)
7 {
8 pthread_attr_t attr;
9 pthread_attr_init(&attr);
10 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
11
12 #ifdef HAVE_ANDROID_OS /* valgrind is rejecting RT-priority create reqs */
13 if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
14 // Now that the pthread_t has a method to find the associated
15 // android_thread_id_t (pid) from pthread_t, it would be possible to avoid
16 // this trampoline in some cases as the parent could set the properties
17 // for the child. However, there would be a race condition because the
18 // child becomes ready immediately, and it doesn't work for the name.
19 // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was
20 // proposed but not yet accepted.
21 thread_data_t* t = new thread_data_t;
22 t->priority = threadPriority;
23 t->threadName = threadName ? strdup(threadName) : NULL;
24 t->entryFunction = entryFunction;
25 t->userData = userData;
26 entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
27 userData = t;
28 }
29 #endif
30
31 if (threadStackSize) {
32 pthread_attr_setstacksize(&attr, threadStackSize);
33 }
34
35 errno = 0;
36 pthread_t thread;
37 int result = pthread_create(&thread, &attr,
38 (android_pthread_entry)entryFunction, userData);
39 pthread_attr_destroy(&attr);
40 if (result != 0) {
41 ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
42 "(android threadPriority=%d)",
43 entryFunction, result, errno, threadPriority);
44 return 0;
45 }
46
47 // Note that *threadID is directly available to the parent only, as it is
48 // assigned after the child starts. Use memory barrier / lock if the child
49 // or other threads also need access.
50 if (threadId != NULL) {
51 *threadId = (android_thread_id_t)thread; // XXX: this is not portable
52 }
53 return 1;
54 }
第37-38行(Thread->androidCreateRawThreadEtc)会调用pthread_create函数来创建一个线程, 并以entryFunction作为线程的入口函数.
page8
在这篇文章里, 我们分析一下Thread的_threadLoop函数的实现:
1 int Thread::_threadLoop(void* user)
2 {
3 Thread* const self = static_cast
4
5 sp
6 wp
7 self->mHoldSelf.clear();
8
9 #ifdef HAVE_ANDROID_OS
10 // this is very useful for debugging with gdb
11 self->mTid = gettid();
12 #endif
13
14 bool first = true;
15
16 do {
17 bool result;
18 if (first) {
19 first = false;
20 self->mStatus = self->readyToRun();
21 result = (self->mStatus == NO_ERROR);
22
23 if (result && !self->exitPending()) {
24 // Binder threads (and maybe others) rely on threadLoop
25 // running at least once after a successful ::readyToRun()
26 // (unless, of course, the thread has already been asked to exit
27 // at that point).
28 // This is because threads are essentially used like this:
29 // (new ThreadSubclass())->run();
30 // The caller therefore does not retain a strong reference to
31 // the thread and the thread would simply disappear after the
32 // successful ::readyToRun() call instead of entering the
33 // threadLoop at least once.
34 result = self->threadLoop();
35 }
36 } else {
37 result = self->threadLoop();
38 }
39
40 // establish a scope for mLock
41 {
42 Mutex::Autolock _l(self->mLock);
43 if (result == false || self->mExitPending) {
44 self->mExitPending = true;
45 self->mRunning = false;
46 // clear thread ID so that requestExitAndWait() does not exit if
47 // called by a new thread using the same thread ID as this one.
48 self->mThread = thread_id_t(-1);
49 // note that interested observers blocked in requestExitAndWait are
50 // awoken by broadcast, but blocked on mLock until break exits scope
51 self->mThreadExitedCondition.broadcast();
52 break;
53 }
54 }
55
56 // Release our strong reference, to let a chance to the thread
57 // to die a peaceful death.
58 strong.clear();
59 // And immediately, re-acquire a strong reference for the next loop
60 strong = weak.promote();
61 } while(strong != 0);
62
63 return 0;
64 }
第18-38行(Thread->_threadLoop)会判断如果线程第一次执行会首先执行readyToRun函数, 紧接着会不停地执行threadLoop函数.
page9
在这篇文章里, 我们分析一下SurfaceFlinger的readyToRun函数的实现:
1 status_t SurfaceFlinger::readyToRun()
2 {
3 ALOGI( "SurfaceFlinger's main thread ready to run. "
4 "Initializing graphics H/W...");
5
6 // initialize EGL for the default display
7 mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
8 eglInitialize(mEGLDisplay, NULL, NULL);
9
10 // Initialize the H/W composer object. There may or may not be an
11 // actual hardware composer underneath.
12 mHwc = new HWComposer(this,
13 *static_cast
14
15 // initialize the config and context
16 EGLint format = mHwc->getVisualID();
17 mEGLConfig = selectEGLConfig(mEGLDisplay, format);
18 mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
19
20 LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
21 "couldn't create EGLContext");
22
23 // initialize our non-virtual displays
24 for (size_t i=0 ; i
26 mDefaultDisplays[i] = new BBinder();
27 wp
28
29 // set-up the displays that are already connected
30 if (mHwc->isConnected(i) || type==DisplayDevice::DISPLAY_PRIMARY) {
31 // All non-virtual displays are currently considered secure.
32 bool isSecure = true;
33 mCurrentState.displays.add(token, DisplayDeviceState(type));
34 sp
35 sp
36 static_cast< sp
37 sp
38 type, isSecure, token, stc, fbs, mEGLConfig);
39 if (i > DisplayDevice::DISPLAY_PRIMARY) {
40 // FIXME: currently we don't get blank/unblank requests
41 // for displays other than the main display, so we always
42 // assume a connected display is unblanked.
43 ALOGD("marking display %d as acquired/unblanked", i);
44 hw->acquireScreen();
45 }
46 mDisplays.add(token, hw);
47 }
48 }
49
50 // we need a GL context current in a few places, when initializing
51 // OpenGL ES (see below), or creating a layer,
52 // or when a texture is (asynchronously) destroyed, and for that
53 // we need a valid surface, so it's convenient to use the main display
54 // for that.
55 sp
56
57 // initialize OpenGL ES
58 DisplayDevice::makeCurrent(mEGLDisplay, hw, mEGLContext);
59 initializeGL(mEGLDisplay);
60
61 // start the EventThread
62 mEventThread = new EventThread(this);
63 mEventQueue.setEventThread(mEventThread);
64
65 // initialize our drawing state
66 mDrawingState = mCurrentState;
67
68
69 // We're now ready to accept clients...
70 mReadyToRunBarrier.open();
71
72 // set initial conditions (e.g. unblank default device)
73 initializeDisplays();
74
75 // start boot animation
76 startBootAnim();
77
78 return NO_ERROR;
79 }
第12-13行(SurfaceFlinger->readyToRun)会创建一个HWComposer对象来初始化成员变量mHwc, mHwc是底层操作Fb文件的.
第24-48行(SurfaceFlinger->readyToRun)会为每一个显示设备申请一个DisplayDevice对象,
第62行(SurfaceFlinger->readyToRun)会创建一个EventThread对象, 并初始化成员变量mEventThread. 关于EventThread的创建过程可以参考page10文件.
因为mEventThread是一个Sp类型的成员变量, 因此这里会导致EventThread的onFirstRef函数的调用, 关于EventThread的onFirstRef函数的详细分析可以参考page11文件.
第63行(SurfaceFlinger->readyToRun)会调用MessageQueue的setEventThread函数来和EventThread创建连接, 关于MessageQueue的setEventThread函数的详细分析可以参考page12文件.
page10
在这篇文章里, 我们来看一下EventThread的创建过程.我们先来看一下EventThread类的继承体系:
class EventThread : public Thread
很显然, EventThread只是一个线程.
EventThread类的构造函数的定义如下:
1 EventThread::EventThread(const sp
2 : mFlinger(flinger),
3 mUseSoftwareVSync(false),
4 mDebugVsyncEnabled(false) {
5
6 for (int32_t i=0 ; i
8 mVSyncEvent[i].header.id = 0;
9 mVSyncEvent[i].header.timestamp = 0;
10 mVSyncEvent[i].vsync.count = 0;
11 }
12 }