如何扩展GHC的线程状态对象

13

我想在线程状态对象(TSO)中添加两个额外的StgWord32类型字段。根据我在GHC-Wiki上找到的信息和查看源代码,我已经扩展了/includes/rts/storage/TSO.h中的结构体并更改了创建不同偏移量的程序(创建DerivedConstants.h)。编译器、RTS和一个简单的应用程序都重新编译成功,但在执行结束时(在hs_exit_中),垃圾收集器报错:

 internal error: scavenge_stack: weird activation record found on stack: 45

我猜这与cmm和/或STG实现细节有关(偏移量是由于在级别上结构体不可见生成的,如果我错了请纠正我)。字段的顺序重要吗?我错过了应该更改的文件吗?

我使用编译器和运行时系统的调试版本,在64位架构上使用相当陈旧的ghc 6.12.3。对于有关ghc 6和7之间TSO处理差异的相关文档和评论的任何提示也非常欢迎。


1
你想要达到什么目的?也许有一种不同、更简单的方法。 - Petr
我想在每个线程中携带一些额外的信息,例如父线程的ID,并在进行负载平衡决策时使用它。 - jev
2个回答

2
你所遇到的错误来自于:ghc/rts/sm/Scav.c。具体来说,是在第1917行:
 default:
    barf("scavenge_stack: weird activation record found on stack: %d", (int)(info->i.type));

看起来你还需要修改ClosureTypes.h,可以在ghc/includes/rts/storage中找到它。这个文件似乎包含了堆对象可能出现的不同类型的头信息。我也遇到了一些奇怪的引导错误,如果我尝试使用stage-1编译器重新构建,我会得到你提到的错误,但如果我进行一次干净的构建,那么它就可以编译成功。


谢谢您的建议。我想知道为什么您认为我应该引入新的闭包类型?我想保留标准的TSO闭包类型,但是向TSO对象添加一个字段。在我看来,一些偏移量可能不正确,信息字段可能会被意外覆盖。 - jev
转念一想,如果你添加的新字段不是指针,那么你可能不需要创建一个新的堆对象。你尝试过进行干净构建吗?这在过去曾经为我解决了这个问题。 - Matt
不幸的是,重新编译并没有帮助(我也不能假设有一个可用的第二阶段编译器)。 - jev

1
一个对我来说足够好的解决办法是为每个Capability引入一个单独的数据结构,用于保存每个轻量级线程的附加信息。我使用了一个HashTable(请参见rts/Hash.h.c),将线程ID映射到自定义信息结构。这些条目是在从spark创建线程时(在schduleActiveteSpark中)添加的。

对于小型程序,测量条目和表的创建、插入、查找和销毁所需的时间显示出了可忽略的开销。主要的开销来源于实际使用信息,最好将其保留在最内层的调度器循环之外。对于THREADED_RTS构建,需要确保其他Capabilities不会访问不属于它们自己的表格(或者如果需要这样的访问,则使用mutex,这是潜在的额外开销源)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接