X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStable.c;h=09efb6accc6cc3417312050f615fcd7e9d08198c;hb=45252b35151fc55aa19fb6770df5ed8267639083;hp=c0520dae68f48eed194261552c88aace7187067c;hpb=423d477bfecd490de1449c59325c8776f91d7aac;p=ghc-hetmet.git diff --git a/ghc/rts/Stable.c b/ghc/rts/Stable.c index c0520da..09efb6a 100644 --- a/ghc/rts/Stable.c +++ b/ghc/rts/Stable.c @@ -1,5 +1,4 @@ /* ----------------------------------------------------------------------------- - * $Id: Stable.c,v 1.28 2004/08/13 13:10:45 simonmar Exp $ * * (c) The GHC Team, 1998-2002 * @@ -14,9 +13,11 @@ #include "Rts.h" #include "Hash.h" #include "RtsUtils.h" +#include "OSThreads.h" #include "Storage.h" #include "RtsAPI.h" #include "RtsFlags.h" +#include "OSThreads.h" /* Comment from ADR's implementation in old RTS: @@ -79,6 +80,10 @@ static snEntry *stable_ptr_free = NULL; static unsigned int SPT_size = 0; +#ifdef THREADED_RTS +static Mutex stable_mutex; +#endif + /* This hash table maps Haskell objects to stable names, so that every * call to lookupStableName on a given object will return the same * stable name. @@ -137,6 +142,12 @@ initStablePtrTable(void) // Nothing to do: // the table will be allocated the first time makeStablePtr is // called, and we want the table to persist through multiple inits. + // + // Also, getStablePtr is now called from __attribute__((constructor)) + // functions, so initialising things here wouldn't work anyway. +#ifdef THREADED_RTS + initMutex(&stable_mutex); +#endif } /* @@ -160,10 +171,11 @@ removeIndirections(StgClosure* p) return q; } -StgWord -lookupStableName(StgPtr p) +static StgWord +lookupStableName_(StgPtr p) { StgWord sn; + void* sn_tmp; if (stable_ptr_free == NULL) { enlargeStablePtrTable(); @@ -174,20 +186,20 @@ lookupStableName(StgPtr p) */ p = (StgPtr)removeIndirections((StgClosure*)p); - (void *)sn = lookupHashTable(addrToStableHash,(W_)p); + sn_tmp = lookupHashTable(addrToStableHash,(W_)p); + sn = (StgWord)sn_tmp; if (sn != 0) { ASSERT(stable_ptr_table[sn].addr == p); - IF_DEBUG(stable,fprintf(stderr,"cached stable name %d at %p\n",sn,p)); + IF_DEBUG(stable,debugBelch("cached stable name %ld at %p\n",sn,p)); return sn; } else { sn = stable_ptr_free - stable_ptr_table; - (P_)stable_ptr_free = stable_ptr_free->addr; + stable_ptr_free = (snEntry*)(stable_ptr_free->addr); stable_ptr_table[sn].ref = 0; stable_ptr_table[sn].addr = p; stable_ptr_table[sn].sn_obj = NULL; - /* IF_DEBUG(stable,fprintf(stderr,"new stable name %d at - %p\n",sn,p)); */ + /* IF_DEBUG(stable,debugBelch("new stable name %d at %p\n",sn,p)); */ /* add the new stable name to the hash table */ insertHashTable(addrToStableHash, (W_)p, (void *)sn); @@ -196,6 +208,16 @@ lookupStableName(StgPtr p) } } +StgWord +lookupStableName(StgPtr p) +{ + StgWord res; + ACQUIRE_LOCK(&stable_mutex); + res = lookupStableName_(p); + RELEASE_LOCK(&stable_mutex); + return res; +} + STATIC_INLINE void freeStableName(snEntry *sn) { @@ -212,15 +234,21 @@ getStablePtr(StgPtr p) { StgWord sn; - sn = lookupStableName(p); + ACQUIRE_LOCK(&stable_mutex); + sn = lookupStableName_(p); stable_ptr_table[sn].ref++; + RELEASE_LOCK(&stable_mutex); return (StgStablePtr)(sn); } void freeStablePtr(StgStablePtr sp) { - snEntry *sn = &stable_ptr_table[(StgWord)sp]; + snEntry *sn; + + ACQUIRE_LOCK(&stable_mutex); + + sn = &stable_ptr_table[(StgWord)sp]; ASSERT((StgWord)sp < SPT_size && sn->addr != NULL && sn->ref > 0); @@ -232,6 +260,8 @@ freeStablePtr(StgStablePtr sp) if (sn->sn_obj == NULL && sn->ref == 0) { freeStableName(sn); } + + RELEASE_LOCK(&stable_mutex); } void @@ -372,13 +402,13 @@ gcStablePtrTable( void ) if (p->sn_obj == NULL) { // StableName object is dead freeStableName(p); - IF_DEBUG(stable, fprintf(stderr,"GC'd Stable name %d\n", - p - stable_ptr_table)); + IF_DEBUG(stable, debugBelch("GC'd Stable name %ld\n", + p - stable_ptr_table)); continue; } else { - (StgClosure *)p->addr = isAlive((StgClosure *)p->addr); - IF_DEBUG(stable, fprintf(stderr,"Stable name %d still alive at %p, ref %d\n", p - stable_ptr_table, p->addr, p->ref)); + p->addr = (StgPtr)isAlive((StgClosure *)p->addr); + IF_DEBUG(stable, debugBelch("Stable name %ld still alive at %p, ref %ld\n", p - stable_ptr_table, p->addr, p->ref)); } } }