From 93e7e96ea33aa929d012f27a396eb6ba6b3eba9a Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Thu, 22 Jun 2006 19:10:02 +0000 Subject: [PATCH] Started implementing the region allocator --- lladd/operations.h | 2 +- lladd/operations/regions.h | 19 +++++ src/lladd/Makefile.am | 3 +- src/lladd/operations/pageOperations.c | 7 +- src/lladd/operations/regions.c | 106 ++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 lladd/operations/regions.h create mode 100644 src/lladd/operations/regions.c diff --git a/lladd/operations.h b/lladd/operations.h index cda0ced..01f9e4b 100644 --- a/lladd/operations.h +++ b/lladd/operations.h @@ -167,7 +167,7 @@ typedef struct { #include "operations/linkedListNTA.h" #include "operations/pageOrientedListNTA.h" #include "operations/linearHashNTA.h" - +#include "operations/regions.h" extern Operation operationsTable[]; /* [MAX_OPERATIONS]; memset somewhere */ diff --git a/lladd/operations/regions.h b/lladd/operations/regions.h new file mode 100644 index 0000000..c71ae76 --- /dev/null +++ b/lladd/operations/regions.h @@ -0,0 +1,19 @@ +/** + Allocates and deallocates regions of pages. The page before each + region is of type BOUNDARY_TAG. All regions except the last one in + the page file have a BOUNDARY_TAG page immediately after the end of + the region. + + Each region is managed by an allocation manager, which manages the + allocation of pages within a region. The contents of pages within + a newly allocated region are undefined. +*/ + +int TregionAlloc(int xid, int pageCount); +void TregionFree(int xid, int firstPage); +int TregionSize(int xid, int firstPage); + +Operation getRegionAlloc(); +Operation getRegionFree(); + +// XXX need callbacks to handle transaction commit/abort. diff --git a/src/lladd/Makefile.am b/src/lladd/Makefile.am index 35b239b..6ba457d 100644 --- a/src/lladd/Makefile.am +++ b/src/lladd/Makefile.am @@ -16,7 +16,8 @@ liblladd_a_SOURCES=crc32.c lhtable.c common.c stats.c io.c bufferManager.c linke operations/arrayList.c hash.c operations/linearHash.c \ operations/naiveLinearHash.c operations/nestedTopActions.c \ operations/linearHashNTA.c operations/linkedListNTA.c \ - operations/pageOrientedListNTA.c operations/bTree.c + operations/pageOrientedListNTA.c operations/bTree.c \ + operations/regions.c # logger/logMemory.c \ ringbuffer.c \ asdfas #operations/lladdhash.c diff --git a/src/lladd/operations/pageOperations.c b/src/lladd/operations/pageOperations.c index c00a870..db12c4f 100644 --- a/src/lladd/operations/pageOperations.c +++ b/src/lladd/operations/pageOperations.c @@ -212,15 +212,12 @@ compensated_function int TpageDealloc(int xid, int pageid) { rid.page = pageid; rid.slot = 0; rid.size = 0; -#endif - -#ifdef REUSE_PAGES assert(freelist != pageid); t.before = freelist; - //#endif + Tupdate(xid, rid, &freelist, OPERATION_FREE_PAGE); - //#ifdef REUSE_PAGES + t.after = pageid; freelist = pageid; rid.page = 0; diff --git a/src/lladd/operations/regions.c b/src/lladd/operations/regions.c new file mode 100644 index 0000000..d9cadca --- /dev/null +++ b/src/lladd/operations/regions.c @@ -0,0 +1,106 @@ +#include "../page.h" +#include + +#define REGION_BASE (123) +#define REGION_VACANT (REGION_BASE + 0) +#define REGION_ZONED (REGION_BASE + 1) +#define REGION_OCCUPIED (REGION_BASE + 2) +#define REGION_CONDEMNED (REGION_BASE + 3) + +#define boundary_tag_ptr(p) (((byte*)end_of_usable_space_ptr((p)))-sizeof(boundary_tag_t)) + +typedef struct boundary_tag_t { + int size; + int prev_size; + int status; + int region_xid; + int allocation_manager; +} boundary_tag_t; + + +void boundaryTagInit(Page * p) { + *page_type_ptr(p) = LLADD_BOUNDARY_TAG; + boundary_tag_t * tag = boundary_tag_ptr(p); + tag.size = INT32_MAX; + tag.prev_size = -1; + tag.status = REGION_VACANT; + tag.region_xid = INVALID_XID; + tag.allocation_manager = 0; +} + +regionsInit() { + Page * p = loadPage(0); + if(*page_type_ptr(p) != LLADD_BOUNDARY_TAG) { + assert(*page_type_ptr(p) == 0); + boundaryTagInit(p); + } + releasePage(p); +} + +pthread_mutex_t region_mutex = PTHREAD_MUTEX_INITIALIZER; + +int TregionAlloc(int xid, int pageCount, int allocationManager) { + // Initial implementation. Naive first fit. + pthread_mutex_lock(®ion_mutex); + int ret = -1; + Page * p = loadPage(0); + boundary_tag_t * t = boundary_tag_ptr(p); + while(t.status != REGION_VACANT || t.size < pageCount) { // XXX This while loop and the boundary tag manipulation below should be factored into two submodules. + int nextPage = p->id + t.size; + releasePage(p); + p = loadPage(nextPage); + t = boundary_tag_ptr(p); + } + t->status = REGION_ZONED; + t->region_xid = xid; + t->allocation_manager = allocationManager; + if(t->size != pageCount) { + // need to split region + + if(t.size != INT_MAX) { + + // allocate new boundary tag. + int newRegionSize = t->size - pageCount - 1; // pageCount must be strictly less than t->size, so this is safe. + Page * new_tag = loadPage(p->id + pageCount + 1); + boundaryTagInit(p); + boundary_tag_ptr(p)->size = newRegionSize; + boundary_tag_ptr(p)->prev_size = pageCount; + boundary_tag_ptr(p)->status = REGION_EPHEMERAL; // region disappears if transaction aborts; is VACANT if it succeeds. GET RID OF EPHEMERAL; just make it vacant, and merge on abort. + boundary_tag_ptr(p)->region_xid = xid; + boundary_tag_ptr(p)->allocation_manager = 0; + releasePage(new_tag); + + Page * next = loadPage(p->id + t.size + 1); + boundary_tag_ptr(next)->prev_size = newRegionSize; + releasePage(next); + } else { + Page * new_tag = loadPage(p->id + pageCount + 1); + boundaryTagInit(p); + boundary_tag_ptr(p)->size = INT_MAX; + boundary_tag_ptr(p)->prev_size = pageCount; + boundary_tag_ptr(p)->status = REGION_EPHEMERAL; + boundary_tag_ptr(p)->region_xid = xid; + boundary_tag_ptr(p)->allocation_manager = 0; + } + + } + releasePage(p); + + pthread_mutex_unlock(®ion_mutex); +} + +void TregionFree(int xid, int firstPage) { + +} + +int TregionSize(int xid, int firstPage) { + +} + +Operation getRegionAlloc() { + +} + +Operation getRegionFree() { + +}