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

How to extend GHC's Thread State Object

我想向 线程状态对象 (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 and/or STG 实现细节相关(由于结构在 cmm 级别不可见,因此生成偏移量,如果我'我错了)。字段的顺序重要吗?我错过了应该更改的文件吗?

我在 64 位架构上使用编译器和 RTS 的 debug 版本和相当过时的 ghc 6.12.3。对相关文档和评论的任何提示 也欢迎讨论 ghc 6 和 7 关于 TSO 处理的区别。

您收到的错误来自: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 中找到它。该文件似乎包含可以出现在堆 object 中的不同种类的 headers。我也 运行 遇到了一些奇怪的引导错误,如果我尝试使用 stage-1 编译器重建,我会得到你提到的错误,但如果我做一个干净的构建,那么它编译得很好。

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

为条目的创建、插入、查找和销毁计时,table 显示小程序的开销可以忽略不计。主要开销来自信息的实际使用,理想情况下应将其保留在最内层的调度程序循环之外。对于 THREADED_RTS 构建,需要确保其他 Capabilities 不会访问不属于他们自己的 table(或者如果需要此类访问,则使用 mutex,这是潜在的来源额外的开销)。