命令字!ready

基本功能:读取cpu中的runqueues与所属进程与线程
基本语法:ready -f 1(flags) -c 1(cpu_no)

用法描述

首先需要用load命令加载ndx文件,完整命令为 .load ndx
然后再输入命令 !ndx.ready -f 1(flags) -c (cpu_no)
参数flags会指定打印方式,例如只打印rq中的一些字段,或者是只打印CPU的tasklist,threadlist,而cpu_no会指定打印哪个CPU。

例如要显示所有的cpu_task:
!ndx.ready -f 1
要显示所有的cpu_runqueues
!ndx.ready -f 2
显示指定cpu数据
!ndx.ready -f 2 -c 0

开发过程

1.首先开发的是每个CPU中的rq结构体的字段。

我们首先得获取rq,也就是runqueus的偏移,然后读取每个CPU储存信息的区域的首地址。从而获得rq_address。
具体到其中的信息,我们依旧采用获取偏移,计算地址,再根据地址读取相应的值,之后再依次进行打印。


实现步骤可以参照linux内核源代码中的print_cpu函数。
值得注意,一些信息是储存在rq包含的结构体当中,这时就得取该结构体的偏移,再取读取字段在该结构体中的偏移,双重偏移。

结果如下图所示,-f 2表示打印runqueues信息。

2.关于打印各cpu所属进程与线程的信息。

该部分信息储存在task_struct的结构体中,需要先读取一个进程结构体的首地址。而task_struct结构体是环形链表形式储存的。

由于该指针会指向下一个task结构体,固需要减去其偏移量。

第一次所用的方法为直接设置一个循环,传入首地址。在需要读取的时候就遍历循环。后觉太慢,遂定义结构体ndx_task,在用户输入指令之后,若需要获取进程信息,则一次行遍历所有的进程与线程。将符合条件的储存进vector中。

3.关于各个进程所属的线程

一个进程关于所属线程的循环如图所示。首进程结构体含有一个指向signal_struct的指针。然后signal中的thread_node为一个储存有两个指针的双向链表结构,有一个指向该进程本身,另一个则指向该进程的最后一个线程(注意,线程的信息也是用task_struct结构体储存的)。

这样的话只要创立两个循环,一遍历进程,二遍历线程,且由于进程也在该环中,故不用单独读取进程。

以下是我们的代码实现:

4.实例测试;

下图是我在GBK8中跑了一个程序,并绑定到1号核心上。

结果如下图,on_cpu表示其正在cpu上运行。State表示正在其运行状态,由于我们设置了过滤,只打印0状态的,也就是正在排队状态的。

作者:施国瑞  创建时间:2023-09-29 11:15
最后编辑:施国瑞  更新时间:2024-04-26 11:16