Barrelfish研究——SKB
什么是SKB
在标准Linux上,如果想知道你的CPU有几个核,该怎么办?方法有很多,最标准的做法就是使用
cat /proc/cpuinfo
就可以一目了然。那么,在Barrelfish上如何解决这个问题呢?这时就需要用到SKB了。
SKB全名是System Knowledge Base,可以直译为“系统知识基地”,从字面上就可以很容易理解它的功能。SKB是一个系统服务,它维护着一个“数据库”,其中包含了系统的各种静态信息(例如设备信息)与动态信息(例如线程信息),以供用户进行操作(主要是查询)。
如何使用SKB
在Barrelfish上使用SKB主要有两种方法,一种是调用C语言的接口,另一种是在fish中使用SKB命令。还是以查询CPU核数为例,两种解决方法如下:
方法一
#include <stdio.h>
#include <barrelfish/barrelfish.h>
#include <skb/skb.h>
int main(int argc, char **argv)
{
errval_t err = skb_client_connect();
int number_of_cores = 0;
if (err_is_fail(err)) {
DEBUG_ERR(err, "skb_client_connect failed");
return err;
}
err = skb_execute("available_nr_cores(Nr),write(Nr)");
if (err_is_fail(err)) {
DEBUG_ERR(err, "skb_execute available_nr_cores(Nr),write(Nr) failed");
return err;
}
err = skb_read_output("%d", &number_of_cores);
if (err_is_fail(err)) {
DEBUG_ERR(err, "skb_read_output failed");
return err;
}
printf("Number of cores: %d\n", number_of_cores);
return 0;
}
Number of cores: 2
方法二
> skb available_nr_cores(Nr),write(Nr).
SKB returned: 2
对比
总共提供多少种调用
SKB的实现是基于ECLiPSe CLP,在usr/skb/programs/目录下,有许多后缀为.pl的Prolog文件。SKB的所有调用都在这些Prolog文件中。
目前Barrelfish关于SKB的文档尚不完整,并没有一个完整的列表告诉我们目前有哪些已经支持的调用(官方提供了一个skb.pdf,其中有一个列表,但大都已经过时)。所以,我们可以用在usr/skb/programs/目录下寻找,需要的调用。
例如,欲获得pci信息,在./usr/skb/programs/device_db.pl文件中可以找到一个关于pci驱动的调用:
find_pci_driver(PciInfo, DriverInfo) :-
在fish中尝试调用:
> skb find_pci_driver(Pci,Driver),write(Pci),write(Driver).
SKB returned: pci_card(32902, 4221, _254, _255, _256)driver(0, e1000n)
查阅pci database,即可得到pci的信息:
Vendor Id: 0x8086
Short Name: Intel
Device Id: 0x0500
Chip Number: E8870
Chip Description: Processor Bus Controller
添加自定义的调用
usr/skb/programs/目录下新建文件my_queries.pl,内容如下:
% get cpu core platform list
core_list_platform(CoreList):-
findall(corename(ID,Platform), corename(ID,Platform,_), CoreList).
在build目录下执行:
make rehake
make sim
启动进入fish后,在Barrelfish文件系统中如果能找到/skb/my_queries.pl,说明加载成功。在fish中执行:
skb [my_queries],core_list_platform(List),write(List).
即可看到屏幕上的打印信息为:
SKB returned: [corename(0, x86_64), corename(1, x86_64)]
说明我们自己实现的调用已经被成功执行。