X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStable.c;h=a4db5cd749de174afa28a9a89b2b8d8d35fe8ed0;hb=86f2671b37507012692a53c2fe45357b0988cb40;hp=30d17c04fbaab405adc93fcad111b8b0c4ea5925;hpb=1621421619df6f19dce3b8cb29471e5d3c731acb;p=ghc-hetmet.git diff --git a/ghc/rts/Stable.c b/ghc/rts/Stable.c index 30d17c0..a4db5cd 100644 --- a/ghc/rts/Stable.c +++ b/ghc/rts/Stable.c @@ -17,6 +17,7 @@ #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. @@ -134,9 +139,23 @@ initFreeList(snEntry *table, nat n, snEntry *free) void 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. + if (SPT_size > 0) + return; + + SPT_size = INIT_SPT_SIZE; + stable_ptr_table = stgMallocBytes(SPT_size * sizeof(snEntry), + "initStablePtrTable"); + + /* we don't use index 0 in the stable name table, because that + * would conflict with the hash table lookup operations which + * return NULL if an entry isn't found in the hash table. + */ + initFreeList(stable_ptr_table+1,INIT_SPT_SIZE-1,NULL); + addrToStableHash = allocHashTable(); + +#ifdef THREADED_RTS + initMutex(&stable_mutex); +#endif } /* @@ -160,8 +179,8 @@ removeIndirections(StgClosure* p) return q; } -StgWord -lookupStableName(StgPtr p) +static StgWord +lookupStableName_(StgPtr p) { StgWord sn; void* sn_tmp; @@ -197,6 +216,18 @@ lookupStableName(StgPtr p) } } +StgWord +lookupStableName(StgPtr p) +{ + StgWord res; + + initStablePtrTable(); + ACQUIRE_LOCK(&stable_mutex); + res = lookupStableName_(p); + RELEASE_LOCK(&stable_mutex); + return res; +} + STATIC_INLINE void freeStableName(snEntry *sn) { @@ -213,15 +244,23 @@ getStablePtr(StgPtr p) { StgWord sn; - sn = lookupStableName(p); + initStablePtrTable(); + 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; + + initStablePtrTable(); + ACQUIRE_LOCK(&stable_mutex); + + sn = &stable_ptr_table[(StgWord)sp]; ASSERT((StgWord)sp < SPT_size && sn->addr != NULL && sn->ref > 0); @@ -233,36 +272,23 @@ freeStablePtr(StgStablePtr sp) if (sn->sn_obj == NULL && sn->ref == 0) { freeStableName(sn); } + + RELEASE_LOCK(&stable_mutex); } void enlargeStablePtrTable(void) { nat old_SPT_size = SPT_size; - - if (SPT_size == 0) { - // 1st time - SPT_size = INIT_SPT_SIZE; - stable_ptr_table = stgMallocBytes(SPT_size * sizeof(snEntry), - "enlargeStablePtrTable"); - - /* we don't use index 0 in the stable name table, because that - * would conflict with the hash table lookup operations which - * return NULL if an entry isn't found in the hash table. - */ - initFreeList(stable_ptr_table+1,INIT_SPT_SIZE-1,NULL); - addrToStableHash = allocHashTable(); - } - else { + // 2nd and subsequent times - SPT_size *= 2; - stable_ptr_table = - stgReallocBytes(stable_ptr_table, + SPT_size *= 2; + stable_ptr_table = + stgReallocBytes(stable_ptr_table, SPT_size * sizeof(snEntry), "enlargeStablePtrTable"); - initFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); - } + initFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL); } /* -----------------------------------------------------------------------------