Commit 259c9384 authored by Kirill Terekhov's avatar Kirill Terekhov

Possibly fix thread safety issue

Creating elements cause reallocation of internal array, pointing to blocks of data. Other processor may use deallocated pointer to the array stored in cache.
parent 25787484
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <limits> #include <limits>
#include "inmost_common.h" #include "inmost_common.h"
#define __VOLATILE volatile
//#define OUT_OF_RANGE //#define OUT_OF_RANGE
//TODO //TODO
...@@ -2142,7 +2143,7 @@ namespace INMOST ...@@ -2142,7 +2143,7 @@ namespace INMOST
static size_type const fwd_alloc_chunk_bits_mask = (1 << (fwd_alloc_chunk_bits))-1; static size_type const fwd_alloc_chunk_bits_mask = (1 << (fwd_alloc_chunk_bits))-1;
static size_type const fwd_alloc_chunk_val = 1 << fwd_alloc_chunk_bits; static size_type const fwd_alloc_chunk_val = 1 << fwd_alloc_chunk_bits;
static size_type const fwd_alloc_chunk_size = sizeof(element *)*fwd_alloc_chunk_val; static size_type const fwd_alloc_chunk_size = sizeof(element *)*fwd_alloc_chunk_val;
element ** chunks; element ** __VOLATILE chunks;
size_type m_size; size_type m_size;
//This neads static_cast to unsigned to //This neads static_cast to unsigned to
__INLINE size_type GetChunkNumber(size_type k) const {return static_cast<uenum>(k) >> block_bits;} __INLINE size_type GetChunkNumber(size_type k) const {return static_cast<uenum>(k) >> block_bits;}
...@@ -2269,13 +2270,21 @@ namespace INMOST ...@@ -2269,13 +2270,21 @@ namespace INMOST
{ {
if( newn > 0 ) if( newn > 0 )
{ {
chunks = (element **) realloc(chunks,fwd_alloc_chunk_size*newn); element ** __VOLATILE chunks_old = chunks;
assert(chunks != NULL); element ** __VOLATILE chunks_new = (element **)malloc(fwd_alloc_chunk_size*newn);
if( newn > oldn ) memset(chunks+oldn*fwd_alloc_chunk_val,0,fwd_alloc_chunk_size*(newn-oldn)); assert(chunks_new != NULL);
memcpy(chunks_new, chunks_old, fwd_alloc_chunk_size*oldn);
memset(chunks_new + oldn*fwd_alloc_chunk_val, 0, fwd_alloc_chunk_size*(newn - oldn));
chunks = chunks_new; //this must be atomic
free(chunks_old); //hopefully no other thread use it
//chunks = (element **) realloc(chunks,fwd_alloc_chunk_size*newn);
//assert(chunks != NULL);
//if( newn > oldn ) memset(chunks+oldn*fwd_alloc_chunk_val,0,fwd_alloc_chunk_size*(newn-oldn));
} }
else else
{ {
free(chunks); free((void *)chunks);
chunks = NULL; chunks = NULL;
} }
} }
...@@ -2305,7 +2314,7 @@ namespace INMOST ...@@ -2305,7 +2314,7 @@ namespace INMOST
free(chunks[q]); free(chunks[q]);
chunks[q] = NULL; chunks[q] = NULL;
} }
free(chunks); free((void *)chunks);
chunks = NULL; chunks = NULL;
m_size = 0; m_size = 0;
} }
...@@ -2420,7 +2429,7 @@ namespace INMOST ...@@ -2420,7 +2429,7 @@ namespace INMOST
static size_type const fwd_alloc_chunk_bits_mask = (1 << (fwd_alloc_chunk_bits))-1; static size_type const fwd_alloc_chunk_bits_mask = (1 << (fwd_alloc_chunk_bits))-1;
static size_type const fwd_alloc_chunk_val = 1 << fwd_alloc_chunk_bits; static size_type const fwd_alloc_chunk_val = 1 << fwd_alloc_chunk_bits;
static size_type const fwd_alloc_chunk_size = sizeof(char *)*fwd_alloc_chunk_val; static size_type const fwd_alloc_chunk_size = sizeof(char *)*fwd_alloc_chunk_val;
char ** chunks; char ** __VOLATILE chunks;
size_type record_size; size_type record_size;
size_type m_size; size_type m_size;
...@@ -2467,13 +2476,20 @@ namespace INMOST ...@@ -2467,13 +2476,20 @@ namespace INMOST
{ {
if( newn > 0 ) if( newn > 0 )
{ {
chunks = reinterpret_cast<char **>(realloc(chunks,fwd_alloc_chunk_size*newn)); char ** __VOLATILE chunks_old = chunks;
assert(chunks != NULL); char ** __VOLATILE chunks_new = (char **)malloc(fwd_alloc_chunk_size*newn);
if( newn > oldn ) memset(chunks+oldn*fwd_alloc_chunk_val,0,fwd_alloc_chunk_size*(newn-oldn)); assert(chunks_new != NULL);
memcpy(chunks_new, chunks_old, fwd_alloc_chunk_size*oldn);
memset(chunks_new + oldn*fwd_alloc_chunk_val, 0, fwd_alloc_chunk_size*(newn - oldn));
chunks = chunks_new; //this must be atomic
free(chunks_old); //hopefully no other thread use it
//chunks = reinterpret_cast<char **>(realloc(chunks,fwd_alloc_chunk_size*newn));
//assert(chunks != NULL);
//if( newn > oldn ) memset(chunks+oldn*fwd_alloc_chunk_val,0,fwd_alloc_chunk_size*(newn-oldn));
} }
else else
{ {
free(chunks); free((void *)chunks);
chunks = NULL; chunks = NULL;
} }
} }
...@@ -2481,8 +2497,8 @@ namespace INMOST ...@@ -2481,8 +2497,8 @@ namespace INMOST
{ {
assert(chunks[q] == NULL); assert(chunks[q] == NULL);
chunks[q] = static_cast<char *>(malloc(block_size*record_size)); chunks[q] = static_cast<char *>(malloc(block_size*record_size));
memset(chunks[q],0,block_size*record_size);
assert(chunks[q] != NULL); assert(chunks[q] != NULL);
memset(chunks[q],0,block_size*record_size);
} }
} }
public: public:
...@@ -2502,7 +2518,7 @@ namespace INMOST ...@@ -2502,7 +2518,7 @@ namespace INMOST
free(chunks[q]); free(chunks[q]);
chunks[q] = NULL; chunks[q] = NULL;
} }
free(chunks); free((void *)chunks);
chunks = NULL; chunks = NULL;
m_size = 0; m_size = 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment