summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund2011-08-11 15:50:17 +0000
committerAndres Freund2011-08-11 15:50:17 +0000
commite2b256c8ab70f235dde9ee4f7057f8821632d934 (patch)
tree02a13271418d2e324b547582361224e849785ad5
parent9a39751e8fea24563577dcbaa49571a646ee6325 (diff)
-rw-r--r--src/backend/utils/mmgr/ilist.h2
-rw-r--r--src/backend/utils/mmgr/mcxt.c2
-rw-r--r--src/backend/utils/mmgr/slab.c44
3 files changed, 33 insertions, 15 deletions
diff --git a/src/backend/utils/mmgr/ilist.h b/src/backend/utils/mmgr/ilist.h
index 5f8d345490..bca17fbbf8 100644
--- a/src/backend/utils/mmgr/ilist.h
+++ b/src/backend/utils/mmgr/ilist.h
@@ -115,6 +115,8 @@ static inline bool ilist_is_empty(ilist_head *head){
#define ilist_front(type, membername, ptr) (&((ptr)->head) == (ptr)->head.next) ? \
NULL : ilist_container(type, membername, (ptr)->head.next)
+#define ilist_front_really(type, membername, ptr) ilist_container(type, membername, (ptr)->head.next)
+
#define ilist_back(type, membername, ptr) (&((ptr)->head) == (ptr)->head.prev) ? \
NULL : ilist_container(type, membername, (ptr)->head.prev)
diff --git a/src/backend/utils/mmgr/mcxt.c b/src/backend/utils/mmgr/mcxt.c
index e5eba13ea6..e0f035e48c 100644
--- a/src/backend/utils/mmgr/mcxt.c
+++ b/src/backend/utils/mmgr/mcxt.c
@@ -25,7 +25,7 @@
#include "slab.h"
-//#define USE_ALLOC_SET
+#define USE_ALLOC_SET
/*****************************************************************************
* GLOBAL MEMORY *
diff --git a/src/backend/utils/mmgr/slab.c b/src/backend/utils/mmgr/slab.c
index f7850078d1..88d477af49 100644
--- a/src/backend/utils/mmgr/slab.c
+++ b/src/backend/utils/mmgr/slab.c
@@ -3,7 +3,7 @@
#define SLAB_ALLOC_SIZE 8192*16
#define SLAB_MAX_SLAB_SIZE 16384
//#define SLAB_USE_MMAP_DIRECTLY
-#define SLAB_MAIN
+//#define SLAB_MAIN
#define NDEBUG
@@ -476,7 +476,6 @@ slab_alloc_in(AllocSlabContext* context, size_t slab_idx,
AllocSlabChunk* chunk;
//assert(slab_idx);
-
if(unlikely(!top_slab)){
//there definitely is space
top_slab = slab_get_block(context);
@@ -496,29 +495,43 @@ slab_alloc_in(AllocSlabContext* context, size_t slab_idx,
}
else{
- bool is_full;
+ int32 num_allocated = top_slab->num_allocated + 1;
+ int num_free = top_slab->max_allocated - num_allocated;
+
if(top_slab->chunk_freelist){
- ++top_slab->num_allocated;
+ top_slab->num_allocated = num_allocated;
chunk = top_slab->chunk_freelist;
top_slab->chunk_freelist = chunk->next_chunk;
+ chunk->block = top_slab;
//printf("block: %p allocation from freelist with %lu allocated, max %lu el %lu\n",
// top_slab, top_slab->num_allocated, top_slab->max_allocated,
// top_slab->element_size);
+ /*
+ * No more free space on block
+ *
+ * We assume that this case cannot be hit if we have allocated a new
+ * block above as we won't ever use slab allocation for sizes where
+ * only one chunk fits on a block
+ */
+ if(unlikely(num_free == 0)){
+ //printf("block: %p block is full with %lu allocated, max %lu el %lu\n",
+ // top_slab, top_slab->num_allocated, top_slab->max_allocated,
+ // top_slab->element_size);
+ ilist_remove(&context->slab_idx[slab_idx],
+ &top_slab->block_node);
+ ilist_push_front(&context->full_blocks_head,
+ &top_slab->block_node);
+ top_slab->flags |= SLAB_BLOCK_ON_FULLLIST;
}
- else{
- //assert((top_slab->end_ptr - top_slab->free_ptr) >= top_slab->element_size);
- //chunk = (AllocSlabChunk*)(top_slab->data + top_slab->element_size * top_slab->num_allocated);
+ }
+ else{
chunk = (AllocSlabChunk*)&top_slab->data[top_slab->element_size * top_slab->num_allocated];
- ++top_slab->num_allocated;
-
+ top_slab->num_allocated = num_allocated;
+ chunk->block = top_slab;
//printf("block: %p allocation from freespace with %lu allocated, max %lu el %lu\n",
// top_slab, top_slab->num_allocated, top_slab->max_allocated,
// top_slab->element_size);
- }
- is_full = top_slab->num_allocated == top_slab->max_allocated;
- chunk->block = top_slab;
-
/*
* No more free space on block
*
@@ -526,7 +539,7 @@ slab_alloc_in(AllocSlabContext* context, size_t slab_idx,
* block above as we won't ever use slab allocation for sizes where
* only one chunk fits on a block
*/
- if(unlikely(is_full)){
+ if(unlikely(num_free == 0)){
//printf("block: %p block is full with %lu allocated, max %lu el %lu\n",
// top_slab, top_slab->num_allocated, top_slab->max_allocated,
// top_slab->element_size);
@@ -536,6 +549,9 @@ slab_alloc_in(AllocSlabContext* context, size_t slab_idx,
&top_slab->block_node);
top_slab->flags |= SLAB_BLOCK_ON_FULLLIST;
}
+
+ }
+
}
#ifndef NDEBUG
slab_check_context((MemoryContext)context);