3

Haskell でトランザクション メモリがどのように実装されているかを調べてきましたが、プログラマーに公開された STM 操作が C で記述されたランタイム システム関数にどのようにフックされるかを理解できていませんghc/libraries/base/GHC/Conc/Sync.hs。git リポジトリには、次の定義が表示されます。

-- |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# #). 変数の後に aを置くことは、何かがボックス化されていないことを示す命名規則にすぎないことを以前に読んだことが#ありますが、それ自体の場合はどういう意味ですか?
  2. newTVar#からまでどうやって行くのstg_newTVarzh?これら2つの間に別の定義が欠けているようです。コンパイラはnewTVar#リストされた C 関数への呼び出しに書き直しますか?
  3. C コードのP_andは何ですか?W_

他に 1 つしか見つかりませんでしnewTVar#ghc/compiler/prelude/primops.txt.pp

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によると、これはプリミティブがどのように定義され、コンパイラーがそれらについて認識できるようにするかです。

4

1 に答える 1

3

(# s2#, TVar tvar# #)ボックス化されていないタプルです。

名前stg_newTVarzhは次のものから作成されます。

  • GHCランタイム全体に共通のstg_接頭辞であり、関数型言語を評価するための抽象マシンであるspineless-tagless G-machineを表します。

  • newTVarの最初の部分ですnewTVar#

  • zhのいわゆるz エンコーディングである final #: このエンコーディングは、ハッシュ (#) などの変な文字を削除して、すべてのプラットフォームのリンカー/ABI で使用できるプレーンな名前を生成します。

于 2015-06-18T08:32:14.113 に答える