Commit d1f3c637 authored by roland's avatar roland Committed by Marge Bot

Use pointer equality in Eq/Ord for ThreadId

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.
parent e57b7cc6
...@@ -41,6 +41,7 @@ StgRegTable * resumeThread (void *); ...@@ -41,6 +41,7 @@ StgRegTable * resumeThread (void *);
// //
// Thread operations from Threads.c // Thread operations from Threads.c
// //
bool eq_thread (StgPtr tso1, StgPtr tso2);
int cmp_thread (StgPtr tso1, StgPtr tso2); int cmp_thread (StgPtr tso1, StgPtr tso2);
long rts_getThreadId (StgPtr tso); long rts_getThreadId (StgPtr tso);
void rts_enableThreadAllocationLimit (StgPtr tso); void rts_enableThreadAllocationLimit (StgPtr tso);
......
...@@ -154,26 +154,21 @@ foreign import ccall unsafe "rts_getThreadId" getThreadId :: ThreadId# -> CInt ...@@ -154,26 +154,21 @@ foreign import ccall unsafe "rts_getThreadId" getThreadId :: ThreadId# -> CInt
id2TSO :: ThreadId -> ThreadId# id2TSO :: ThreadId -> ThreadId#
id2TSO (ThreadId t) = t 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 foreign import ccall unsafe "cmp_thread" cmp_thread :: ThreadId# -> ThreadId# -> CInt
-- Returns -1, 0, 1 -- 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 -- | @since 4.2.0.0
instance Eq ThreadId where instance Eq ThreadId where
t1 == t2 = ThreadId t1 == ThreadId t2 = eq_thread t1 t2 /= 0
case t1 `cmpThread` t2 of
EQ -> True
_ -> False
-- | @since 4.2.0.0 -- | @since 4.2.0.0
instance Ord ThreadId where 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 -- | Every thread has an allocation counter that tracks how much
-- memory has been allocated by the thread. The counter is -- memory has been allocated by the thread. The counter is
......
...@@ -606,6 +606,7 @@ ...@@ -606,6 +606,7 @@
SymI_HasProto(stg_compactFixupPointerszh) \ SymI_HasProto(stg_compactFixupPointerszh) \
SymI_HasProto(stg_compactSizzezh) \ SymI_HasProto(stg_compactSizzezh) \
SymI_HasProto(closure_flags) \ SymI_HasProto(closure_flags) \
SymI_HasProto(eq_thread) \
SymI_HasProto(cmp_thread) \ SymI_HasProto(cmp_thread) \
SymI_HasProto(createAdjustor) \ SymI_HasProto(createAdjustor) \
SymI_HasProto(stg_decodeDoublezu2Intzh) \ SymI_HasProto(stg_decodeDoublezu2Intzh) \
......
...@@ -138,22 +138,37 @@ createThread(Capability *cap, W_ size) ...@@ -138,22 +138,37 @@ createThread(Capability *cap, W_ size)
return tso; return tso;
} }
/* ---------------------------------------------------------------------------
* 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. * Comparing Thread ids.
* *
* This is used from STG land in the implementation of the * This is used from STG land in the implementation of the Ord instance
* instances of Eq/Ord for ThreadIds. * for ThreadIds.
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
int int
cmp_thread(StgPtr tso1, StgPtr tso2) cmp_thread(StgPtr tso1, StgPtr tso2)
{ {
if (tso1 == tso2) return 0;
StgThreadID id1 = ((StgTSO *)tso1)->id; StgThreadID id1 = ((StgTSO *)tso1)->id;
StgThreadID id2 = ((StgTSO *)tso2)->id; StgThreadID id2 = ((StgTSO *)tso2)->id;
if (id1 < id2) return (-1); ASSERT(id1 != id2);
if (id1 > id2) return 1;
return 0; return id1 < id2 ? -1 : 1;
} }
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment