Android Process & Thread
Native Service and Android Service
- Native Service:In every main() method of NativeService, which is called by init process through parseing init.rc, the globale object of ProcessState will be created by calling ProcessState::self(),and then startThreadPool and created main thread by calling IPCThreadPool.self()->joinThreadPool().
- Android Service:All Android Service is created by SystemServer and running in the same process which is system server.
New Process with main()
1 int main(int argc, char** argv) 2 { 3 sp<ProcessState> proc(ProcessState::self()); 4 sp<IServiceManager> sm = defaultServiceManager(); 5 LOGI("ServiceManager: %p", sm.get()); 6 AudioFlinger::instantiate(); 7 MediaPlayerService::instantiate(); 8 CameraService::instantiate(); 9 AudioPolicyService::instantiate(); 10 ProcessState::self()->startThreadPool(); 11 IPCThreadState::self()->joinThreadPool(); 12 }
Static: private/binder/Static.h
- Static.h
1 #include <utils/threads.h> 2 #include <binder/IBinder.h> 3 #include <binder/IMemory.h> 4 #include <binder/ProcessState.h> 5 #include <binder/IPermissionController.h> 6 #include <binder/IServiceManager.h> 7 namespace android { 8 // For ProcessState.cpp 9 extern Mutex gProcessMutex; 10 extern sp<ProcessState> gProcess; 11 // For ServiceManager.cpp 12 extern Mutex gDefaultServiceManagerLock; 13 extern sp<IServiceManager> gDefaultServiceManager; 14 extern sp<IPermissionController> gPermissionController; 15 }
- Static.cpp
1 #include <private/binder/Static.h> 2 #include <binder/IPCThreadState.h> 3 #include <utils/Log.h> 4 namespace android { 5 // ------------ ProcessState.cpp 6 Mutex gProcessMutex; 7 sp<ProcessState> gProcess; 8 class LibUtilsIPCtStatics 9 { 10 public: 11 LibUtilsIPCtStatics() 12 { 13 } 14 15 ~LibUtilsIPCtStatics() 16 { 17 IPCThreadState::shutdown(); 18 } 19 }; 20 static LibUtilsIPCtStatics gIPCStatics; 21 // ------------ ServiceManager.cpp 22 Mutex gDefaultServiceManagerLock; 23 sp<IServiceManager> gDefaultServiceManager; 24 sp<IPermissionController> gPermissionController; 25 }
- When we create new process and call main()..........,the gloable vairables will be created
Mutex gProcessMutex; sp<ProcessState> gProcess; Mutex gDefaultServiceManagerLock; sp<IServiceManager> gDefaultServiceManager; sp<IPermissionController> gPermissionController;
Threads
- android.threads wrap something related to thread using linux's pthread.h
- threads.h
- Threads.cpp
- The definition of Mutex in thread
- Mutex
- The interface of thread
- Thread
- Create a thread on linux as global function
1 inline bool createThread(thread_func_t f, void *a) { 2 return androidCreateThread(f, a) ? true : false; 3 } 4 int androidCreateThread(android_thread_func_t fn, void* arg) 5 { 6 return createThreadEtc(fn, arg); 7 } 8 9 // Create thread with lots of parameters 10 inline bool createThreadEtc(thread_func_t entryFunction, 11 void *userData, 12 const char* threadName = "android:unnamed_thread", 13 int32_t threadPriority = PRIORITY_DEFAULT, 14 size_t threadStackSize = 0, 15 thread_id_t *threadId = 0) 16 { 17 return androidCreateThreadEtc(entryFunction, userData, threadName, 18 threadPriority, threadStackSize, threadId) ? true : false; 19 } 20 static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc; 21 int androidCreateRawThreadEtc(android_thread_func_t entryFunction, 22 void *userData, 23 const char* threadName, 24 int32_t threadPriority, 25 size_t threadStackSize, 26 android_thread_id_t *threadId) 27 { 28 pthread_attr_t attr; 29 pthread_attr_init(&attr); 30 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 31 #ifdef HAVE_ANDROID_OS /** valgrind is rejecting RT-priority create reqs */ 32 if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) { 33 // We could avoid the trampoline if there was a way to get to the 34 // android_thread_id_t (pid) from pthread_t 35 thread_data_t* t = new thread_data_t; 36 t->priority = threadPriority; 37 t->threadName = threadName ? strdup(threadName) : NULL; 38 t->entryFunction = entryFunction; 39 t->userData = userData; 40 entryFunction = (android_thread_func_t)&thread_data_t::trampoline; 41 userData = t; 42 } 43 #endif 44 if (threadStackSize) { 45 pthread_attr_setstacksize(&attr, threadStackSize); 46 } 47 errno = 0; 48 pthread_t thread; 49 int result = pthread_create(&thread, &attr,android_pthread_entry)entryFunction, userData); 50 pthread_attr_destroy(&attr); 51 if (result != 0) { 52 LOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n" 53 "(android threadPriority=%d)", 54 entryFunction, result, errno, threadPriority); 55 return 0; 56 } 57 // Note that *threadID is directly available to the parent only, as it is 58 // assigned after the child starts. Use memory barrier / lock if the child 59 // or other threads also need access. 60 if (threadId != NULL) { 61 *threadId = (android_thread_id_t)thread; // XXX: this is not portable 62 } 63 return 1; 64 }
- Create a new thread on win32 as global function
1 int androidCreateRawThreadEtc(android_thread_func_t fn, 2 void *userData, 3 const char* threadName, 4 int32_t threadPriority, 5 size_t threadStackSize, 6 android_thread_id_t *threadId) 7 { 8 return doCreateThread( fn, userData, threadId); 9 } 10 static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_id_t *id) 11 { 12 HANDLE hThread; 13 struct threadDetails* pDetails = new threadDetails; // must be on heap 14 unsigned int thrdaddr; 15 pDetails->func = fn; 16 pDetails->arg = arg; 17 #if defined(HAVE__BEGINTHREADEX) 18 hThread = (HANDLE) _beginthreadex(NULL, 0, threadIntermediary, pDetails, 0,&thrdaddr); 19 if (hThread == 0) 20 #elif defined(HAVE_CREATETHREAD) 21 hThread = CreateThread(NULL, 0,LPTHREAD_START_ROUTINE) threadIntermediary, 22 (void*) pDetails, 0, (DWORD*) &thrdaddr); 23 if (hThread == NULL) 24 #endif 25 { 26 LOG(LOG_WARN, "thread", "WARNING: thread create failed\n"); 27 return false; 28 } 29 #if defined(HAVE_CREATETHREAD) 30 /** close the management handle */ 31 CloseHandle(hThread); 32 #endif 33 if (id != NULL) { 34 *id = (android_thread_id_t)thrdaddr; 35 } 36 return true; 37 }
- Create a thead in thread object
1 status_t Thread::run(const char* name, int32_t priority, size_t stack) 2 { 3 Mutex::Autolock _l(mLock); 4 if (mRunning) { 5 // thread already started 6 return INVALID_OPERATION; 7 }) 8 mStatus = NO_ERROR; 9 mExitPending = false; 10 mThread = thread_id_t(-1); 11 mHoldSelf = this; 12 mRunning = true; 13 bool res; 14 if (mCanCallJava) { 15 res = createThreadEtc(_threadLoop, 16 this, name, priority, stack, &mThread); 17 } else { 18 res = androidCreateRawThreadEtc(_threadLoop, 19 this, name, priority, stack, &mThread); 20 } 21 if (res == false) { 22 mStatus = UNKNOWN_ERROR; // something happened! 23 mRunning = false; 24 mThread = thread_id_t(-1); 25 mHoldSelf.clear(); // "this" may have gone away after this. 26 27 return UNKNOWN_ERROR; 28 } 29 return NO_ERROR; 30 } 31 int Thread::_threadLoop(void* user) 32 { 33 Thread* const self = static_cast<Thread*>(user); 34 sp<Thread> strong(self->mHoldSelf); 35 wp<Thread> weak(strong); 36 self->mHoldSelf.clear(); 37 #ifdef HAVE_ANDROID_OS 38 // this is very useful for debugging with gdb 39 self->mTid = gettid(); 40 #endif 41 bool first = true; 42 43 do { 44 bool result; 45 if (first) { 46 first = false; 47 self->mStatus = self->readyToRun(); 48 result = (self->mStatus == NO_ERROR); 49 50 if (result && !self->exitPending()) { 51 result = self->threadLoop(); 52 } 53 } else { 54 result = self->threadLoop(); 55 } 56 // establish a scope for mLock 57 { 58 Mutex::Autolock _l(self->mLock); 59 if (result == false || self->mExitPending) { 60 self->mExitPending = true; 61 self->mRunning = false; 62 // clear thread ID so that requestExitAndWait() does not exit if 63 // called by a new thread using the same thread ID as this one. 64 self->mThread = thread_id_t(-1); 65 // note that interested observers blocked in requestExitAndWait are 66 // awoken by broadcast, but blocked on mLock until break exits scope 67 self->mThreadExitedCondition.broadcast(); 68 break; 69 } 70 } 71 strong.clear(); 72 strong = weak.promote(); 73 } while(strong != 0); 74 return 0; 75 }
ProcessState
- ProcessState.h
- ProcessState.h
- ProcessState.cpp
- ProcessState.cpp
- Create a new object of ProcessState and assign to global sp<ProcessState> gProcess;
1 sp<ProcessState> ProcessState::self() 2 { 3 if (gProcess != NULL) 4 return gProcess; 5 AutoMutex _l(gProcessMutex); 6 if (gProcess == NULL) 7 gProcess = new ProcessState; 8 return gProcess; 9 }
- Open the binder to get handler of binder
1 static int open_driver()//every process where the service run or client run will have its own default binder's handle 2 { 3 int fd = open("/dev/binder", O_RDWR); 4 if (fd >= 0) { 5 fcntl(fd, F_SETFD, FD_CLOEXEC); 6 int vers; 7 status_t result = ioctl(fd, BINDER_VERSION, &vers); 8 if (result == -1) { 9 LOGE("Binder ioctl to obtain version failed: %s", strerror(errno)); 10 close(fd); 11 fd = -1; 12 } 13 if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) { 14 LOGE("Binder driver protocol does not match user space protocol!"); 15 close(fd); 16 fd = -1; 17 } 18 size_t maxThreads = 15; 19 result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); 20 if (result == -1) { 21 LOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); 22 } 23 } else { 24 LOGW("Opening '/dev/binder' failed: %s\n", strerror(errno)); 25 } 26 return fd; 27 }
- PrecessState's Constructor
- PoolThread of ProcessState
1 class PoolThread : public Thread 2 { 3 public: 4 PoolThread(bool isMain) 5 : mIsMain(isMain) 6 { 7 } 8 protected: 9 virtual bool threadLoop()//override threadLoop of Thread 10 { 11IPCThreadState::self()->joinThreadPool(mIsMain); 12 return false; 13 } 14 const bool mIsMain; 15 };
- Start thread pool
1 void ProcessState::startThreadPool() 2 { 3 AutoMutex _l(mLock); 4 if (!mThreadPoolStarted) { 5 mThreadPoolStarted = true; 6spawnPooledThread(true); 7 } 8 } 9 void ProcessState::spawnPooledThread(bool isMain) 10 { 11 if (mThreadPoolStarted) { 12 int32_t s = android_atomic_add(1, &mThreadPoolSeq); 13 char buf[32]; 14 sprintf(buf, "Binder Thread #%d", s); 15 LOGV("Spawning new pooled thread, name=%s\n", buf); 16 sp<Thread> t = new PoolThread(isMain); 17 t->run(buf);//thread run by calling threadLoop
18 } 19 }
IPCThreadState
- IPCThreadState.h
- IPCThreadState.h
- IPCThreadState.cpp
- IPCThreadState.cpp
- IPCThread.Self()
1 static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; 2 static bool gHaveTLS = false; 3 static pthread_key_t gTLS = 0; 4 static bool gShutdown = false; 5 static bool gDisableBackgroundScheduling = false; 6 IPCThreadState* IPCThreadState::self() 7 { 8 if (gHaveTLS) { 9 restart: 10 const pthread_key_t k = gTLS; 11 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); 12 if (st) return st; 13 return new IPCThreadState; 14 } 15 if (gShutdown) return NULL; 16 pthread_mutex_lock(&gTLSMutex); 17 if (!gHaveTLS) { 18 if (pthread_key_create(&gTLS, threadDestructor) != 0) { 19 pthread_mutex_unlock(&gTLSMutex); 20 return NULL; 21 } 22 gHaveTLS = true; 23 } 24 pthread_mutex_unlock(&gTLSMutex); 25 goto restart; 26 } 27 IPCThreadState::IPCThreadState() 28 : mProcess(ProcessState::self()), 29 mMyThreadId(androidGetTid()), 30 mStrictModePolicy(0), 31 mLastTransactionBinderFlags(0) 32 { 33 pthread_setspecific(gTLS, this); 34 clearCaller(); 35 mIn.setDataCapacity(256); 36 mOut.setDataCapacity(256); 37 }
- joinThreadPool
1 void IPCThreadState::joinThreadPool(bool isMain) 2 { 3 LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid()); 4 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); 5 androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT); 6 status_t result; 7 do { 8 int32_t cmd; 9 if (mIn.dataPosition() >= mIn.dataSize()) { 10 size_t numPending = mPendingWeakDerefs.size(); 11 if (numPending > 0) { 12 for (size_t i = 0; i < numPending; i++) { 13 RefBase::weakref_type* refs = mPendingWeakDerefs[i]; 14 refs->decWeak(mProcess.get()); 15 } 16 mPendingWeakDerefs.clear(); 17 } 18 numPending = mPendingStrongDerefs.size(); 19 if (numPending > 0) { 20 for (size_t i = 0; i < numPending; i++) { 21 BBinder* obj = mPendingStrongDerefs[i]; 22 obj->decStrong(mProcess.get()); 23 } 24 mPendingStrongDerefs.clear(); 25 } 26 } 27 // now get the next command to be processed, waiting if necessary 28 result = talkWithDriver(); 29 if (result >= NO_ERROR) { 30 size_t IN = mIn.dataAvail(); 31 if (IN < sizeof(int32_t)) continue; 32 cmd = mIn.readInt32(); 33 IF_LOG_COMMANDS() { 34 alog << "Processing top-level Command: " 35 << getReturnString(cmd) << endl; 36 } 37 result = executeCommand(cmd); 38 } 39 androidSetThreadSchedulingGroup(mMyThreadId, ANDROID_TGROUP_DEFAULT); 40 if(result == TIMED_OUT && !isMain) { 41 break; 42 } 43 } while (result != -ECONNREFUSED && result != -EBADF); 44 LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n", 45 (void*)pthread_self(), getpid(), (void*)result); 46 mOut.writeInt32(BC_EXIT_LOOPER); 47 talkWithDriver(false); 48 }
沒有留言:
張貼留言