From 54ba9b034753bb41301b84b84e39ee399c2d98b8 Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Tue, 27 Jul 2004 01:04:35 +0000 Subject: [PATCH] Refactored bufferMananger / pageCache, so that bufferMananger handles loading an unloading pages, and pageCache only implements the replacement policy. Also, used memprof to detect and remove all memory leaks (at least all memory leaks that are encountered by check_transactional2), and fixed a number of misuses of the pblHash. --- lladd/common.h | 4 +- lladd/pageCache.h | 20 ++- src/libdfa/rw.c | 3 + src/lladd/blobManager.c | 27 +++- src/lladd/bufferManager.c | 181 +++++++++++++++++++++++++- src/lladd/logger/logWriter.c | 6 +- src/lladd/page.c | 19 ++- src/lladd/page.h | 4 + src/lladd/pageCache.c | 203 +++--------------------------- src/lladd/recovery2.c | 3 + src/lladd/transactional2.c | 5 +- test/lladd/Makefile.am | 2 +- test/lladd/check_transactional2.c | 22 +++- 13 files changed, 287 insertions(+), 212 deletions(-) diff --git a/lladd/common.h b/lladd/common.h index 1ab7bd1..2a38f95 100644 --- a/lladd/common.h +++ b/lladd/common.h @@ -99,8 +99,8 @@ extern int errno; #define lsn_t long -/*#define DEBUGGING */ -/*#define PROFILE_LATCHES */ +/*#define DEBUGGING + #define PROFILE_LATCHES */ #ifdef DEBUGGING /** @todo Files that use DEBUG have to pull in stdio.h, which is a pain! */ diff --git a/lladd/pageCache.h b/lladd/pageCache.h index 00cfa5c..ac7f09a 100644 --- a/lladd/pageCache.h +++ b/lladd/pageCache.h @@ -22,11 +22,25 @@ Page * getPage(int pageid, int locktype); Note that pageCache does not perform any file I/O of its own. @todo pageCache should not include page.h at all. It should treat - pages as (int, void*) pairs. + pages as (int, void*) pairs. (But the page struct contains the + pointers that pageCache manipulates..) */ -void pageCacheInit(); +void pageCacheInit(Page * first); void pageCacheDeinit(); -/*Page * loadPage(int pageid); */ + +void cacheHitOnPage(Page * ret); +void cacheRemovePage(Page * ret); +void cacheInsertPage (Page * ret); +/** Return a page that is a reasonable candidate for replacement. This + function does not actually remove the page from cache.*/ +Page * cacheStalePage(); + +#define INITIAL 0 +#define FULL 1 + + + +extern int cache_state; #endif diff --git a/src/libdfa/rw.c b/src/libdfa/rw.c index 9487eee..f7ca7a5 100644 --- a/src/libdfa/rw.c +++ b/src/libdfa/rw.c @@ -146,6 +146,9 @@ void deletelock (rwl *lock) pthread_mutex_destroy (lock->mut); pthread_cond_destroy (lock->readOK); pthread_cond_destroy (lock->writeOK); + free(lock->mut); + free(lock->writeOK); + free(lock->readOK); free (lock); return; diff --git a/src/lladd/blobManager.c b/src/lladd/blobManager.c index e004455..46681bd 100644 --- a/src/lladd/blobManager.c +++ b/src/lladd/blobManager.c @@ -68,6 +68,7 @@ static void tripleHashInsert(int xid, recordid rid, lsn_t newLSN) { if(xidHash == NULL) { xidHash = pblHtCreate(); + DEBUG("New blob xact: xid = %d\n", xid); pblHtInsert(dirtyBlobs, &xid, sizeof(int), xidHash); } @@ -152,7 +153,17 @@ void closeBlobStore() { assert(!ret); blobf0 = NULL; blobf1 = NULL; - + pblHashTable_t * xidhash; + for(xidhash = pblHtFirst(dirtyBlobs); xidhash; xidhash = pblHtNext(dirtyBlobs)) { + fflush(NULL); + sync(); + printf("WARNING!: Found list of dirty blobs for transaction: %ld\nIt is possible that these blobs were not synced to disk properly.\n\nThe data has now been flushed to disk, but this warning could indicate a bug that could cause data corruption.", *(lsn_t*)pblHtCurrentKey(dirtyBlobs)); + fflush(NULL); + sync(); + + pblHtRemove(dirtyBlobs, 0, 0); + } + pblHtDelete(dirtyBlobs); pthread_mutex_destroy(&blob_hash_mutex); @@ -383,25 +394,29 @@ void abortBlobs(int xid) { pblHashTable_t * rid_buckets = pblHtLookup(dirtyBlobs, &xid, sizeof(int)); pblHashTable_t * this_bucket; + DEBUG("Blob cleanup xid=%d\n", xid); + if(rid_buckets) { /* Otherwise, there are no dirty blobs for this xid.. */ for(this_bucket = pblHtFirst(rid_buckets); this_bucket; this_bucket = pblHtNext(rid_buckets)) { lsn_t * rid_lsn; - int page_number; - + int page_number = *(int*)pblHtCurrentKey(rid_buckets); + /* All right, this_bucket contains all of the rids for this page. */ for(rid_lsn = pblHtFirst(this_bucket); rid_lsn; rid_lsn = pblHtNext(this_bucket)) { recordid * rid = pblHtCurrentKey(this_bucket); - page_number = rid->page; - pblHtRemove(this_bucket, rid, sizeof(recordid)); + /* page_number = rid->page; */ + assert(page_number == rid->page); + pblHtRemove(this_bucket, 0, 0);/*rid, sizeof(recordid)); */ free(rid_lsn); } - pblHtRemove(rid_buckets, &page_number, sizeof(int)); + pblHtRemove(rid_buckets, 0, 0); pblHtDelete(this_bucket); } pblHtDelete(rid_buckets); + pblHtRemove(dirtyBlobs, &xid, sizeof(int)); } pthread_mutex_unlock(&blob_hash_mutex); diff --git a/src/lladd/bufferManager.c b/src/lladd/bufferManager.c index 96a67ff..4d64853 100644 --- a/src/lladd/bufferManager.c +++ b/src/lladd/bufferManager.c @@ -57,6 +57,7 @@ terms specified in this license. #include #include "pageFile.h" +#include /** Invariant: This lock should be held while updating lastFreepage, or @@ -69,26 +70,70 @@ terms specified in this license. this lock. */ +static pblHashTable_t *activePages; /* page lookup */ + +static pthread_mutex_t loadPagePtr_mutex; + static pthread_mutex_t lastFreepage_mutex; static unsigned int lastFreepage = 0; +static Page * dummy_page; int bufInit() { pageInit(); openPageFile(); - pageCacheInit(); - openBlobStore(); + + + pthread_mutex_init(&lastFreepage_mutex , NULL); + pthread_mutex_init(&loadPagePtr_mutex, NULL); + activePages = pblHtCreate(); lastFreepage = 0; - pthread_mutex_init(&lastFreepage_mutex , NULL); + + dummy_page = pageAlloc(-1); + pageRealloc(dummy_page, -1); + Page *first; + first = pageAlloc(0); + pageRealloc(first, 0); + pblHtInsert(activePages, &first->id, sizeof(int), first); + + openBlobStore(); + + pageCacheInit(first); + + assert(activePages); + return 0; } void bufDeinit() { closeBlobStore(); + + Page *p; + DEBUG("pageCacheDeinit()"); + + for( p = (Page*)pblHtFirst( activePages ); p; p = (Page*)pblHtNext(activePages)) { + + pblHtRemove( activePages, 0, 0 ) + DEBUG("+"); + /** @todo No one seems to set the dirty flag... */ + /*if(p->dirty && (ret = pageWrite(p)/ *flushPage(*p)* /)) { + printf("ERROR: flushPage on %s line %d", __FILE__, __LINE__); + abort(); + / * exit(ret); * / + }*/ + + pageWrite(p); + } + + pthread_mutex_destroy(&loadPagePtr_mutex); + + pblHtDelete(activePages); pageCacheDeinit(); closePageFile(); + + pageDeInit(); return; } @@ -110,7 +155,7 @@ void releasePage (Page * p) { Page * lastRallocPage = 0; /** @todo ralloc ignores it's xid parameter; change the interface? */ -recordid ralloc(int xid, /*lsn_t lsn,*/ long size) { +recordid ralloc(int xid, long size) { recordid ret; Page * p; @@ -190,3 +235,131 @@ int bufTransAbort(int xid, lsn_t lsn) { return 0; } + +Page * getPage(int pageid, int locktype) { + Page * ret; + int spin = 0; + pthread_mutex_lock(&loadPagePtr_mutex); + ret = pblHtLookup(activePages, &pageid, sizeof(int)); + + if(ret) { + if(locktype == RW) { + writelock(ret->loadlatch, 217); + } else { + readlock(ret->loadlatch, 217); + } + } + + while (ret && (ret->id != pageid)) { + unlock(ret->loadlatch); + pthread_mutex_unlock(&loadPagePtr_mutex); + sched_yield(); + pthread_mutex_lock(&loadPagePtr_mutex); + ret = pblHtLookup(activePages, &pageid, sizeof(int)); + + if(ret) { + // writelock(ret->loadlatch, 217); + if(locktype == RW) { + writelock(ret->loadlatch, 217); + } else { + readlock(ret->loadlatch, 217); + } + } + spin++; + if(spin > 10000) { + printf("GetPage is stuck!"); + } + } + + if(ret) { + cacheHitOnPage(ret); + assert(ret->id == pageid); + pthread_mutex_unlock(&loadPagePtr_mutex); + } else { + + /* If ret is null, then we know that: + + a) there is no cache entry for pageid + b) this is the only thread that has gotten this far, + and that will try to add an entry for pageid + c) the most recent version of this page has been + written to the OS's file cache. */ + int oldid = -1; + + if( cache_state == FULL ) { + + /* Select an item from cache, and remove it atomicly. (So it's + only reclaimed once) */ + + ret = cacheStalePage(); + cacheRemovePage(ret); + + oldid = ret->id; + + assert(oldid != pageid); + + } else { + + ret = pageAlloc(-1); + ret->id = -1; + ret->inCache = 0; + } + + writelock(ret->loadlatch, 217); + + /* Inserting this into the cache before releasing the mutex + ensures that constraint (b) above holds. */ + pblHtInsert(activePages, &pageid, sizeof(int), ret); + + pthread_mutex_unlock(&loadPagePtr_mutex); + + /* Could writelock(ret) go here? */ + + assert(ret != dummy_page); + if(ret->id != -1) { + pageWrite(ret); + } + + pageRealloc(ret, pageid); + + pageRead(ret); + + writeunlock(ret->loadlatch); + + pthread_mutex_lock(&loadPagePtr_mutex); + + /* pblHtRemove(activePages, &(ret->id), sizeof(int)); */ + pblHtRemove(activePages, &(oldid), sizeof(int)); + + /* Put off putting this back into cache until we're done with + it. -- This could cause the cache to empty out if the ratio of + threads to buffer slots is above ~ 1/3, but it decreases the + liklihood of thrashing. */ + cacheInsertPage(ret); + + pthread_mutex_unlock(&loadPagePtr_mutex); + + if(locktype == RW) { + writelock(ret->loadlatch, 217); + } else { + readlock(ret->loadlatch, 217); + } + if(ret->id != pageid) { + unlock(ret->loadlatch); + printf("pageCache.c: Thrashing detected. Strongly consider increasing LLADD's buffer pool size!\n"); + fflush(NULL); + return getPage(pageid, locktype); + } + + } + + assert(ret->id == pageid); + + return ret; + +} + +Page *loadPage(int pageid) { + Page * ret = getPage(pageid, RW); + return ret; +} diff --git a/src/lladd/logger/logWriter.c b/src/lladd/logger/logWriter.c index 548dbff..85dbd6f 100644 --- a/src/lladd/logger/logWriter.c +++ b/src/lladd/logger/logWriter.c @@ -319,7 +319,8 @@ void closeLogWriter() { deletelock(flushedLSN_lock); deletelock(nextAvailableLSN_lock); deletelock(log_read_lock); - pthread_mutex_destroy(&log_write_mutex); + pthread_mutex_destroy(&log_write_mutex); + pthread_mutex_destroy(&truncateLog_mutex); } @@ -356,14 +357,17 @@ static LogEntry * readLogEntry() { if(nmemb != 1) { /* Partial log entry. */ if(feof(log)) { + free(ret); return NULL; } if(ferror(log)) { perror("Error reading log!"); + free(ret); assert(0); return 0; } assert(0); + free(ret); return 0; } diff --git a/src/lladd/page.c b/src/lladd/page.c index 27a519a..ad3585b 100644 --- a/src/lladd/page.c +++ b/src/lladd/page.c @@ -406,6 +406,21 @@ void pageInit() { pthread_mutex_init(&pageAllocMutex, NULL); + for(int i = 0; i < MAX_BUFFER_SIZE+1; i++) { + pool[i].rwlatch = initlock(); + pool[i].loadlatch = initlock(); + pool[i].memAddr = malloc(PAGE_SIZE); + } + +} + +void pageDeInit() { + for(int i = 0; i < MAX_BUFFER_SIZE+1; i++) { + + deletelock(pool[i].rwlatch); + deletelock(pool[i].loadlatch); + free(pool[i].memAddr); + } } typedef struct { @@ -690,10 +705,10 @@ Page *pageAlloc(int id) { /* We have an implicit lock on rwlatch, since we allocated it, but haven't returned yet. */ - page->rwlatch = initlock(); + /* page->rwlatch = initlock(); page->loadlatch = initlock(); - page->memAddr = malloc(PAGE_SIZE); + page->memAddr = malloc(PAGE_SIZE); */ nextPage++; assert(nextPage <= MAX_BUFFER_SIZE + 1); /* There's a dummy page that we need to keep around, thus the +1 */ diff --git a/src/lladd/page.h b/src/lladd/page.h index 58e2138..1b13402 100644 --- a/src/lladd/page.h +++ b/src/lladd/page.h @@ -192,6 +192,8 @@ struct Page_s { */ void pageInit(); +void pageDeInit(); + /** * assumes that the page is already loaded in memory. It takes * as a parameter a Page. The Page struct contains the new LSN and the page @@ -258,6 +260,8 @@ void pageDeRalloc(Page * page, recordid rid); int pageGetSlotType(Page * p, int slot, int type); void pageSetSlotType(Page * p, int slot, int type); +Page * loadPage(int page); +Page * getPage(int page, int mode); END_C_DECLS diff --git a/src/lladd/pageCache.c b/src/lladd/pageCache.c index f20eb61..87ed936 100644 --- a/src/lladd/pageCache.c +++ b/src/lladd/pageCache.c @@ -7,54 +7,34 @@ */ #include #include -#include "latches.h" + #include "page.h" #include #include #include -#include + #include #include "pageFile.h" -static pblHashTable_t *activePages; /* page lookup */ static unsigned int bufferSize; /* < MAX_BUFFER_SIZE */ static Page *repHead, *repMiddle, *repTail; /* replacement policy */ -static pthread_mutex_t loadPagePtr_mutex; -#define INITIAL 0 -#define FULL 1 +int cache_state; -static int state; -/* These three functions are for internal use. They are not declared - static so that their test case can compile. */ -static void cacheHitOnPage(Page * ret); -static void cacheRemovePage(Page * ret); -static void cacheInsertPage (Page * ret); +void pageCacheInit(Page * first) { -static Page * dummy_page; -void pageCacheInit() { - - Page *first; bufferSize = 1; - state = INITIAL; + cache_state = INITIAL; - pthread_mutex_init(&loadPagePtr_mutex, NULL); - activePages = pblHtCreate(); - assert(activePages); DEBUG("pageCacheInit()"); - first = pageAlloc(0); - dummy_page = pageAlloc(-1); - pageRealloc(first, 0); - pageRealloc(dummy_page, -1); first->inCache = 1; - pblHtInsert(activePages, &first->id, sizeof(int), first); - + first->prev = first->next = NULL; /* pageMap(first); */ pageRead(first); @@ -66,25 +46,7 @@ void pageCacheInit() { } void pageCacheDeinit() { - Page *p; - DEBUG("pageCacheDeinit()"); - for( p = (Page*)pblHtFirst( activePages ); p; p = (Page*)pblHtRemove( activePages, 0, 0 )) { - DEBUG("+"); - /** @todo No one seems to set the dirty flag... */ - /*if(p->dirty && (ret = pageWrite(p)/ *flushPage(*p)* /)) { - printf("ERROR: flushPage on %s line %d", __FILE__, __LINE__); - abort(); - / * exit(ret); * / - }*/ - - pageWrite(p); - } - - pthread_mutex_destroy(&loadPagePtr_mutex); - - - pblHtDelete(activePages); } static void headInsert(Page *ret) { @@ -101,7 +63,7 @@ static void headInsert(Page *ret) { static void middleInsert(Page *ret) { - assert(state == FULL); + assert(cache_state == FULL); /* assert( bufferSize == MAX_BUFFER_SIZE ); */ @@ -122,7 +84,7 @@ static void middleInsert(Page *ret) { /** @todo Under high contention, the buffer pool can empty. What should be done about this, other than making sure that # threads > buffer size? */ static void qRemove(Page *ret) { - assert(state == FULL); + assert(cache_state == FULL); assert(ret->next != ret && ret->prev != ret); @@ -145,150 +107,18 @@ static void qRemove(Page *ret) { assert(ret != repHead); } -Page * getPage(int pageid, int locktype) { - Page * ret; - int spin = 0; - pthread_mutex_lock(&loadPagePtr_mutex); - ret = pblHtLookup(activePages, &pageid, sizeof(int)); - - if(ret) { - if(locktype == RW) { - writelock(ret->loadlatch, 217); - } else { - readlock(ret->loadlatch, 217); - } - //writelock(ret->loadlatch, 217); - } - - while (ret && (ret->id != pageid)) { - unlock(ret->loadlatch); - pthread_mutex_unlock(&loadPagePtr_mutex); - sched_yield(); - pthread_mutex_lock(&loadPagePtr_mutex); - ret = pblHtLookup(activePages, &pageid, sizeof(int)); - - if(ret) { - // writelock(ret->loadlatch, 217); - if(locktype == RW) { - writelock(ret->loadlatch, 217); - } else { - readlock(ret->loadlatch, 217); - } - } - spin++; - if(spin > 10000) { - printf("GetPage is stuck!"); - } - } - - if(ret) { - cacheHitOnPage(ret); - assert(ret->id == pageid); - pthread_mutex_unlock(&loadPagePtr_mutex); - } else { - - /* If ret is null, then we know that: - - a) there is no cache entry for pageid - b) this is the only thread that has gotten this far, - and that will try to add an entry for pageid - c) the most recent version of this page has been - written to the OS's file cache. */ - int oldid = -1; - - if( state == FULL ) { - - /* Select an item from cache, and remove it atomicly. (So it's - only reclaimed once) */ - - ret = repTail; - cacheRemovePage(ret); - - oldid = ret->id; - - assert(oldid != pageid); - - } else { - - ret = pageAlloc(-1); - ret->id = -1; - ret->inCache = 0; - } - - writelock(ret->loadlatch, 217); - - /* Inserting this into the cache before releasing the mutex - ensures that constraint (b) above holds. */ - pblHtInsert(activePages, &pageid, sizeof(int), ret); - - pthread_mutex_unlock(&loadPagePtr_mutex); - - /* Could writelock(ret) go here? */ - - assert(ret != dummy_page); - if(ret->id != -1) { - pageWrite(ret); - } - - pageRealloc(ret, pageid); - - pageRead(ret); - - writeunlock(ret->loadlatch); - - pthread_mutex_lock(&loadPagePtr_mutex); - - /* pblHtRemove(activePages, &(ret->id), sizeof(int)); */ - pblHtRemove(activePages, &(oldid), sizeof(int)); - - /* Put off putting this back into cache until we're done with - it. -- This could cause the cache to empty out if the ratio of - threads to buffer slots is above ~ 1/3, but it decreases the - liklihood of thrashing. */ - cacheInsertPage(ret); - - pthread_mutex_unlock(&loadPagePtr_mutex); - - /* downgradelock(ret->loadlatch); */ - - // writelock(ret->loadlatch, 217); - if(locktype == RW) { - writelock(ret->loadlatch, 217); - } else { - readlock(ret->loadlatch, 217); - } - if(ret->id != pageid) { - unlock(ret->loadlatch); - printf("pageCache.c: Thrashing detected. Strongly consider increasing LLADD's buffer pool size!\n"); - fflush(NULL); - return getPage(pageid, locktype); - } - - /* } else { - - pthread_mutex_unlock(&loadPagePtr_mutex); - - } */ - } - - assert(ret->id == pageid); - - return ret; - -} - -static void cacheInsertPage (Page * ret) { +void cacheInsertPage (Page * ret) { bufferSize++; assert(!ret->inCache); ret->inCache ++; - if(state == FULL) { + if(cache_state == FULL) { middleInsert(ret); } else { if(bufferSize == MAX_BUFFER_SIZE/* - 1*/) { /* Set up page kick mechanism. */ int i; Page *iter; - state = FULL; + cache_state = FULL; headInsert(ret); assert(ret->next != ret && ret->prev != ret); @@ -314,16 +144,16 @@ static void cacheInsertPage (Page * ret) { } } -static void cacheRemovePage(Page * ret) { +void cacheRemovePage(Page * ret) { assert(ret->inCache); qRemove(ret); ret->inCache--; bufferSize --; } -static void cacheHitOnPage(Page * ret) { +void cacheHitOnPage(Page * ret) { /* The page may not be in cache if it is about to be freed. */ - if(ret->inCache && state == FULL) { /* we need to worry about page sorting */ + if(ret->inCache && cache_state == FULL) { /* we need to worry about page sorting */ /* move to head */ if( ret != repHead ) { qRemove(ret); @@ -341,7 +171,6 @@ static void cacheHitOnPage(Page * ret) { } } -Page *loadPage(int pageid) { - Page * ret = getPage(pageid, RW); - return ret; +Page * cacheStalePage() { + return repTail; } diff --git a/src/lladd/recovery2.c b/src/lladd/recovery2.c index 82f2534..913c6c7 100644 --- a/src/lladd/recovery2.c +++ b/src/lladd/recovery2.c @@ -168,6 +168,7 @@ static void Redo() { redoUpdate(e); } } + free(e); } } @@ -247,7 +248,9 @@ static void Undo(int recovery) { printf ("Unknown log type to undo (TYPE=%d, XID= %d, LSN=%ld), skipping...\n", e->type, e->xid, e->LSN); break; } + free(e); } + /* printf("$"); fflush(NULL); */ } free(prepare_guard_state); diff --git a/src/lladd/transactional2.c b/src/lladd/transactional2.c index dd3cbe9..90d24bc 100644 --- a/src/lladd/transactional2.c +++ b/src/lladd/transactional2.c @@ -101,7 +101,6 @@ void Tupdate(int xid, recordid rid, const void *dat, int op) { p = loadPage(rid.page); - /* KLUDGE re-enable loggging!*/ e = LogUpdate(&XactionTable[xid % MAX_TRANSACTIONS], p, rid, op, dat); assert(XactionTable[xid % MAX_TRANSACTIONS].prevLSN == e->LSN); @@ -111,6 +110,8 @@ void Tupdate(int xid, recordid rid, const void *dat, int op) { doUpdate(e, p); releasePage(p); + free(e); + } void Tread(int xid, recordid rid, void * dat) { @@ -124,6 +125,7 @@ int Tcommit(int xid) { #ifdef DEBUGGING pthread_mutex_lock(&transactional_2_mutex); assert(numActiveXactions <= MAX_TRANSACTIONS); + pthread_mutex_unlock(&transactional_2_mutex); #endif lsn = LogTransCommit(&XactionTable[xid % MAX_TRANSACTIONS]); @@ -166,6 +168,7 @@ int Tdeinit() { for( i = 0; i < MAX_TRANSACTIONS; i++ ) { if( XactionTable[i].xid != INVALID_XTABLE_XID ) { Tabort(XactionTable[i].xid); + printf("WARNING: Tdeinit() is aborting transaction %d\n", XactionTable[i].xid); } } assert( numActiveXactions == 0 ); diff --git a/test/lladd/Makefile.am b/test/lladd/Makefile.am index f98a867..e1e2c5b 100644 --- a/test/lladd/Makefile.am +++ b/test/lladd/Makefile.am @@ -6,6 +6,6 @@ else TESTS = endif noinst_PROGRAMS = $(TESTS) -LDADD = @CHECK_LIBS@ $(top_builddir)/src/lladd/liblladd.a $(top_builddir)/src/pbl/libpbl.a $(top_builddir)/src/libdfa/librw.a #-lefence +LDADD = @CHECK_LIBS@ $(top_builddir)/src/lladd/liblladd.a $(top_builddir)/src/pbl/libpbl.a $(top_builddir)/src/libdfa/librw.a -lefence CLEANFILES = check_lht.log check_logEntry.log storefile.txt logfile.txt blob0_file.txt blob1_file.txt check_blobRecovery.log check_logWriter.log check_operations.log check_recovery.log check_transactional2.log check_page.log check_bufferManager.log AM_CFLAGS= -g -Wall -pedantic -std=gnu99 diff --git a/test/lladd/check_transactional2.c b/test/lladd/check_transactional2.c index 61f14e6..5766900 100644 --- a/test/lladd/check_transactional2.c +++ b/test/lladd/check_transactional2.c @@ -121,7 +121,7 @@ void * writingAbortingBlobWorkerThread ( void * v ) { } Tcommit(xid); - + free(rids); return NULL; } @@ -179,7 +179,9 @@ void * writingAbortingWorkerThread ( void * v ) { } Tcommit(xid); - + + free (rids); + return NULL; } @@ -226,7 +228,8 @@ void * writingWorkerThread ( void * v ) { } Tcommit(xid); - + free(rids); + return NULL; } @@ -297,9 +300,7 @@ START_TEST(transactional_blobSmokeTest) { fail_unless(rid.size == ARRAY_SIZE * sizeof(int), NULL); - printf("TSet starting.\n"); fflush(NULL); Tset(xid, rid, &foo); - printf("TSet returning.\n"); fflush(NULL); Tread(xid, rid, &bar); @@ -432,6 +433,17 @@ START_TEST(transactional_blobs_threads_abort) { } Tdeinit(); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + sleep (10000000); + } END_TEST /**