Commit 7a605453 authored by Simon Marlow's avatar Simon Marlow
Browse files

fix for the unregisterised way

We always assign to BaseReg on return from resumeThread(), but in
cases where BaseReg is not an lvalue (eg. unreg) we need to disable
this assigment.  See comments for more details.
parent 035d995b
...@@ -702,19 +702,23 @@ pprCall ppr_fn cconv results args vols ...@@ -702,19 +702,23 @@ pprCall ppr_fn cconv results args vols
| otherwise | otherwise
= save vols $$ = save vols $$
ptext SLIT("CALLER_SAVE_SYSTEM") $$ ptext SLIT("CALLER_SAVE_SYSTEM") $$
hcat [ ppr_results results, ppr_fn, ppr_assign results (ppr_fn <> parens (commafy (map pprArg args))) <> semi $$
parens (commafy (map pprArg args)), semi ] $$
ptext SLIT("CALLER_RESTORE_SYSTEM") $$ ptext SLIT("CALLER_RESTORE_SYSTEM") $$
restore vols restore vols
where where
ppr_results [] = empty ppr_assign [] rhs = rhs
ppr_results [(one,hint)] ppr_assign [(reg@(CmmGlobal BaseReg), hint)] rhs
| Just ty <- strangeRegType reg
= ptext SLIT("ASSIGN_BaseReg") <> parens (parens ty <> rhs)
-- BaseReg is special, sometimes it isn't an lvalue and we
-- can't assign to it.
ppr_assign [(one,hint)] rhs
| Just ty <- strangeRegType one | Just ty <- strangeRegType one
= pprReg one <> ptext SLIT(" = ") <> parens ty = pprReg one <> ptext SLIT(" = ") <> parens ty <> rhs
| otherwise | otherwise
= pprReg one <> ptext SLIT(" = ") = pprReg one <> ptext SLIT(" = ")
<> pprUnHint hint (cmmRegRep one) <> pprUnHint hint (cmmRegRep one) <> rhs
ppr_results _other = panic "pprCall: multiple results" ppr_assign _other _rhs = panic "pprCall: multiple results"
pprArg (expr, PtrHint) pprArg (expr, PtrHint)
= cCast (ptext SLIT("void *")) expr = cCast (ptext SLIT("void *")) expr
......
...@@ -337,13 +337,23 @@ struct PartCapability_ { ...@@ -337,13 +337,23 @@ struct PartCapability_ {
extern W_ MainCapability[]; extern W_ MainCapability[];
#endif #endif
/*
* Assigning to BaseReg (the ASSIGN_BaseReg macro): this happens on
* return from a "safe" foreign call, when the thread might be running
* on a new Capability. Obviously if BaseReg is not a register, then
* we are restricted to a single Capability (this invariant is enforced
* in Capability.c:initCapabilities), and assigning to BaseReg can be omitted.
*/
#if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS) #if defined(REG_Base) && !defined(NO_GLOBAL_REG_DECLS)
GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base) GLOBAL_REG_DECL(StgRegTable *,BaseReg,REG_Base)
#define ASSIGN_BaseReg(e) (BaseReg = (e))
#else #else
#ifdef SMP #ifdef SMP
#error BaseReg must be in a register for SMP #error BaseReg must be in a register for SMP
#endif #endif
#define BaseReg (&((struct PartCapability_ *)MainCapability)->r) #define BaseReg (&((struct PartCapability_ *)MainCapability)->r)
#define ASSIGN_BaseReg(e) /*nothing*/
#endif #endif
#if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS) #if defined(REG_Sp) && !defined(NO_GLOBAL_REG_DECLS)
......
...@@ -163,6 +163,14 @@ initCapabilities( void ) ...@@ -163,6 +163,14 @@ initCapabilities( void )
#if defined(SMP) #if defined(SMP)
nat i,n; nat i,n;
#ifndef REG_BaseReg
// We can't support multiple CPUs if BaseReg is not a register
if (RtsFlags.ParFlags.nNodes > 1) {
errorBelch("warning: multiple CPUs not supported in this build, reverting to 1");
RtsFlags.ParFlags.nNodes = 1;
}
#endif
n_capabilities = n = RtsFlags.ParFlags.nNodes; n_capabilities = n = RtsFlags.ParFlags.nNodes;
capabilities = stgMallocBytes(n * sizeof(Capability), "initCapabilities"); capabilities = stgMallocBytes(n * sizeof(Capability), "initCapabilities");
......
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