女媧,在 FxOS 裡捏 process

在 Firefox OS 中,有一個類似 Android Zygote 的 process,利用  fork()  複製出應用程序並在這些應用程序間透過 copy-on-write 共享記憶體分頁。這麼做有助於降低記憶體用量和更快速的啟動應用程式。她的名字叫 Nuwa – 女媧 [1][2]

不過, fork()  有一個限制是只有呼叫  fork()  的 thread 會被保留下來,可是 FxOS 是 multi-threaded,那究竟女媧是怎麼"捏"出 process 來的呢?讓我們一起來看看。

首先,FxOS 透過 ld 的 wrap 功能 [3] 包裝了某些函式。例如,所有對  pthread_create()  的呼叫,實際上會呼叫定義在 Nuwa.cpp [4] 裡的 __wrap_pthread_create() 。這樣一來,我們可以對這些函式增加額外的行為,且不影響原本使用這些函式的程式。

在更深入以前,我想先解釋一下大致上的概念。FxOS 會讓需要被重建的 threads 在 Nuwa process 裡暫停下來,並記錄下它們暫停前的狀態。稍後在 fork 出來的 child process 裡重建新的 threads 後,讓它們從剛剛暫停前的狀態繼續往下執行。沒錯,我們將會用上  setjmp()  /  longjmp()  來記錄並繼續,讓我們接著往下看。

準備動作

pthread_create()  在女媧 process 裡被呼叫時, __wrap_pthread_create()  會 new 出一個 thread info structure 來儲存相關資訊,並把它加入一個 sAllThreads 的 linked list 中。除此之外,還會  malloc  一個 stack 給即將被創建的 thread 使用。這個 stack 是必須的,假設我們沒有自己  malloc  一個 stack 的話,在  fork()  後的 child process 裡,這個 thread 的 stack 會消失,我們就沒有辦法讓它在 child process 裡繼續接著往下執行了。實際的 thread 函式稍後會在  _thread_create_startup()  中呼叫。

暫停

當 thread 開始執行並呼叫 epoll_wait() , poll() , pthread_mutex_lock() , pthread_cond_wait() , 和  pthread_cond_timedwait()  其中任一函式時,它會執行  setjmp()  並對一個已經被 locked 的 mutex 呼叫 pthread_mutex_lock()  讓整個 thread 暫停下來。這些動作在對應的 wrapper 函式中,由 macro THREAD_FREEZE_POINT*  完成。

fork() 並繼續

稍後當一個 child process 從女媧  fork()  出來, RecreateThreads()  會在 child process 中被呼叫,並對 sAllThreads 中每一個有  TINFO_FLAG_NUWA_SUPPORT  flag 的 thread 進行重建。注意 thread 的 stack 會被指定是我們剛解釋過的 malloc’d stack。在這裡,thread 函式是 thread_recreate_startup() ,它將重設 thread 的名字,紀錄重建後的 pthread ID 和 native thread ID,呼叫 setjmp() ,接著  longjmp()  回到稍早該 thread 在女媧 process 裡  setjmp()  的地方,繼續往下執行。當原始的 thread 函式結束後,接著會回到  thread_create_startup()  再  longjmp()  回到剛剛在  thread_recreate_startup()  設下的 setjmp() 。透過下圖我們可以更清楚的了解整個準備-暫停-繼續的流程:
recreate

也許眼尖的網友會注意到還有一些其他的 pthread 函式也被包裝,例如: pthread_join() 。這是因為在女媧 process 裡創建的 thread,其 ID 可能被儲存在某個變數中而被 child process 繼承。如果在 child process 中呼叫  pthread_join()  且傳入該 ID,它需要被替換成重建後的 pthread ID,否則將會產生錯誤,因此  pthread_join()  才會也被包裝。

希望這篇文章能讓大家對女媧的運作有些許的了解。:)

[1] http://en.wikipedia.org/wiki/N%C3%BCwa
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=771765
[3] http://ftp.gnu.org/pub/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html
[4] http://hg.mozilla.org/mozilla-central/file/7297cfffd91c/mozglue/build/Nuwa.cpp

您可能也會喜歡

目前找不到相關文章

對此文章發表回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *