/* ----------------------------------------------------------------------------- * * (c) The GHC Team, 1998-2009 * * External Storage Manger Interface * * ---------------------------------------------------------------------------*/ #ifndef SM_STORAGE_H #define SM_STORAGE_H #include "Capability.h" #include "BeginPrivate.h" /* ----------------------------------------------------------------------------- Initialisation / De-initialisation -------------------------------------------------------------------------- */ void initStorage(void); void exitStorage(void); void freeStorage(rtsBool free_heap); /* ----------------------------------------------------------------------------- Storage manager state -------------------------------------------------------------------------- */ INLINE_HEADER rtsBool doYouWantToGC( Capability *cap ) { return (cap->r.rCurrentNursery->link == NULL || g0->n_large_blocks >= alloc_blocks_lim); } /* for splitting blocks groups in two */ bdescr * splitLargeBlock (bdescr *bd, nat blocks); /* ----------------------------------------------------------------------------- Generational garbage collection support recordMutable(StgPtr p) Informs the garbage collector that a previously immutable object has become (permanently) mutable. Used by thawArray and similar. updateWithIndirection(p1,p2) Updates the object at p1 with an indirection pointing to p2. This is normally called for objects in an old generation (>0) when they are updated. updateWithPermIndirection(p1,p2) As above but uses a permanent indir. -------------------------------------------------------------------------- */ /* * Storage manager mutex */ #if defined(THREADED_RTS) extern Mutex sm_mutex; #endif #if defined(THREADED_RTS) #define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex); #define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex); #define ASSERT_SM_LOCK() ASSERT_LOCK_HELD(&sm_mutex); #else #define ACQUIRE_SM_LOCK #define RELEASE_SM_LOCK #define ASSERT_SM_LOCK() #endif INLINE_HEADER void recordMutableGen(StgClosure *p, nat gen_no) { bdescr *bd; bd = generations[gen_no].mut_list; if (bd->free >= bd->start + BLOCK_SIZE_W) { bdescr *new_bd; new_bd = allocBlock(); new_bd->link = bd; bd = new_bd; generations[gen_no].mut_list = bd; } *bd->free++ = (StgWord)p; } INLINE_HEADER void recordMutableGenLock(StgClosure *p, nat gen_no) { ACQUIRE_SM_LOCK; recordMutableGen(p,gen_no); RELEASE_SM_LOCK; } INLINE_HEADER void recordMutable(StgClosure *p) { bdescr *bd; ASSERT(closure_MUTABLE(p)); bd = Bdescr((P_)p); if (bd->gen_no > 0) recordMutableGen(p, bd->gen_no); } INLINE_HEADER void recordMutableLock(StgClosure *p) { ACQUIRE_SM_LOCK; recordMutable(p); RELEASE_SM_LOCK; } /* ----------------------------------------------------------------------------- The write barrier for MVARs -------------------------------------------------------------------------- */ void dirty_MVAR(StgRegTable *reg, StgClosure *p); /* ----------------------------------------------------------------------------- Nursery manipulation -------------------------------------------------------------------------- */ extern nursery *nurseries; void resetNurseries ( void ); void resizeNurseries ( nat blocks ); void resizeNurseriesFixed ( nat blocks ); lnat countNurseryBlocks ( void ); /* ----------------------------------------------------------------------------- Stats 'n' DEBUG stuff -------------------------------------------------------------------------- */ lnat calcAllocated (void); lnat calcLiveBlocks (void); lnat calcLiveWords (void); lnat countOccupied (bdescr *bd); lnat calcNeeded (void); /* ---------------------------------------------------------------------------- Storage manager internal APIs and globals ------------------------------------------------------------------------- */ extern bdescr *exec_block; #define END_OF_STATIC_LIST ((StgClosure*)1) void move_TSO (StgTSO *src, StgTSO *dest); extern StgClosure * caf_list; extern StgClosure * revertible_caf_list; #include "EndPrivate.h" #endif /* SM_STORAGE_H */