Page 83 - 《软件学报》2025年第8期
P. 83

3506                                                       软件学报  2025  年第  36  卷第  8  期


                 保其排他性. 第    5  个算子表示锁的状态分为        3  种: 开放状态, 半开放状态和关闭状态, 半开放状态锁的状态数组中
                 所有位置均为     false. 这个不变式确保了锁在各种操作         (如获取和释放) 中的正确性和一致性. 可以看以下例子理解
                 详细过程.
                    假设锁的容量为      3, 当前状态如下.
                    ● o= 0, 表示当前锁的持有者位置.
                    ● i = 2, 表示有两个线程在等待队列中.
                    ● xs = [true, false, false], 表示锁的状态数组.
                    在这种情况下, 不变式 lock_inv 确保:
                    ● 锁的状态数组长度为        3.
                    ● key  值 nextPtr 存储的值为 0 + 2 = 2.
                    ● 锁的状态数组 arr 存储当前状态 [true, false, false].
                    ● 锁的拥有者是位置       0, 当前的队列范围是 [0, 2).
                    ● 锁的状态为开放状态, 即 xs = list_with_one(3, 0).

                 4.3.2    任务管理与调度模块建模
                    在任务管理与调度模块, 某内核主要涉及一个主循环, 所有的调度等操作都存在于主循环中, 调度器中包括                                 3
                 个函数.
                    (1) set_current_thread: 选择线程队列中的第  1  个  Ready  线程作为当前线程, 无可用线程时进入待机等待中断.
                    (2) run_current_thread: 循环调用  thread  的  run  函数执行当前线程, 线程执行中遇到系统调用、中断、异常后
                 run  函数退出, 再调用   handle_user_trap  函数处理陷入内核原因. 完成处理后根据线程状态进行不同处理:
                    ● Ready: 处理完当前陷入线程可继续执行.
                    ● Wait: 线程执行异步等待系统调用陷入内核, 在内核中被设为                Wait 状态.
                    ● Suspended: 线程运行时遇到时钟中断陷入内核, 线程时间片用完时被设为                  Suspended  状态.
                    ● Exit: 线程执行  ky_proc_exit 系统调用陷入内核, 在内核中被设为        Exit 状态.
                    (3) clear_current_thread: 根据线程状态清除当前线程.
                    ● Suspended: 说明线程已经经历了中止, 将状态改回          Ready, 再重新加入队尾.
                    ● Wait: 将在协程函数中将状态改回        Ready (后续章节介绍), 再重新加入队尾.
                    ● Exit: 说明线程已终止, 无需加入队尾, 此时需要根据终止的线程是否为根线程, 进行相应的清理操作.
                    在内核主循环的最后, 循环依次调用上述              3  个函数. 当线程队列为空时, 系统进入待机. 每次调用完             3  个函数
                 后, 执行一次协程调度器.
                    我们的建模是从代码层面上建模的, 下面介绍线程状态清除的建模. 其余建模与此类似.
                    对于  clear_current_thread, 并且在仅考虑  GhostArc 的情况下, 在执行前的状态确定如下, 表示当前必须要有一
                 个正在运行的线程.

                                      pre_clear_current_thread(s) := ∃t, s.current_thread = Some(t).
                    在执行后状态确定为:

                  post_clear_current_thread(s) := ∃t, s.current_thread = Some(t)∧
                 (match t.state with

                             ′
                 |Suspended => s .suspended_queue = t :: s.suspended_queue∧ s .current_thread = None∧update_ref_count(s, s )
                                                                                                    ′
                                                                ′

                                                  ′
                         ′
                 |Wait => s .wait_queue = t :: s.wait_queue∧ s .current_thread = None∧update_ref_count(s, s )
                                                                                      ′

                                                            ′
                 |Exit => s .current_thread = None∧remove_re f_count(s, s )
                        ′

                                                                                          ′
                 |Ready => s .ready_queue = t :: s.ready_queue∧ s .current_thread = None∧update_ref_count(s, s )
                                                      ′
                          ′
                 end)
   78   79   80   81   82   83   84   85   86   87   88