一進入 ruby_init_stack()
就先設定 native_main_thread.id,推測每個 thread 都會有自己的 stack。因為 thread 的定義隨 OS 各自有不同,這邊先保留模糊的概念。
native_main_thread.id = pthread_self();
以 linux 為例, pthread_self()
會回傳 calling thread 的 ID,man 指出 ID 與 pthread_create()
回傳值相同。查 code 看到 YARV 在開 thread 時是呼叫 pthread_create
。
native_main_thread
是 static variable。根據 C11 spec 在 initialization 時的規則,stack_maxsize 會設為 0。
If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
所以如果是 multi-thread 建立的時候,進來只會設 id 就離開。在 main() 第一次執行時會用 get_main_stack
的實作取得 stackaddr 與 size
void* stackaddr;
size_t size;
if (get_main_stack(&stackaddr, &size) == 0) {
native_main_thread.stack_maxsize = size;
native_main_thread.stack_start = stackaddr;
reserve_stack(stackaddr, size);
goto bound_check;
}
在 get_main_stack
的定義可以發現 linux 和 macOS 不同,thread 是由 OS 實作,使用時應該要瞭解 runtime OS 的定義。因為通常 rails server 都跑在 linux 上,後續探討選擇以 linux 為主。thread 的 stack 其實都不大,所以之前認為 compile 的 AST 會放在裡面應該是錯誤的想法。接下來看 ruby_init
裡呼叫的 ruby_setup
看有沒有相關的邏輯