Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
GHC
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
4,261
Issues
4,261
List
Boards
Labels
Service Desk
Milestones
Iterations
Merge Requests
406
Merge Requests
406
Requirements
Requirements
List
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Code Review
Insights
Issue
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Glasgow Haskell Compiler
GHC
Commits
f7c8c3d4
Commit
f7c8c3d4
authored
Jun 09, 2013
by
ian@well-typed.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Whitespace only
parent
63889324
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
124 additions
and
124 deletions
+124
-124
rts/PrimOps.cmm
rts/PrimOps.cmm
+124
-124
No files found.
rts/PrimOps.cmm
View file @
f7c8c3d4
...
@@ -160,16 +160,16 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
...
@@ -160,16 +160,16 @@ stg_newArrayzh ( W_ n /* words */, gcptr init )
p
=
arr
+
SIZEOF_StgMutArrPtrs
;
p
=
arr
+
SIZEOF_StgMutArrPtrs
;
for
:
for
:
if
(
p
<
arr
+
WDS
(
words
))
{
if
(
p
<
arr
+
WDS
(
words
))
{
W_
[
p
]
=
init
;
W_
[
p
]
=
init
;
p
=
p
+
WDS
(
1
);
p
=
p
+
WDS
(
1
);
goto
for
;
goto
for
;
}
}
// Initialise the mark bits with 0
// Initialise the mark bits with 0
for2
:
for2
:
if
(
p
<
arr
+
WDS
(
size
))
{
if
(
p
<
arr
+
WDS
(
size
))
{
W_
[
p
]
=
0
;
W_
[
p
]
=
0
;
p
=
p
+
WDS
(
1
);
p
=
p
+
WDS
(
1
);
goto
for2
;
goto
for2
;
}
}
return
(
arr
);
return
(
arr
);
...
@@ -179,11 +179,11 @@ stg_unsafeThawArrayzh ( gcptr arr )
...
@@ -179,11 +179,11 @@ stg_unsafeThawArrayzh ( gcptr arr )
{
{
// SUBTLETY TO DO WITH THE OLD GEN MUTABLE LIST
// SUBTLETY TO DO WITH THE OLD GEN MUTABLE LIST
//
//
// A MUT_ARR_PTRS lives on the mutable list, but a MUT_ARR_PTRS_FROZEN
// A MUT_ARR_PTRS lives on the mutable list, but a MUT_ARR_PTRS_FROZEN
// normally doesn't. However, when we freeze a MUT_ARR_PTRS, we leave
// normally doesn't. However, when we freeze a MUT_ARR_PTRS, we leave
// it on the mutable list for the GC to remove (removing something from
// it on the mutable list for the GC to remove (removing something from
// the mutable list is not easy).
// the mutable list is not easy).
//
//
// So that we can tell whether a MUT_ARR_PTRS_FROZEN is on the mutable list,
// So that we can tell whether a MUT_ARR_PTRS_FROZEN is on the mutable list,
// when we freeze it we set the info ptr to be MUT_ARR_PTRS_FROZEN0
// when we freeze it we set the info ptr to be MUT_ARR_PTRS_FROZEN0
// to indicate that it is still on the mutable list.
// to indicate that it is still on the mutable list.
...
@@ -198,11 +198,11 @@ stg_unsafeThawArrayzh ( gcptr arr )
...
@@ -198,11 +198,11 @@ stg_unsafeThawArrayzh ( gcptr arr )
if
(
StgHeader_info
(
arr
)
!=
stg_MUT_ARR_PTRS_FROZEN0_info
)
{
if
(
StgHeader_info
(
arr
)
!=
stg_MUT_ARR_PTRS_FROZEN0_info
)
{
SET_INFO
(
arr
,
stg_MUT_ARR_PTRS_DIRTY_info
);
SET_INFO
(
arr
,
stg_MUT_ARR_PTRS_DIRTY_info
);
recordMutable
(
arr
);
recordMutable
(
arr
);
// must be done after SET_INFO, because it ASSERTs closure_MUTABLE()
// must be done after SET_INFO, because it ASSERTs closure_MUTABLE()
return
(
arr
);
return
(
arr
);
}
else
{
}
else
{
SET_INFO
(
arr
,
stg_MUT_ARR_PTRS_DIRTY_info
);
SET_INFO
(
arr
,
stg_MUT_ARR_PTRS_DIRTY_info
);
return
(
arr
);
return
(
arr
);
}
}
}
}
...
@@ -229,16 +229,16 @@ stg_newArrayArrayzh ( W_ n /* words */ )
...
@@ -229,16 +229,16 @@ stg_newArrayArrayzh ( W_ n /* words */ )
p
=
arr
+
SIZEOF_StgMutArrPtrs
;
p
=
arr
+
SIZEOF_StgMutArrPtrs
;
for
:
for
:
if
(
p
<
arr
+
WDS
(
words
))
{
if
(
p
<
arr
+
WDS
(
words
))
{
W_
[
p
]
=
arr
;
W_
[
p
]
=
arr
;
p
=
p
+
WDS
(
1
);
p
=
p
+
WDS
(
1
);
goto
for
;
goto
for
;
}
}
// Initialise the mark bits with 0
// Initialise the mark bits with 0
for2
:
for2
:
if
(
p
<
arr
+
WDS
(
size
))
{
if
(
p
<
arr
+
WDS
(
size
))
{
W_
[
p
]
=
0
;
W_
[
p
]
=
0
;
p
=
p
+
WDS
(
1
);
p
=
p
+
WDS
(
1
);
goto
for2
;
goto
for2
;
}
}
return
(
arr
);
return
(
arr
);
...
@@ -258,7 +258,7 @@ stg_newMutVarzh ( gcptr init )
...
@@ -258,7 +258,7 @@ stg_newMutVarzh ( gcptr init )
mv
=
Hp
-
SIZEOF_StgMutVar
+
WDS
(
1
);
mv
=
Hp
-
SIZEOF_StgMutVar
+
WDS
(
1
);
SET_HDR
(
mv
,
stg_MUT_VAR_DIRTY_info
,
CCCS
);
SET_HDR
(
mv
,
stg_MUT_VAR_DIRTY_info
,
CCCS
);
StgMutVar_var
(
mv
)
=
init
;
StgMutVar_var
(
mv
)
=
init
;
return
(
mv
);
return
(
mv
);
}
}
...
@@ -283,19 +283,19 @@ stg_atomicModifyMutVarzh ( gcptr mv, gcptr f )
...
@@ -283,19 +283,19 @@ stg_atomicModifyMutVarzh ( gcptr mv, gcptr f )
{
{
W_
z
,
x
,
y
,
r
,
h
;
W_
z
,
x
,
y
,
r
,
h
;
/* If x is the current contents of the MutVar#, then
/* If x is the current contents of the MutVar#, then
We want to make the new contents point to
We want to make the new contents point to
(sel_0 (f x))
(sel_0 (f x))
and the return value is
and the return value is
(sel_1 (f x))
(sel_1 (f x))
obviously we can share (f x).
obviously we can share (f x).
z = [stg_ap_2 f x] (max (HS + 2) MIN_UPD_SIZE)
z = [stg_ap_2 f x] (max (HS + 2) MIN_UPD_SIZE)
y = [stg_sel_0 z] (max (HS + 1) MIN_UPD_SIZE)
y = [stg_sel_0 z] (max (HS + 1) MIN_UPD_SIZE)
r = [stg_sel_1 z] (max (HS + 1) MIN_UPD_SIZE)
r = [stg_sel_1 z] (max (HS + 1) MIN_UPD_SIZE)
*/
*/
...
@@ -384,8 +384,8 @@ stg_mkWeakzh ( gcptr key,
...
@@ -384,8 +384,8 @@ stg_mkWeakzh ( gcptr key,
StgWeak_cfinalizer
(
w
)
=
stg_NO_FINALIZER_closure
;
StgWeak_cfinalizer
(
w
)
=
stg_NO_FINALIZER_closure
;
ACQUIRE_LOCK
(
sm_mutex
);
ACQUIRE_LOCK
(
sm_mutex
);
StgWeak_link
(
w
)
=
W_
[
weak_ptr_list
];
StgWeak_link
(
w
)
=
W_
[
weak_ptr_list
];
W_
[
weak_ptr_list
]
=
w
;
W_
[
weak_ptr_list
]
=
w
;
RELEASE_LOCK
(
sm_mutex
);
RELEASE_LOCK
(
sm_mutex
);
IF_DEBUG
(
weak
,
ccall
debugBelch
(
stg_weak_msg
,
w
));
IF_DEBUG
(
weak
,
ccall
debugBelch
(
stg_weak_msg
,
w
));
...
@@ -461,7 +461,7 @@ stg_finalizzeWeakzh ( gcptr w )
...
@@ -461,7 +461,7 @@ stg_finalizzeWeakzh ( gcptr w )
// LDV_recordDead_FILL_SLOP_DYNAMIC((StgClosure *)w);
// LDV_recordDead_FILL_SLOP_DYNAMIC((StgClosure *)w);
// or, LDV_recordDead():
// or, LDV_recordDead():
// LDV_recordDead((StgClosure *)w, sizeofW(StgWeak) - sizeofW(StgProfHeader));
// LDV_recordDead((StgClosure *)w, sizeofW(StgWeak) - sizeofW(StgProfHeader));
// Furthermore, when PROFILING is turned on, dead weak pointers are exactly as
// Furthermore, when PROFILING is turned on, dead weak pointers are exactly as
// large as weak pointers, so there is no need to fill the slop, either.
// large as weak pointers, so there is no need to fill the slop, either.
// See stg_DEAD_WEAK_info in StgMiscClosures.hc.
// See stg_DEAD_WEAK_info in StgMiscClosures.hc.
#endif
#endif
...
@@ -512,7 +512,7 @@ stg_deRefWeakzh ( gcptr w )
...
@@ -512,7 +512,7 @@ stg_deRefWeakzh ( gcptr w )
-------------------------------------------------------------------------- */
-------------------------------------------------------------------------- */
stg_decodeFloatzuIntzh
(
F_
arg
)
stg_decodeFloatzuIntzh
(
F_
arg
)
{
{
W_
p
;
W_
p
;
W_
mp_tmp1
;
W_
mp_tmp1
;
W_
mp_tmp_w
;
W_
mp_tmp_w
;
...
@@ -521,16 +521,16 @@ stg_decodeFloatzuIntzh ( F_ arg )
...
@@ -521,16 +521,16 @@ stg_decodeFloatzuIntzh ( F_ arg )
mp_tmp1
=
Sp
-
WDS
(
1
);
mp_tmp1
=
Sp
-
WDS
(
1
);
mp_tmp_w
=
Sp
-
WDS
(
2
);
mp_tmp_w
=
Sp
-
WDS
(
2
);
/* Perform the operation */
/* Perform the operation */
ccall
__decodeFloat_Int
(
mp_tmp1
"
ptr
"
,
mp_tmp_w
"
ptr
"
,
arg
);
ccall
__decodeFloat_Int
(
mp_tmp1
"
ptr
"
,
mp_tmp_w
"
ptr
"
,
arg
);
/* returns: (Int# (mantissa), Int# (exponent)) */
/* returns: (Int# (mantissa), Int# (exponent)) */
return
(
W_
[
mp_tmp1
],
W_
[
mp_tmp_w
]);
return
(
W_
[
mp_tmp1
],
W_
[
mp_tmp_w
]);
}
}
stg_decodeDoublezu2Intzh
(
D_
arg
)
stg_decodeDoublezu2Intzh
(
D_
arg
)
{
{
W_
p
;
W_
p
;
W_
mp_tmp1
;
W_
mp_tmp1
;
W_
mp_tmp2
;
W_
mp_tmp2
;
...
@@ -564,13 +564,13 @@ stg_forkzh ( gcptr closure )
...
@@ -564,13 +564,13 @@ stg_forkzh ( gcptr closure )
gcptr
threadid
;
gcptr
threadid
;
(
"
ptr
"
threadid
)
=
ccall
createIOThread
(
MyCapability
()
"
ptr
"
,
(
"
ptr
"
threadid
)
=
ccall
createIOThread
(
MyCapability
()
"
ptr
"
,
RtsFlags_GcFlags_initialStkSize
(
RtsFlags
),
RtsFlags_GcFlags_initialStkSize
(
RtsFlags
),
closure
"
ptr
"
);
closure
"
ptr
"
);
/* start blocked if the current thread is blocked */
/* start blocked if the current thread is blocked */
StgTSO_flags
(
threadid
)
=
%lobits16
(
StgTSO_flags
(
threadid
)
=
%lobits16
(
TO_W_
(
StgTSO_flags
(
threadid
))
|
TO_W_
(
StgTSO_flags
(
threadid
))
|
TO_W_
(
StgTSO_flags
(
CurrentTSO
))
&
(
TSO_BLOCKEX
|
TSO_INTERRUPTIBLE
));
TO_W_
(
StgTSO_flags
(
CurrentTSO
))
&
(
TSO_BLOCKEX
|
TSO_INTERRUPTIBLE
));
ccall
scheduleThread
(
MyCapability
()
"
ptr
"
,
threadid
"
ptr
"
);
ccall
scheduleThread
(
MyCapability
()
"
ptr
"
,
threadid
"
ptr
"
);
...
@@ -578,7 +578,7 @@ stg_forkzh ( gcptr closure )
...
@@ -578,7 +578,7 @@ stg_forkzh ( gcptr closure )
// context switch soon, but not immediately: we don't want every
// context switch soon, but not immediately: we don't want every
// forkIO to force a context-switch.
// forkIO to force a context-switch.
Capability_context_switch
(
MyCapability
())
=
1
::
CInt
;
Capability_context_switch
(
MyCapability
())
=
1
::
CInt
;
return
(
threadid
);
return
(
threadid
);
}
}
...
@@ -588,13 +588,13 @@ again: MAYBE_GC(again);
...
@@ -588,13 +588,13 @@ again: MAYBE_GC(again);
gcptr
threadid
;
gcptr
threadid
;
(
"
ptr
"
threadid
)
=
ccall
createIOThread
(
MyCapability
()
"
ptr
"
,
(
"
ptr
"
threadid
)
=
ccall
createIOThread
(
MyCapability
()
"
ptr
"
,
RtsFlags_GcFlags_initialStkSize
(
RtsFlags
),
RtsFlags_GcFlags_initialStkSize
(
RtsFlags
),
closure
"
ptr
"
);
closure
"
ptr
"
);
/* start blocked if the current thread is blocked */
/* start blocked if the current thread is blocked */
StgTSO_flags
(
threadid
)
=
%lobits16
(
StgTSO_flags
(
threadid
)
=
%lobits16
(
TO_W_
(
StgTSO_flags
(
threadid
))
|
TO_W_
(
StgTSO_flags
(
threadid
))
|
TO_W_
(
StgTSO_flags
(
CurrentTSO
))
&
(
TSO_BLOCKEX
|
TSO_INTERRUPTIBLE
));
TO_W_
(
StgTSO_flags
(
CurrentTSO
))
&
(
TSO_BLOCKEX
|
TSO_INTERRUPTIBLE
));
ccall
scheduleThreadOn
(
MyCapability
()
"
ptr
"
,
cpu
,
threadid
"
ptr
"
);
ccall
scheduleThreadOn
(
MyCapability
()
"
ptr
"
,
cpu
,
threadid
"
ptr
"
);
...
@@ -602,7 +602,7 @@ again: MAYBE_GC(again);
...
@@ -602,7 +602,7 @@ again: MAYBE_GC(again);
// context switch soon, but not immediately: we don't want every
// context switch soon, but not immediately: we don't want every
// forkIO to force a context-switch.
// forkIO to force a context-switch.
Capability_context_switch
(
MyCapability
())
=
1
::
CInt
;
Capability_context_switch
(
MyCapability
())
=
1
::
CInt
;
return
(
threadid
);
return
(
threadid
);
}
}
...
@@ -1014,7 +1014,7 @@ retry_pop_stack:
...
@@ -1014,7 +1014,7 @@ retry_pop_stack:
}
}
}
}
// We've reached the ATOMICALLY_FRAME: attempt to wait
// We've reached the ATOMICALLY_FRAME: attempt to wait
ASSERT
(
frame_type
==
ATOMICALLY_FRAME
);
ASSERT
(
frame_type
==
ATOMICALLY_FRAME
);
if
(
outer
!=
NO_TREC
)
{
if
(
outer
!=
NO_TREC
)
{
// We called retry while checking invariants, so abort the current
// We called retry while checking invariants, so abort the current
...
@@ -1152,9 +1152,9 @@ stg_writeTVarzh (P_ tvar, /* :: TVar a */
...
@@ -1152,9 +1152,9 @@ stg_writeTVarzh (P_ tvar, /* :: TVar a */
stg_isEmptyMVarzh
(
P_
mvar
/* :: MVar a */
)
stg_isEmptyMVarzh
(
P_
mvar
/* :: MVar a */
)
{
{
if
(
StgMVar_value
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_value
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
return
(
1
);
return
(
1
);
}
else
{
}
else
{
return
(
0
);
return
(
0
);
}
}
}
}
...
@@ -1163,7 +1163,7 @@ stg_newMVarzh ()
...
@@ -1163,7 +1163,7 @@ stg_newMVarzh ()
W_
mvar
;
W_
mvar
;
ALLOC_PRIM_
(
SIZEOF_StgMVar
,
stg_newMVarzh
);
ALLOC_PRIM_
(
SIZEOF_StgMVar
,
stg_newMVarzh
);
mvar
=
Hp
-
SIZEOF_StgMVar
+
WDS
(
1
);
mvar
=
Hp
-
SIZEOF_StgMVar
+
WDS
(
1
);
SET_HDR
(
mvar
,
stg_MVAR_DIRTY_info
,
CCCS
);
SET_HDR
(
mvar
,
stg_MVAR_DIRTY_info
,
CCCS
);
// MVARs start dirty: generation 0 has no mutable list
// MVARs start dirty: generation 0 has no mutable list
...
@@ -1196,7 +1196,7 @@ stg_takeMVarzh ( P_ mvar /* :: MVar a */ )
...
@@ -1196,7 +1196,7 @@ stg_takeMVarzh ( P_ mvar /* :: MVar a */ )
#else
#else
info
=
GET_INFO
(
mvar
);
info
=
GET_INFO
(
mvar
);
#endif
#endif
if
(
info
==
stg_MVAR_CLEAN_info
)
{
if
(
info
==
stg_MVAR_CLEAN_info
)
{
ccall
dirty_MVAR
(
BaseReg
"
ptr
"
,
mvar
"
ptr
"
);
ccall
dirty_MVAR
(
BaseReg
"
ptr
"
,
mvar
"
ptr
"
);
}
}
...
@@ -1205,7 +1205,7 @@ stg_takeMVarzh ( P_ mvar /* :: MVar a */ )
...
@@ -1205,7 +1205,7 @@ stg_takeMVarzh ( P_ mvar /* :: MVar a */ )
* and wait until we're woken up.
* and wait until we're woken up.
*/
*/
if
(
StgMVar_value
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_value
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
// We want to put the heap check down here in the slow path,
// We want to put the heap check down here in the slow path,
// but be careful to unlock the closure before returning to
// but be careful to unlock the closure before returning to
// the RTS if the check fails.
// the RTS if the check fails.
...
@@ -1220,24 +1220,24 @@ stg_takeMVarzh ( P_ mvar /* :: MVar a */ )
...
@@ -1220,24 +1220,24 @@ stg_takeMVarzh ( P_ mvar /* :: MVar a */ )
StgMVarTSOQueue_link
(
q
)
=
END_TSO_QUEUE
;
StgMVarTSOQueue_link
(
q
)
=
END_TSO_QUEUE
;
StgMVarTSOQueue_tso
(
q
)
=
CurrentTSO
;
StgMVarTSOQueue_tso
(
q
)
=
CurrentTSO
;
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
StgMVar_head
(
mvar
)
=
q
;
StgMVar_head
(
mvar
)
=
q
;
}
else
{
}
else
{
StgMVarTSOQueue_link
(
StgMVar_tail
(
mvar
))
=
q
;
StgMVarTSOQueue_link
(
StgMVar_tail
(
mvar
))
=
q
;
ccall
recordClosureMutated
(
MyCapability
()
"
ptr
"
,
ccall
recordClosureMutated
(
MyCapability
()
"
ptr
"
,
StgMVar_tail
(
mvar
));
StgMVar_tail
(
mvar
));
}
}
StgTSO__link
(
CurrentTSO
)
=
q
;
StgTSO__link
(
CurrentTSO
)
=
q
;
StgTSO_block_info
(
CurrentTSO
)
=
mvar
;
StgTSO_block_info
(
CurrentTSO
)
=
mvar
;
StgTSO_why_blocked
(
CurrentTSO
)
=
BlockedOnMVar
::
I16
;
StgTSO_why_blocked
(
CurrentTSO
)
=
BlockedOnMVar
::
I16
;
StgMVar_tail
(
mvar
)
=
q
;
StgMVar_tail
(
mvar
)
=
q
;
jump
stg_block_takemvar
(
mvar
);
jump
stg_block_takemvar
(
mvar
);
}
}
/* we got the value... */
/* we got the value... */
val
=
StgMVar_value
(
mvar
);
val
=
StgMVar_value
(
mvar
);
q
=
StgMVar_head
(
mvar
);
q
=
StgMVar_head
(
mvar
);
loop
:
loop
:
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
...
@@ -1251,9 +1251,9 @@ loop:
...
@@ -1251,9 +1251,9 @@ loop:
q
=
StgInd_indirectee
(
q
);
q
=
StgInd_indirectee
(
q
);
goto
loop
;
goto
loop
;
}
}
// There are putMVar(s) waiting... wake up the first thread on the queue
// There are putMVar(s) waiting... wake up the first thread on the queue
tso
=
StgMVarTSOQueue_tso
(
q
);
tso
=
StgMVarTSOQueue_tso
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
...
@@ -1270,11 +1270,11 @@ loop:
...
@@ -1270,11 +1270,11 @@ loop:
// indicate that the MVar operation has now completed.
// indicate that the MVar operation has now completed.
StgTSO__link
(
tso
)
=
stg_END_TSO_QUEUE_closure
;
StgTSO__link
(
tso
)
=
stg_END_TSO_QUEUE_closure
;
// no need to mark the TSO dirty, we have only written END_TSO_QUEUE.
// no need to mark the TSO dirty, we have only written END_TSO_QUEUE.
ccall
tryWakeupThread
(
MyCapability
()
"
ptr
"
,
tso
);
ccall
tryWakeupThread
(
MyCapability
()
"
ptr
"
,
tso
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
return
(
val
);
return
(
val
);
}
}
...
@@ -1288,7 +1288,7 @@ stg_tryTakeMVarzh ( P_ mvar /* :: MVar a */ )
...
@@ -1288,7 +1288,7 @@ stg_tryTakeMVarzh ( P_ mvar /* :: MVar a */ )
#else
#else
info
=
GET_INFO
(
mvar
);
info
=
GET_INFO
(
mvar
);
#endif
#endif
/* If the MVar is empty, put ourselves on its blocking queue,
/* If the MVar is empty, put ourselves on its blocking queue,
* and wait until we're woken up.
* and wait until we're woken up.
*/
*/
...
@@ -1296,19 +1296,19 @@ stg_tryTakeMVarzh ( P_ mvar /* :: MVar a */ )
...
@@ -1296,19 +1296,19 @@ stg_tryTakeMVarzh ( P_ mvar /* :: MVar a */ )
#if
defined
(
THREADED_RTS
)
#if
defined
(
THREADED_RTS
)
unlockClosure
(
mvar
,
info
);
unlockClosure
(
mvar
,
info
);
#endif
#endif
/* HACK: we need a pointer to pass back,
/* HACK: we need a pointer to pass back,
* so we abuse NO_FINALIZER_closure
* so we abuse NO_FINALIZER_closure
*/
*/
return
(
0
,
stg_NO_FINALIZER_closure
);
return
(
0
,
stg_NO_FINALIZER_closure
);
}
}
if
(
info
==
stg_MVAR_CLEAN_info
)
{
if
(
info
==
stg_MVAR_CLEAN_info
)
{
ccall
dirty_MVAR
(
BaseReg
"
ptr
"
,
mvar
"
ptr
"
);
ccall
dirty_MVAR
(
BaseReg
"
ptr
"
,
mvar
"
ptr
"
);
}
}
/* we got the value... */
/* we got the value... */
val
=
StgMVar_value
(
mvar
);
val
=
StgMVar_value
(
mvar
);
q
=
StgMVar_head
(
mvar
);
q
=
StgMVar_head
(
mvar
);
loop
:
loop
:
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
...
@@ -1322,9 +1322,9 @@ loop:
...
@@ -1322,9 +1322,9 @@ loop:
q
=
StgInd_indirectee
(
q
);
q
=
StgInd_indirectee
(
q
);
goto
loop
;
goto
loop
;
}
}
// There are putMVar(s) waiting... wake up the first thread on the queue
// There are putMVar(s) waiting... wake up the first thread on the queue
tso
=
StgMVarTSOQueue_tso
(
q
);
tso
=
StgMVarTSOQueue_tso
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
...
@@ -1341,11 +1341,11 @@ loop:
...
@@ -1341,11 +1341,11 @@ loop:
// indicate that the MVar operation has now completed.
// indicate that the MVar operation has now completed.
StgTSO__link
(
tso
)
=
stg_END_TSO_QUEUE_closure
;
StgTSO__link
(
tso
)
=
stg_END_TSO_QUEUE_closure
;
// no need to mark the TSO dirty, we have only written END_TSO_QUEUE.
// no need to mark the TSO dirty, we have only written END_TSO_QUEUE.
ccall
tryWakeupThread
(
MyCapability
()
"
ptr
"
,
tso
);
ccall
tryWakeupThread
(
MyCapability
()
"
ptr
"
,
tso
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
return
(
1
,
val
);
return
(
1
,
val
);
}
}
...
@@ -1381,27 +1381,27 @@ stg_putMVarzh ( P_ mvar, /* :: MVar a */
...
@@ -1381,27 +1381,27 @@ stg_putMVarzh ( P_ mvar, /* :: MVar a */
StgMVarTSOQueue_link
(
q
)
=
END_TSO_QUEUE
;
StgMVarTSOQueue_link
(
q
)
=
END_TSO_QUEUE
;
StgMVarTSOQueue_tso
(
q
)
=
CurrentTSO
;
StgMVarTSOQueue_tso
(
q
)
=
CurrentTSO
;
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
StgMVar_head
(
mvar
)
=
q
;
StgMVar_head
(
mvar
)
=
q
;
}
else
{
}
else
{
StgMVarTSOQueue_link
(
StgMVar_tail
(
mvar
))
=
q
;
StgMVarTSOQueue_link
(
StgMVar_tail
(
mvar
))
=
q
;
ccall
recordClosureMutated
(
MyCapability
()
"
ptr
"
,
ccall
recordClosureMutated
(
MyCapability
()
"
ptr
"
,
StgMVar_tail
(
mvar
));
StgMVar_tail
(
mvar
));
}
}
StgTSO__link
(
CurrentTSO
)
=
q
;
StgTSO__link
(
CurrentTSO
)
=
q
;
StgTSO_block_info
(
CurrentTSO
)
=
mvar
;
StgTSO_block_info
(
CurrentTSO
)
=
mvar
;
StgTSO_why_blocked
(
CurrentTSO
)
=
BlockedOnMVar
::
I16
;
StgTSO_why_blocked
(
CurrentTSO
)
=
BlockedOnMVar
::
I16
;
StgMVar_tail
(
mvar
)
=
q
;
StgMVar_tail
(
mvar
)
=
q
;
jump
stg_block_putmvar
(
mvar
,
val
);
jump
stg_block_putmvar
(
mvar
,
val
);
}
}
q
=
StgMVar_head
(
mvar
);
q
=
StgMVar_head
(
mvar
);
loop
:
loop
:
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
/* No further takes, the MVar is now full. */
/* No further takes, the MVar is now full. */
StgMVar_value
(
mvar
)
=
val
;
StgMVar_value
(
mvar
)
=
val
;
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
return
();
return
();
}
}
if
(
StgHeader_info
(
q
)
==
stg_IND_info
||
if
(
StgHeader_info
(
q
)
==
stg_IND_info
||
...
@@ -1411,7 +1411,7 @@ loop:
...
@@ -1411,7 +1411,7 @@ loop:
}
}
// There are takeMVar(s) waiting: wake up the first one
// There are takeMVar(s) waiting: wake up the first one
tso
=
StgMVarTSOQueue_tso
(
q
);
tso
=
StgMVarTSOQueue_tso
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
...
@@ -1432,7 +1432,7 @@ loop:
...
@@ -1432,7 +1432,7 @@ loop:
if
(
TO_W_
(
StgStack_dirty
(
stack
))
==
0
)
{
if
(
TO_W_
(
StgStack_dirty
(
stack
))
==
0
)
{
ccall
dirty_STACK
(
MyCapability
()
"
ptr
"
,
stack
"
ptr
"
);
ccall
dirty_STACK
(
MyCapability
()
"
ptr
"
,
stack
"
ptr
"
);
}
}
ccall
tryWakeupThread
(
MyCapability
()
"
ptr
"
,
tso
);
ccall
tryWakeupThread
(
MyCapability
()
"
ptr
"
,
tso
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
...
@@ -1453,11 +1453,11 @@ stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */
...
@@ -1453,11 +1453,11 @@ stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */
if
(
StgMVar_value
(
mvar
)
!=
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_value
(
mvar
)
!=
stg_END_TSO_QUEUE_closure
)
{
#if
defined
(
THREADED_RTS
)
#if
defined
(
THREADED_RTS
)
unlockClosure
(
mvar
,
info
);
unlockClosure
(
mvar
,
info
);
#endif
#endif
return
(
0
);
return
(
0
);
}
}
if
(
info
==
stg_MVAR_CLEAN_info
)
{
if
(
info
==
stg_MVAR_CLEAN_info
)
{
ccall
dirty_MVAR
(
BaseReg
"
ptr
"
,
mvar
"
ptr
"
);
ccall
dirty_MVAR
(
BaseReg
"
ptr
"
,
mvar
"
ptr
"
);
}
}
...
@@ -1465,9 +1465,9 @@ stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */
...
@@ -1465,9 +1465,9 @@ stg_tryPutMVarzh ( P_ mvar, /* :: MVar a */
q
=
StgMVar_head
(
mvar
);
q
=
StgMVar_head
(
mvar
);
loop
:
loop
:
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
if
(
q
==
stg_END_TSO_QUEUE_closure
)
{
/* No further takes, the MVar is now full. */
/* No further takes, the MVar is now full. */
StgMVar_value
(
mvar
)
=
val
;
StgMVar_value
(
mvar
)
=
val
;
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
unlockClosure
(
mvar
,
stg_MVAR_DIRTY_info
);
return
(
1
);
return
(
1
);
}
}
if
(
StgHeader_info
(
q
)
==
stg_IND_info
||
if
(
StgHeader_info
(
q
)
==
stg_IND_info
||
...
@@ -1477,7 +1477,7 @@ loop:
...
@@ -1477,7 +1477,7 @@ loop:
}
}
// There are takeMVar(s) waiting: wake up the first one
// There are takeMVar(s) waiting: wake up the first one
tso
=
StgMVarTSOQueue_tso
(
q
);
tso
=
StgMVarTSOQueue_tso
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
StgMVar_head
(
mvar
)
=
StgMVarTSOQueue_link
(
q
);
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{
if
(
StgMVar_head
(
mvar
)
==
stg_END_TSO_QUEUE_closure
)
{