Use pointer equality in Eq/Ord for ThreadId
authorRoland Zumkeller <Roland.Zumkeller@gmail.com>
Sat, 22 Jun 2019 17:35:07 +0000 (19:35 +0200)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Wed, 20 Nov 2019 01:39:19 +0000 (20:39 -0500)
Changes (==) to use only pointer equality. This is safe because two
threads are the same iff they have the same id.

Changes `compare` to check pointer equality first and fall back on ids
only in case of inequality.

See discussion in #16761.

includes/rts/Threads.h
libraries/base/GHC/Conc/Sync.hs
rts/RtsSymbols.c
rts/Threads.c

index 7f016de..6d4aa76 100644 (file)
@@ -41,6 +41,7 @@ StgRegTable * resumeThread  (void *);
 //
 // Thread operations from Threads.c
 //
+bool    eq_thread                        (StgPtr tso1, StgPtr tso2);
 int     cmp_thread                       (StgPtr tso1, StgPtr tso2);
 long    rts_getThreadId                  (StgPtr tso);
 void    rts_enableThreadAllocationLimit  (StgPtr tso);
index 8749199..de8ca8e 100644 (file)
@@ -154,26 +154,21 @@ foreign import ccall unsafe "rts_getThreadId" getThreadId :: ThreadId# -> CInt
 id2TSO :: ThreadId -> ThreadId#
 id2TSO (ThreadId t) = t
 
+foreign import ccall unsafe "eq_thread" eq_thread :: ThreadId# -> ThreadId# -> CBool
+
 foreign import ccall unsafe "cmp_thread" cmp_thread :: ThreadId# -> ThreadId# -> CInt
 -- Returns -1, 0, 1
 
-cmpThread :: ThreadId -> ThreadId -> Ordering
-cmpThread t1 t2 =
-   case cmp_thread (id2TSO t1) (id2TSO t2) of
-      -1 -> LT
-      0  -> EQ
-      _  -> GT -- must be 1
-
 -- | @since 4.2.0.0
 instance Eq ThreadId where
-   t1 == t2 =
-      case t1 `cmpThread` t2 of
-         EQ -> True
-         _  -> False
+  ThreadId t1 == ThreadId t2 = eq_thread t1 t2 /= 0
 
 -- | @since 4.2.0.0
 instance Ord ThreadId where
-   compare = cmpThread
+  compare (ThreadId t1) (ThreadId t2) = case cmp_thread t1 t2 of
+    -1 -> LT
+    0  -> EQ
+    _  -> GT
 
 -- | Every thread has an allocation counter that tracks how much
 -- memory has been allocated by the thread.  The counter is
index b2f90a8..aef4960 100644 (file)
       SymI_HasProto(stg_compactFixupPointerszh)                         \
       SymI_HasProto(stg_compactSizzezh)                                 \
       SymI_HasProto(closure_flags)                                      \
+      SymI_HasProto(eq_thread)                                          \
       SymI_HasProto(cmp_thread)                                         \
       SymI_HasProto(createAdjustor)                                     \
       SymI_HasProto(stg_decodeDoublezu2Intzh)                           \
index cce32ca..22d58bb 100644 (file)
@@ -139,21 +139,36 @@ createThread(Capability *cap, W_ size)
 }
 
 /* ---------------------------------------------------------------------------
+ * Equality on Thread ids.
+ *
+ * This is used from STG land in the implementation of the Eq instance
+ * for ThreadIds.
+ * ------------------------------------------------------------------------ */
+
+bool
+eq_thread(StgPtr tso1, StgPtr tso2)
+{
+  return tso1 == tso2;
+}
+
+/* ---------------------------------------------------------------------------
  * Comparing Thread ids.
  *
- * This is used from STG land in the implementation of the
- * instances of Eq/Ord for ThreadIds.
+ * This is used from STG land in the implementation of the Ord instance
+ * for ThreadIds.
  * ------------------------------------------------------------------------ */
 
 int
 cmp_thread(StgPtr tso1, StgPtr tso2)
 {
+  if (tso1 == tso2) return 0;
+
   StgThreadID id1 = ((StgTSO *)tso1)->id;
   StgThreadID id2 = ((StgTSO *)tso2)->id;
 
-  if (id1 < id2) return (-1);
-  if (id1 > id2) return 1;
-  return 0;
+  ASSERT(id1 != id2);
+
+  return id1 < id2 ? -1 : 1;
 }
 
 /* ---------------------------------------------------------------------------