forked from GitHub/gf-core
synchronize the mmap sizes between processes
This commit is contained in:
@@ -481,6 +481,8 @@ struct PGF_INTERNAL_DECL malloc_state
|
|||||||
/* Bitmap of bins */
|
/* Bitmap of bins */
|
||||||
unsigned int binmap[BINMAPSIZE];
|
unsigned int binmap[BINMAPSIZE];
|
||||||
|
|
||||||
|
size_t file_size;
|
||||||
|
|
||||||
/* The namespace of all persistant grammar revisions */
|
/* The namespace of all persistant grammar revisions */
|
||||||
Namespace<PgfPGF> revisions;
|
Namespace<PgfPGF> revisions;
|
||||||
|
|
||||||
@@ -499,7 +501,6 @@ struct PGF_INTERNAL_DECL malloc_state
|
|||||||
|
|
||||||
PGF_INTERNAL
|
PGF_INTERNAL
|
||||||
PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
||||||
size_t file_size;
|
|
||||||
bool is_new = false;
|
bool is_new = false;
|
||||||
bool is_first = false;
|
bool is_first = false;
|
||||||
|
|
||||||
@@ -509,24 +510,24 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
|
|
||||||
if (filepath == NULL) {
|
if (filepath == NULL) {
|
||||||
this->filepath = NULL;
|
this->filepath = NULL;
|
||||||
file_size = getpagesize();
|
mmap_size = getpagesize();
|
||||||
is_new = true;
|
is_new = true;
|
||||||
} else {
|
} else {
|
||||||
fd = open(filepath, flags, mode);
|
fd = open(filepath, flags, mode);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
throw pgf_systemerror(errno, filepath);
|
throw pgf_systemerror(errno, filepath);
|
||||||
|
|
||||||
file_size = lseek(fd, 0, SEEK_END);
|
mmap_size = lseek(fd, 0, SEEK_END);
|
||||||
if (file_size == ((off_t) -1)) {
|
if (mmap_size == ((off_t) -1)) {
|
||||||
int code = errno;
|
int code = errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
throw pgf_systemerror(code, filepath);
|
throw pgf_systemerror(code, filepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
is_new = false;
|
is_new = false;
|
||||||
if (file_size == 0) {
|
if (mmap_size == 0) {
|
||||||
file_size = getpagesize();
|
mmap_size = getpagesize();
|
||||||
if (ftruncate(fd, file_size) < 0) {
|
if (ftruncate(fd, mmap_size) < 0) {
|
||||||
int code = errno;
|
int code = errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
throw pgf_systemerror(code, filepath);
|
throw pgf_systemerror(code, filepath);
|
||||||
@@ -542,16 +543,16 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
#ifndef MREMAP_MAYMOVE
|
#ifndef MREMAP_MAYMOVE
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
ms = (malloc_state*)
|
ms = (malloc_state*)
|
||||||
mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
code = errno;
|
code = errno;
|
||||||
} else {
|
} else {
|
||||||
ms = (malloc_state*) ::malloc(file_size);
|
ms = (malloc_state*) ::malloc(mmap_size);
|
||||||
code = ENOMEM;
|
code = ENOMEM;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int mflags = (fd < 0) ? (MAP_PRIVATE | MAP_ANONYMOUS) : MAP_SHARED;
|
int mflags = (fd < 0) ? (MAP_PRIVATE | MAP_ANONYMOUS) : MAP_SHARED;
|
||||||
ms = (malloc_state*)
|
ms = (malloc_state*)
|
||||||
mmap(NULL, file_size, PROT_READ | PROT_WRITE, mflags, fd, 0);
|
mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, mflags, fd, 0);
|
||||||
code = errno;
|
code = errno;
|
||||||
#endif
|
#endif
|
||||||
if (ms == MAP_FAILED || ms == NULL) {
|
if (ms == MAP_FAILED || ms == NULL) {
|
||||||
@@ -581,12 +582,12 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
hMap = CreateFileMapping((HANDLE) _get_osfhandle(fd),
|
hMap = CreateFileMapping((HANDLE) _get_osfhandle(fd),
|
||||||
NULL,
|
NULL,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
HIWORD(file_size), LOWORD(file_size),
|
HIWORD(mmap_size), LOWORD(mmap_size),
|
||||||
NULL);
|
NULL);
|
||||||
if (hMap != NULL) {
|
if (hMap != NULL) {
|
||||||
ms = (malloc_state*) MapViewOfFile(hMap,
|
ms = (malloc_state*) MapViewOfFile(hMap,
|
||||||
FILE_MAP_WRITE,
|
FILE_MAP_WRITE,
|
||||||
0,0,file_size);
|
0,0,mmap_size);
|
||||||
if (ms == NULL) {
|
if (ms == NULL) {
|
||||||
code = last_error_to_errno();
|
code = last_error_to_errno();
|
||||||
CloseHandle(hMap);
|
CloseHandle(hMap);
|
||||||
@@ -601,7 +602,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
code = ENOMEM;
|
code = ENOMEM;
|
||||||
name = NULL;
|
name = NULL;
|
||||||
hMap = INVALID_HANDLE_VALUE;
|
hMap = INVALID_HANDLE_VALUE;
|
||||||
ms = (malloc_state*) ::malloc(file_size);
|
ms = (malloc_state*) ::malloc(mmap_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ms == NULL) {
|
if (ms == NULL) {
|
||||||
@@ -629,7 +630,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (is_new) {
|
if (is_new) {
|
||||||
init_state(file_size);
|
init_state(mmap_size);
|
||||||
} else {
|
} else {
|
||||||
if (strncmp(ms->sign, slovo, sizeof(ms->sign)) != 0) {
|
if (strncmp(ms->sign, slovo, sizeof(ms->sign)) != 0) {
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
@@ -638,7 +639,7 @@ PgfDB::PgfDB(const char* filepath, int flags, int mode) {
|
|||||||
::free(ms);
|
::free(ms);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
munmap(ms,file_size);
|
munmap(ms,mmap_size);
|
||||||
#else
|
#else
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
::free(ms);
|
::free(ms);
|
||||||
@@ -851,6 +852,8 @@ void PgfDB::init_state(size_t size)
|
|||||||
|
|
||||||
memset(ms->binmap, 0, sizeof(ms->binmap));
|
memset(ms->binmap, 0, sizeof(ms->binmap));
|
||||||
|
|
||||||
|
ms->file_size = size;
|
||||||
|
|
||||||
ms->revisions = 0;
|
ms->revisions = 0;
|
||||||
ms->transient_revisions = 0;
|
ms->transient_revisions = 0;
|
||||||
ms->transient_concr_revisions = 0;
|
ms->transient_concr_revisions = 0;
|
||||||
@@ -1310,70 +1313,10 @@ object PgfDB::malloc_internal(size_t bytes)
|
|||||||
size_t alloc_size =
|
size_t alloc_size =
|
||||||
((nb + MINSIZE - size + page_size - 1) / page_size) * page_size;
|
((nb + MINSIZE - size + page_size - 1) / page_size) * page_size;
|
||||||
|
|
||||||
size_t old_size =
|
|
||||||
ms->top + size + sizeof(size_t);
|
|
||||||
size_t new_size =
|
size_t new_size =
|
||||||
old_size + alloc_size;
|
ms->file_size + alloc_size;
|
||||||
|
|
||||||
malloc_state* new_ms;
|
resize_map(new_size);
|
||||||
#ifndef _WIN32
|
|
||||||
// OSX do not implement mremap or MREMAP_MAYMOVE
|
|
||||||
#ifndef MREMAP_MAYMOVE
|
|
||||||
if (fd >= 0) {
|
|
||||||
if (munmap(ms, old_size) == -1)
|
|
||||||
throw pgf_systemerror(errno);
|
|
||||||
ms = NULL;
|
|
||||||
if (ftruncate(fd, new_size) < 0)
|
|
||||||
throw pgf_systemerror(errno, filepath);
|
|
||||||
new_ms =
|
|
||||||
(malloc_state*) mmap(0, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
|
||||||
if (new_ms == MAP_FAILED)
|
|
||||||
throw pgf_systemerror(errno);
|
|
||||||
} else {
|
|
||||||
new_ms = (malloc_state*) realloc(ms, new_size);
|
|
||||||
if (new_ms == NULL)
|
|
||||||
throw pgf_systemerror(ENOMEM);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (fd >= 0) {
|
|
||||||
if (ftruncate(fd, new_size) < 0)
|
|
||||||
throw pgf_systemerror(errno, filepath);
|
|
||||||
}
|
|
||||||
new_ms =
|
|
||||||
(malloc_state*) mremap(ms, old_size, new_size, MREMAP_MAYMOVE);
|
|
||||||
if (new_ms == MAP_FAILED)
|
|
||||||
throw pgf_systemerror(errno);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
if (fd >= 0) {
|
|
||||||
UnmapViewOfFile(ms);
|
|
||||||
CloseHandle(hMap);
|
|
||||||
ms = NULL;
|
|
||||||
|
|
||||||
hMap = CreateFileMapping((HANDLE) _get_osfhandle(fd),
|
|
||||||
NULL,
|
|
||||||
PAGE_READWRITE,
|
|
||||||
HIWORD(new_size), LOWORD(new_size),
|
|
||||||
NULL);
|
|
||||||
if (hMap == NULL) {
|
|
||||||
hMap = INVALID_HANDLE_VALUE;
|
|
||||||
throw pgf_systemerror(last_error_to_errno());
|
|
||||||
}
|
|
||||||
|
|
||||||
new_ms = (malloc_state*) MapViewOfFile(hMap,
|
|
||||||
FILE_MAP_WRITE,
|
|
||||||
0,0,new_size);
|
|
||||||
if (new_ms == NULL)
|
|
||||||
throw pgf_systemerror(last_error_to_errno());
|
|
||||||
} else {
|
|
||||||
new_ms = (malloc_state*) realloc(ms, new_size);
|
|
||||||
if (new_ms == NULL)
|
|
||||||
throw pgf_systemerror(ENOMEM);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ms = new_ms;
|
|
||||||
current_base = (unsigned char*) ms;
|
|
||||||
|
|
||||||
victim = ptr(ms,ms->top);
|
victim = ptr(ms,ms->top);
|
||||||
|
|
||||||
@@ -1678,6 +1621,10 @@ void PgfDB::lock(DB_scope_mode m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// If another process has resized the file we must resize the map
|
||||||
|
if (mmap_size != ms->file_size)
|
||||||
|
resize_map(ms->file_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PgfDB::unlock()
|
void PgfDB::unlock()
|
||||||
@@ -1720,6 +1667,74 @@ void PgfDB::unlock()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PgfDB::resize_map(size_t new_size)
|
||||||
|
{
|
||||||
|
malloc_state* new_ms;
|
||||||
|
#ifndef _WIN32
|
||||||
|
// OSX do not implement mremap or MREMAP_MAYMOVE
|
||||||
|
#ifndef MREMAP_MAYMOVE
|
||||||
|
if (fd >= 0) {
|
||||||
|
size_t old_file_size = ms->file_size;
|
||||||
|
if (munmap(ms, mmap_size) == -1)
|
||||||
|
throw pgf_systemerror(errno);
|
||||||
|
ms = NULL;
|
||||||
|
if (old_file_size != new_size) {
|
||||||
|
if (ftruncate(fd, new_size) < 0)
|
||||||
|
throw pgf_systemerror(errno, filepath);
|
||||||
|
}
|
||||||
|
new_ms =
|
||||||
|
(malloc_state*) mmap(0, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (new_ms == MAP_FAILED)
|
||||||
|
throw pgf_systemerror(errno);
|
||||||
|
} else {
|
||||||
|
new_ms = (malloc_state*) realloc(ms, new_size);
|
||||||
|
if (new_ms == NULL)
|
||||||
|
throw pgf_systemerror(ENOMEM);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (fd >= 0 && ms->file_size != new_size) {
|
||||||
|
if (ftruncate(fd, new_size) < 0)
|
||||||
|
throw pgf_systemerror(errno, filepath);
|
||||||
|
}
|
||||||
|
new_ms =
|
||||||
|
(malloc_state*) mremap(ms, mmap_size, new_size, MREMAP_MAYMOVE);
|
||||||
|
if (new_ms == MAP_FAILED)
|
||||||
|
throw pgf_systemerror(errno);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
if (fd >= 0) {
|
||||||
|
UnmapViewOfFile(ms);
|
||||||
|
CloseHandle(hMap);
|
||||||
|
ms = NULL;
|
||||||
|
|
||||||
|
hMap = CreateFileMapping((HANDLE) _get_osfhandle(fd),
|
||||||
|
NULL,
|
||||||
|
PAGE_READWRITE,
|
||||||
|
HIWORD(new_size), LOWORD(new_size),
|
||||||
|
NULL);
|
||||||
|
if (hMap == NULL) {
|
||||||
|
hMap = INVALID_HANDLE_VALUE;
|
||||||
|
throw pgf_systemerror(last_error_to_errno());
|
||||||
|
}
|
||||||
|
|
||||||
|
new_ms = (malloc_state*) MapViewOfFile(hMap,
|
||||||
|
FILE_MAP_WRITE,
|
||||||
|
0,0,new_size);
|
||||||
|
if (new_ms == NULL)
|
||||||
|
throw pgf_systemerror(last_error_to_errno());
|
||||||
|
} else {
|
||||||
|
new_ms = (malloc_state*) realloc(ms, new_size);
|
||||||
|
if (new_ms == NULL)
|
||||||
|
throw pgf_systemerror(ENOMEM);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ms = new_ms;
|
||||||
|
current_base = (unsigned char*) ms;
|
||||||
|
mmap_size = new_size;
|
||||||
|
ms->file_size = new_size;
|
||||||
|
}
|
||||||
|
|
||||||
DB_scope::DB_scope(PgfDB *db, DB_scope_mode m)
|
DB_scope::DB_scope(PgfDB *db, DB_scope_mode m)
|
||||||
{
|
{
|
||||||
db->lock(m);
|
db->lock(m);
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ private:
|
|||||||
int fd;
|
int fd;
|
||||||
const char *filepath;
|
const char *filepath;
|
||||||
malloc_state* ms;
|
malloc_state* ms;
|
||||||
|
size_t mmap_size;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pthread_rwlock_t *rwlock;
|
pthread_rwlock_t *rwlock;
|
||||||
@@ -117,6 +118,8 @@ private:
|
|||||||
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
|
PGF_INTERNAL_DECL void lock(DB_scope_mode m);
|
||||||
PGF_INTERNAL_DECL void unlock();
|
PGF_INTERNAL_DECL void unlock();
|
||||||
|
|
||||||
|
PGF_INTERNAL_DECL void resize_map(size_t new_size);
|
||||||
|
|
||||||
friend class DB_scope;
|
friend class DB_scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user