You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
这个线程栈由一次低优先级发生的陷入创建,在栈上压入控制流上下文后开始处理,此时使用的栈空间称为 0 级陷入栈。若处理过程中再次发生陷入,栈指针不动,当前上下文直接压到栈上后开始处理,此时使用的栈空间称为 1 级陷入栈。以此类推,若发生 n 次嵌套陷入后,无法处理,需要挂起等待,则 n 级嵌套处理必须退出,栈顶存放用于恢复 n-1 级陷入处理的 n 级上下文,然后一步恢复另一个线程的最后一个上下文。此时,刚刚创建的那个线程上,共有 n 个内核陷入和一个低权限陷入不能处理,处于挂起状态。只有原来的 n 级陷入处理完成才能依次恢复。
479
+
480
+
这种逐级压到同一个栈的方式可以节省栈空间的开销,也会减少同权限陷入不得不换栈导致的缓存失效问题。但也会压住之前到来的陷入无法处理,必须跟着挂起。尤其是新到来的同权限陷入通常和被压住的陷入没什么关系,很可能带来死锁。所以,如果第 n 级上下文无法立即处理,可以选择创建一个挂起状态的新线程,然后恢复处理 n-1 级陷入。只需分配一个新的栈空间,拷贝 n 级陷入栈的数据到新栈上,然后构造一个可恢复这个陷入栈的上下文即可。
481
+
482
+
这种从挂起创建的线程栈具有这样的结构:
483
+
484
+
| 栈底(高地址)
485
+
| -
486
+
| 无效上下文
487
+
| n 级陷入栈
488
+
| n+1 级嵌套上下文
489
+
490
+
从这个线程恢复时,恢复 n+1 级嵌套上下文将继续执行 n 级陷入栈的处理流程,完成后识别到下一个要恢复的是一个无效的上下文,可以执行一个调度流程,这个栈空间则可回收。
0 commit comments