[commit: ghc] master: rts/Pool: Add poolTryTake (c4308b4)

git at git.haskell.org git at git.haskell.org
Thu Nov 26 14:11:40 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/c4308b468c7fe723b6f0a1009b233a55260de503/ghc

>---------------------------------------------------------------

commit c4308b468c7fe723b6f0a1009b233a55260de503
Author: Ben Gamari <ben at smart-cactus.org>
Date:   Thu Nov 26 12:02:33 2015 +0100

    rts/Pool: Add poolTryTake


>---------------------------------------------------------------

c4308b468c7fe723b6f0a1009b233a55260de503
 rts/Pool.c | 41 ++++++++++++++++++++++++++++++-----------
 rts/Pool.h | 10 +++++++++-
 2 files changed, 39 insertions(+), 12 deletions(-)

diff --git a/rts/Pool.c b/rts/Pool.c
index 6c23807..b3e3446 100644
--- a/rts/Pool.c
+++ b/rts/Pool.c
@@ -111,19 +111,40 @@ nat poolGetDesiredSize(Pool *pool) {
     return pool->desired_size;
 }
 
+// Try taking a PoolEntry with an item from a pool,
+// returning NULL if no items are available.
+static PoolEntry *poolTryTake_(Pool *pool) {
+    PoolEntry *ent = NULL;
+    if (pool->available != NULL) {
+        ent = pool->available;
+        pool->available = ent->next;
+    } else if (pool->current_size < pool->max_size) {
+        ent = stgMallocBytes(sizeof(PoolEntry), "pool_take");
+        ent->flags = 0;
+        ent->thing = pool->alloc_fn();
+        pool->current_size++;
+    } else {
+        return NULL;
+    }
+
+    ent->next = pool->taken;
+    pool->taken = ent;
+    return ent;
+}
+
+void *poolTryTake(Pool *pool) {
+    ACQUIRE_LOCK(&pool->mutex);
+    PoolEntry *ent = poolTryTake_(pool);
+    RELEASE_LOCK(&pool->mutex);
+    return ent ? ent->thing : NULL;
+}
+
 void *poolTake(Pool *pool) {
     PoolEntry *ent = NULL;
     ACQUIRE_LOCK(&pool->mutex);
     while (ent == NULL) {
-        if (pool->available != NULL) {
-            ent = pool->available;
-            pool->available = ent->next;
-        } else if (pool->current_size < pool->max_size) {
-            ent = stgMallocBytes(sizeof(PoolEntry), "pool_take");
-            ent->flags = 0;
-            ent->thing = pool->alloc_fn();
-            pool->current_size++;
-        } else {
+        ent = poolTryTake_(pool);
+        if (!ent) {
 #ifdef THREADED_RTS
             waitCondition(&pool->cond, &pool->mutex);
 #else
@@ -132,8 +153,6 @@ void *poolTake(Pool *pool) {
         }
     }
 
-    ent->next = pool->taken;
-    pool->taken = ent;
     RELEASE_LOCK(&pool->mutex);
     return ent->thing;
 }
diff --git a/rts/Pool.h b/rts/Pool.h
index d1aeab5..dd00412 100644
--- a/rts/Pool.h
+++ b/rts/Pool.h
@@ -43,7 +43,15 @@ void poolSetDesiredSize(Pool *pool, nat size);
 /* Get the desired size of a pool */
 nat poolGetDesiredSize(Pool *pool);
 
-/* Grab an available thing from a pool */
+/* Try to grab an available thing from a pool, returning NULL if no things
+ * are available.
+ */
+void *poolTryTake(Pool *pool);
+
+/* Grab an available thing from a pool. This will block if no elements are
+ * available in the case of a threaded runtime or abort in a single-threaded
+ * environment.
+ */
 void *poolTake(Pool *pool);
 
 /* Release a thing back to the pool from which it was taken */



More information about the ghc-commits mailing list