haskell - 连接到 GHC 运行时系统

标签 haskell functional-programming runtime transactional-memory

我一直在研究如何在 Haskell 中实现事务内存,但我不确定我是否理解向程序员公开的 STM 操作如何 Hook 到用 C 编写的运行时系统函数中。在 ghc/libraries/base/GHC/Conc/Sync.hs 的 git repo,我看到以下定义:

-- |A monad supporting atomic memory transactions.
newtype STM a = STM (State# RealWorld -> (# State# RealWorld, a #))
            deriving Typeable

-- |Shared memory locations that support atomic memory transactions.
data TVar a = TVar (TVar# RealWorld a)
          deriving Typeable

-- |Create a new TVar holding a value supplied
newTVar :: a -> STM (TVar a)
newTVar val = STM $ \s1# ->
    case newTVar# val s1# of
         (# s2#, tvar# #) -> (# s2#, TVar tvar# #)

然后在 ghc/rts/PrimOps.cmm 中,我看到以下 C-- 定义:

stg_newTVarzh (P_ init){
  W_ tv;

  ALLOC_PRIM_P (SIZEOF_StgTVar, stg_newTVarzh, init);

  tv = Hp - SIZEOF_StgTVar + WDS(1);
  SET_HDR (tv, stg_TVAR_DIRTY_info, CCCS);

  StgTVar_current_value(tv) = init;
  StgTVar_first_watch_queue_entry(tv) = stg_END_STM_WATCH_QUEUE_closure;
  StgTVar_num_updates(tv) = 0;

  return (tv);
}

我的问题:

  1. (# s2#, TVar tvar# #) 中第一个和最后一个# 是什么意思。我之前读到过,在变量后放置一个 # 只是一种命名约定,表示某些内容未装箱,但它本身意味着什么?
  2. 我们如何从 newTVar#stg_newTVarzh?似乎我错过了这两者之间的另一个定义。编译器是否将 newTVar# 重写为对列出的 C 函数的调用?
  3. C-- 代码中的P_W_是什么?

我只能在 ghc/compiler/prelude/primops.txt.pp

中找到另一处 newTVar#
primop  NewTVarOp "newTVar#" GenPrimOp
   a
    -> State# s -> (# State# s, TVar# s a #)
 {Create a new {\tt TVar\#} holding a specified initial value.}
with
 out_of_line  = True
 has_side_effects = True

根据 https://ghc.haskell.org/trac/ghc/wiki/Commentary/PrimOps ,这就是原语的定义方式,以便编译器了解它们。

最佳答案

(# s2#, TVar tvar# #) 是一个 unboxed tuple .

名称 stg_newTVarzh 是从:

  • stg_ 前缀,这是整个 GHC 运行时通用的,代表 spineless-tagless G-machine,一种评估函数式语言的抽象机器;

  • newTVarnewTVar#的第一部分;

  • 最后的zh,也就是所谓的z-encoding #:此编码生成一个可供链接器/ABI 在所有平台中使用的纯名称,删除哈希 (#) 等有趣的字符。

关于haskell - 连接到 GHC 运行时系统,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30903526/

相关文章:

haskell - let 如何与 Haskell 中更高级别的类型交互?

haskell - 在 Haskell 中,当你只传递一个列表时,map 函数是什么意思?

c - C中准确的运行时间计算

.net - 访问 Form 上的成员可能会导致运行时异常,因为它是 marshal-by-reference 类的字段

haskell - 如何通过 Haskell 的 optparse-applicative 使用具有多个值的选项

haskell - 变压器组中 ST 类型的问题

functional-programming - 在对象嵌套数组中查找对象的路径

scala - 与 monad 不同的 monad-transformer 是什么?

haskell - 存在函数依赖关系时类型推断如何工作

javascript - 在运行时动态获取javascript中数组成员的名称