diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-02-05 12:46:48 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-02-05 12:46:48 +0000 |
commit | 829a7d022e91da80295913e6c70179f211e5b966 (patch) | |
tree | 546c6254015be4805288254ab124971ce7648493 /rts/Sparks.h | |
parent | 4fc80ef6710401b4b249c2bf298986623bdbd503 (diff) | |
download | haskell-829a7d022e91da80295913e6c70179f211e5b966.tar.gz |
Refactor the spark queue implementation into a generic work-stealing deque
So we can use this abstraction elsewhere in the RTS
Diffstat (limited to 'rts/Sparks.h')
-rw-r--r-- | rts/Sparks.h | 90 |
1 files changed, 22 insertions, 68 deletions
diff --git a/rts/Sparks.h b/rts/Sparks.h index e2c60e9625..105742f04f 100644 --- a/rts/Sparks.h +++ b/rts/Sparks.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------------- * - * (c) The GHC Team, 2000-2006 + * (c) The GHC Team, 2000-2009 * * Sparking support for GRAN, PAR and THREADED_RTS versions of the RTS. * @@ -9,6 +9,8 @@ #ifndef SPARKS_H #define SPARKS_H +#include "WSDeque.h" + #if defined(PARALLEL_HASKELL) #error Sparks.c using new internal structure, needs major overhaul! #endif @@ -17,68 +19,18 @@ #if defined(THREADED_RTS) -/* Spark pools: used to store pending sparks - * (THREADED_RTS & PARALLEL_HASKELL only) - * Implementation uses a DeQue to enable concurrent read accesses at - * the top end. - */ -typedef struct SparkPool_ { - /* Size of elements array. Used for modulo calculation: we round up - to powers of 2 and use the dyadic log (modulo == bitwise &) */ - StgWord size; - StgWord moduloSize; /* bitmask for modulo */ - - /* top, index where multiple readers steal() (protected by a cas) */ - volatile StgWord top; - - /* bottom, index of next free place where one writer can push - elements. This happens unsynchronised. */ - volatile StgWord bottom; - /* both position indices are continuously incremented, and used as - an index modulo the current array size. */ - - /* lower bound on the current top value. This is an internal - optimisation to avoid unnecessarily accessing the top field - inside pushBottom */ - volatile StgWord topBound; - - /* The elements array */ - StgClosurePtr* elements; - /* Please note: the dataspace cannot follow the admin fields - immediately, as it should be possible to enlarge it without - disposing the old one automatically (as realloc would)! */ - -} SparkPool; - - -/* INVARIANTS, in this order: reasonable size, - topBound consistent, space pointer, space accessible to us. - - NB. This is safe to use only (a) on a spark pool owned by the - current thread, or (b) when there's only one thread running, or no - stealing going on (e.g. during GC). -*/ -#define ASSERT_SPARK_POOL_INVARIANTS(p) \ - ASSERT((p)->size > 0); \ - ASSERT((p)->topBound <= (p)->top); \ - ASSERT((p)->elements != NULL); \ - ASSERT(*((p)->elements) || 1); \ - ASSERT(*((p)->elements - 1 + ((p)->size)) || 1); - -// No: it is possible that top > bottom when using reclaimSpark() -// ASSERT((p)->bottom >= (p)->top); -// ASSERT((p)->size > (p)->bottom - (p)->top); +typedef WSDeque SparkPool; // Initialisation void initSparkPools (void); // Take a spark from the "write" end of the pool. Can be called // by the pool owner only. -StgClosure* reclaimSpark(SparkPool *pool); +INLINE_HEADER StgClosure* reclaimSpark(SparkPool *pool); // Returns True if the spark pool is empty (can give a false positive // if the pool is almost empty). -rtsBool looksEmpty(SparkPool* deque); +INLINE_HEADER rtsBool looksEmpty(SparkPool* deque); StgClosure * tryStealSpark (Capability *cap); void freeSparkPool (SparkPool *pool); @@ -87,30 +39,32 @@ void traverseSparkQueue(evac_fn evac, void *user, Capability *cap); void pruneSparkQueue (evac_fn evac, void *user, Capability *cap); INLINE_HEADER void discardSparks (SparkPool *pool); -INLINE_HEADER nat sparkPoolSize (SparkPool *pool); -#endif +INLINE_HEADER long sparkPoolSize (SparkPool *pool); /* ----------------------------------------------------------------------------- * PRIVATE below here * -------------------------------------------------------------------------- */ -#if defined(PARALLEL_HASKELL) || defined(THREADED_RTS) +INLINE_HEADER StgClosure* reclaimSpark(SparkPool *pool) +{ + return popWSDeque(pool); +} -INLINE_HEADER rtsBool -emptySparkPool (SparkPool *pool) -{ return looksEmpty(pool); } +INLINE_HEADER rtsBool looksEmpty(SparkPool* deque) +{ + return looksEmptyWSDeque(deque); +} -INLINE_HEADER nat -sparkPoolSize (SparkPool *pool) -{ return (pool->bottom - pool->top); } +INLINE_HEADER long sparkPoolSize (SparkPool *pool) +{ + return dequeElements(pool); +} -INLINE_HEADER void -discardSparks (SparkPool *pool) +INLINE_HEADER void discardSparks (SparkPool *pool) { - pool->top = pool->bottom; -// pool->topBound = pool->top; + discardElements(pool); } -#endif +#endif // THREADED_RTS #endif /* SPARKS_H */ |