From a3d73fa6588209063f156a97b140e61202da2866 Mon Sep 17 00:00:00 2001 From: Krasimir Angelov Date: Mon, 23 May 2022 11:33:47 +0200 Subject: [PATCH] register_revision must refresh the transaction to the latest --- src/runtime/c/pgf/db.cxx | 77 +++++++++++++++++++++++++++++++++------- src/runtime/c/pgf/db.h | 4 ++- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/runtime/c/pgf/db.cxx b/src/runtime/c/pgf/db.cxx index 735c4aab9..36bfc8a4b 100644 --- a/src/runtime/c/pgf/db.cxx +++ b/src/runtime/c/pgf/db.cxx @@ -349,6 +349,8 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) { free_descriptors[0] = ms->free_descriptors; free_descriptors[1] = 0; free_descriptors[2] = 0; + last_free_block = 0; + last_free_block_size= 0; } PGF_INTERNAL @@ -400,39 +402,63 @@ void PgfDB::register_revision(object o) WaitForSingleObject(hMutex, INFINITE); #endif + bool found = false; revision_entry *free_entry = NULL; +#ifdef DEBUG_MEMORY_ALLOCATOR + fprintf(stderr, "revisions"); +#endif + + ms->min_txn_id = SIZE_MAX; for (size_t i = 0; i < ms->n_revisions; i++) { revision_entry *entry = &ms->revisions[i]; if (entry->ref_count == 0) { if (free_entry == NULL) free_entry = entry; } else { +#ifdef DEBUG_MEMORY_ALLOCATOR + fprintf(stderr, " %ld:%s(%016lx):%ld", + entry->txn_id, + ((entry->o & MALLOC_ALIGN_MASK) == PgfPGF::tag) ? "pgf" : "concr", + entry->o & ~MALLOC_ALIGN_MASK, + entry->ref_count); +#endif + if (entry->pid == pid && entry->o == o) { entry->ref_count++; - goto done; + entry->txn_id = ms->curr_txn_id; + found = true; } + + if (ms->min_txn_id > entry->txn_id) + ms->min_txn_id = entry->txn_id; } } - if (free_entry == NULL) { - size_t n_max = (page_size-sizeof(malloc_state))/sizeof(revision_entry); - if (ms->n_revisions >= n_max) { + if (!found) { + if (free_entry == NULL) { + size_t n_max = (page_size-sizeof(malloc_state))/sizeof(revision_entry); + if (ms->n_revisions >= n_max) { #ifndef _WIN32 - pthread_mutex_unlock(&ms->mutex); + pthread_mutex_unlock(&ms->mutex); #else - ReleaseMutex(hMutex); + ReleaseMutex(hMutex); #endif - throw pgf_error("Too many retained database revisions"); + throw pgf_error("Too many retained database revisions"); + } + free_entry = &ms->revisions[ms->n_revisions++]; } - free_entry = &ms->revisions[ms->n_revisions++]; + + free_entry->pid = pid; + free_entry->o = o; + free_entry->ref_count = 1; + free_entry->txn_id = ms->curr_txn_id; } - free_entry->pid = pid; - free_entry->o = o; - free_entry->ref_count = 1; - free_entry->txn_id = ms->curr_txn_id; +#ifdef DEBUG_MEMORY_ALLOCATOR + fprintf(stderr, " minimal %ld\n", ms->min_txn_id); +#endif done: #ifndef _WIN32 @@ -1175,6 +1201,24 @@ void PgfDB::free_internal(object o, size_t bytes) return; } + if (last_free_block != 0) { + if (last_free_block+last_free_block_size == o) { + last_free_block_size += block_size; +#ifdef DEBUG_MEMORY_ALLOCATOR + fprintf(stderr, "merged block %016lx %ld\n", last_free_block, last_free_block_size); +#endif + } else if (o+block_size == last_free_block) { + last_free_block = o; + last_free_block_size += block_size; +#ifdef DEBUG_MEMORY_ALLOCATOR + fprintf(stderr, "merged block %016lx %ld\n", last_free_block, last_free_block_size); +#endif + } + } + + last_free_block = o; + last_free_block_size = block_size; + free_blocks = insert_block_descriptor(free_blocks, o, block_size); #ifdef DEBUG_MEMORY_ALLOCATOR @@ -1217,11 +1261,18 @@ void PgfDB::start_transaction() free_descriptors[0] = ms->free_descriptors; free_descriptors[1] = 0; free_descriptors[2] = 0; + last_free_block = 0; + last_free_block_size = 0; } PGF_INTERNAL void PgfDB::commit(object o) { + if (last_free_block != 0) { + last_free_block = 0; + last_free_block_size = 0; + } + malloc_state *ms = current_db->ms; object save_top = ms->top; object save_free_blocks = ms->free_blocks; @@ -1312,6 +1363,8 @@ void PgfDB::rollback() free_descriptors[0] = ms->free_descriptors; free_descriptors[1] = 0; free_descriptors[2] = 0; + last_free_block = 0; + last_free_block_size = 0; } #ifdef _WIN32 diff --git a/src/runtime/c/pgf/db.h b/src/runtime/c/pgf/db.h index 9d0dbad60..6d7e50412 100644 --- a/src/runtime/c/pgf/db.h +++ b/src/runtime/c/pgf/db.h @@ -68,9 +68,11 @@ private: // The following four fields are normally equal to // the corresponding fields in the malloc_state. // The exception is when a transaction is active. - object top; + object top; object free_blocks; object free_descriptors[3]; + object last_free_block; + size_t last_free_block_size; size_t mmap_size; size_t page_size;