Implement tryAtomicReadMVar#.
authorEdward Z. Yang <ezyang@mit.edu>
Wed, 10 Jul 2013 20:32:15 +0000 (13:32 -0700)
committerEdward Z. Yang <ezyang@mit.edu>
Wed, 10 Jul 2013 20:32:15 +0000 (13:32 -0700)
Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
compiler/prelude/primops.txt.pp
includes/stg/MiscClosures.h
rts/Linker.c
rts/PrimOps.cmm

index 739092d..e5a3e21 100644 (file)
@@ -1726,6 +1726,14 @@ primop  AtomicReadMVarOp "atomicReadMVar#" GenPrimOp
    out_of_line      = True
    has_side_effects = True
 
+primop  TryAtomicReadMVarOp "tryAtomicReadMVar#" GenPrimOp
+   MVar# s a -> State# s -> (# State# s, Int#, a #)
+   {If {\tt MVar\#} is empty, immediately return with integer 0 and value undefined.
+   Otherwise, return wtih integer 1 and contents of {\tt MVar\#}.}
+   with
+   out_of_line      = True
+   has_side_effects = True
+
 primop  SameMVarOp "sameMVar#" GenPrimOp
    MVar# s a -> MVar# s a -> Bool
 
index 88cee59..287fce9 100644 (file)
@@ -381,6 +381,7 @@ RTS_FUN_DECL(stg_putMVarzh);
 RTS_FUN_DECL(stg_atomicReadMVarzh);
 RTS_FUN_DECL(stg_tryTakeMVarzh);
 RTS_FUN_DECL(stg_tryPutMVarzh);
+RTS_FUN_DECL(stg_tryAtomicReadMVarzh);
 
 RTS_FUN_DECL(stg_waitReadzh);
 RTS_FUN_DECL(stg_waitWritezh);
index 9129b46..1389b4f 100644 (file)
@@ -1319,6 +1319,7 @@ typedef struct _RtsSymbolVal {
       SymI_HasProto(stg_threadStatuszh)                                 \
       SymI_HasProto(stg_tryPutMVarzh)                                   \
       SymI_HasProto(stg_tryTakeMVarzh)                                  \
+      SymI_HasProto(stg_tryAtomicReadMVarzh)                            \
       SymI_HasProto(stg_unmaskAsyncExceptionszh)                        \
       SymI_HasProto(unloadObj)                                          \
       SymI_HasProto(stg_unsafeThawArrayzh)                              \
index abe54c8..6bb938e 100644 (file)
@@ -1567,6 +1567,22 @@ stg_atomicReadMVarzh ( P_ mvar, /* :: MVar a */ )
     return (val);
 }
 
+stg_tryAtomicReadMVarzh ( P_ mvar, /* :: MVar a */ )
+{
+    W_ val, info, tso, q;
+
+    LOCK_CLOSURE(mvar, info);
+
+    if (StgMVar_value(mvar) == stg_END_TSO_QUEUE_closure) {
+        return (0, stg_NO_FINALIZER_closure);
+    }
+
+    val = StgMVar_value(mvar);
+
+    unlockClosure(mvar, stg_MVAR_DIRTY_info);
+    return (1, val);
+}
+
 /* -----------------------------------------------------------------------------
    Stable pointer primitives
    -------------------------------------------------------------------------  */