summaryrefslogtreecommitdiff
path: root/ghc/rts/BlockAlloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ghc/rts/BlockAlloc.c')
-rw-r--r--ghc/rts/BlockAlloc.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/ghc/rts/BlockAlloc.c b/ghc/rts/BlockAlloc.c
index baa096a61a..9b01354289 100644
--- a/ghc/rts/BlockAlloc.c
+++ b/ghc/rts/BlockAlloc.c
@@ -21,6 +21,7 @@
#include "RtsUtils.h"
#include "BlockAlloc.h"
#include "MBlock.h"
+#include "Storage.h"
#include <string.h>
@@ -28,6 +29,8 @@ static void initMBlock(void *mblock);
static bdescr *allocMegaGroup(nat mblocks);
static void freeMegaGroup(bdescr *bd);
+// In SMP mode, the free list is protected by sm_mutex. In the
+// threaded RTS, it is protected by the Capability.
static bdescr *free_list = NULL;
/* -----------------------------------------------------------------------------
@@ -67,6 +70,7 @@ allocGroup(nat n)
void *mblock;
bdescr *bd, **last;
+ ASSERT_SM_LOCK();
ASSERT(n != 0);
if (n > BLOCKS_PER_MBLOCK) {
@@ -104,11 +108,31 @@ allocGroup(nat n)
}
bdescr *
+allocGroup_lock(nat n)
+{
+ bdescr *bd;
+ ACQUIRE_SM_LOCK;
+ bd = allocGroup(n);
+ RELEASE_SM_LOCK;
+ return bd;
+}
+
+bdescr *
allocBlock(void)
{
return allocGroup(1);
}
+bdescr *
+allocBlock_lock(void)
+{
+ bdescr *bd;
+ ACQUIRE_SM_LOCK;
+ bd = allocBlock();
+ RELEASE_SM_LOCK;
+ return bd;
+}
+
/* -----------------------------------------------------------------------------
Any request larger than BLOCKS_PER_MBLOCK needs a megablock group.
First, search the free list for enough contiguous megablocks to
@@ -220,6 +244,8 @@ freeGroup(bdescr *p)
{
bdescr *bd, *last;
+ ASSERT_SM_LOCK();
+
/* are we dealing with a megablock group? */
if (p->blocks > BLOCKS_PER_MBLOCK) {
freeMegaGroup(p);
@@ -256,6 +282,14 @@ freeGroup(bdescr *p)
IF_DEBUG(sanity, checkFreeListSanity());
}
+void
+freeGroup_lock(bdescr *p)
+{
+ ACQUIRE_SM_LOCK;
+ freeGroup(p);
+ RELEASE_SM_LOCK;
+}
+
static void
freeMegaGroup(bdescr *p)
{
@@ -281,6 +315,14 @@ freeChain(bdescr *bd)
}
}
+void
+freeChain_lock(bdescr *bd)
+{
+ ACQUIRE_SM_LOCK;
+ freeChain(bd);
+ RELEASE_SM_LOCK;
+}
+
static void
initMBlock(void *mblock)
{
@@ -324,8 +366,8 @@ checkFreeListSanity(void)
for (bd = free_list; bd != NULL; bd = bd->link) {
IF_DEBUG(block_alloc,
- debugBelch("group at 0x%x, length %d blocks\n",
- (nat)bd->start, bd->blocks));
+ debugBelch("group at 0x%p, length %d blocks\n",
+ bd->start, bd->blocks));
ASSERT(bd->blocks > 0);
checkWellFormedGroup(bd);
if (bd->link != NULL) {