"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/common/classes/alloc.cpp" between
Firebird-3.0.2.32703-0.tar.bz2 and Firebird-3.0.4.33054-0.tar.bz2

About: Firebird is a relational database offering many ANSI SQL standard features.

alloc.cpp  (Firebird-3.0.2.32703-0.tar.bz2):alloc.cpp  (Firebird-3.0.4.33054-0.tar.bz2)
skipping to change at line 85 skipping to change at line 85
static void* lastBlock; static void* lastBlock;
static void* stopAddress = (void*) 0x2254938; static void* stopAddress = (void*) 0x2254938;
***/ ***/
#undef MEM_DEBUG #undef MEM_DEBUG
#if defined(DEBUG_GDS_ALLOC) && !defined(USE_VALGRIND) #if defined(DEBUG_GDS_ALLOC) && !defined(USE_VALGRIND)
#define MEM_DEBUG #define MEM_DEBUG
#endif #endif
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
static const int GUARD_BYTES = Firebird::ALLOC_ALIGNMENT; // * 2048; static const int GUARD_BYTES = ALLOC_ALIGNMENT; // * 2048;
static const UCHAR INIT_BYTE = 0xCC; static const UCHAR INIT_BYTE = 0xCC;
static const UCHAR GUARD_BYTE = 0xDD; static const UCHAR GUARD_BYTE = 0xDD;
static const UCHAR DEL_BYTE = 0xEE; static const UCHAR DEL_BYTE = 0xEE;
#else #else
static const int GUARD_BYTES = 0; static const int GUARD_BYTES = 0;
#endif #endif
template <typename T> template <typename T>
T absVal(T n) throw () T absVal(T n) throw ()
{ {
skipping to change at line 122 skipping to change at line 122
void* memory; // Extent pointer void* memory; // Extent pointer
size_t size; // Size of extent size_t size; // Size of extent
int handle; // Valgrind handle of protected extent block int handle; // Valgrind handle of protected extent block
}; };
DelayedExtent delayedExtents[DELAYED_EXTENT_COUNT]; DelayedExtent delayedExtents[DELAYED_EXTENT_COUNT];
size_t delayedExtentCount = 0; size_t delayedExtentCount = 0;
size_t delayedExtentsPos = 0; size_t delayedExtentsPos = 0;
#endif #endif
// Uncomment to validate pool on every alloc\release operation.
// Could slowdown pool significantly !
//#define VALIDATE_POOL
// We cache this amount of extents to avoid memory mapping overhead // We cache this amount of extents to avoid memory mapping overhead
const int MAP_CACHE_SIZE = 16; // == 1 MB const int MAP_CACHE_SIZE = 16; // == 1 MB
const size_t DEFAULT_ALLOCATION = 65536; const size_t DEFAULT_ALLOCATION = 65536;
Firebird::Vector<void*, MAP_CACHE_SIZE> extents_cache; Firebird::Vector<void*, MAP_CACHE_SIZE> extents_cache;
#ifndef WIN_NT
struct FailedBlock
{
size_t blockSize;
FailedBlock* next;
FailedBlock** prev;
};
FailedBlock* failedList = NULL;
#endif
void corrupt(const char* text) throw () void corrupt(const char* text) throw ()
{ {
#ifdef DEV_BUILD #ifdef DEV_BUILD
fprintf(stderr, "%s\n", text); fprintf(stderr, "%s\n", text);
abort(); abort();
#endif #endif
} }
} // anonymous namespace } // anonymous namespace
skipping to change at line 193 skipping to change at line 208
template <class T> template <class T>
void validate(T* e) void validate(T* e)
{ {
if (e->next && e->next->prev != &(e->next)) if (e->next && e->next->prev != &(e->next))
fatal_exception::raise("bad back link in SemiDoubleLink") ; fatal_exception::raise("bad back link in SemiDoubleLink") ;
} }
} }
#ifdef USE_VALGRIND #ifdef USE_VALGRIND
// Size of Valgrind red zone applied before and after memory block allocated for user // Size of Valgrind red zone applied before and after memory block allocated for user
#define VALGRIND_REDZONE 8 #define VALGRIND_REDZONE MEM_ALIGN
#undef MEM_DEBUG // valgrind works instead #undef MEM_DEBUG // valgrind works instead
#else #else
#define VALGRIND_REDZONE 0 #define VALGRIND_REDZONE 0
#endif #endif
typedef SLONG INT32; typedef SLONG INT32;
class MemBlock; class MemBlock;
class MemMediumHunk; class MemMediumHunk;
skipping to change at line 228 skipping to change at line 243
MemBlock* next; MemBlock* next;
}; };
private: private:
size_t hdrLength; size_t hdrLength;
public: public:
#ifdef DEBUG_GDS_ALLOC #ifdef DEBUG_GDS_ALLOC
INT32 lineNumber; INT32 lineNumber;
const char *fileName; const char *fileName;
#elif (SIZEOF_VOID_P == 4) && (ALLOC_ALIGNMENT == 16)
FB_UINT64 dummyAlign;
#endif #endif
#if defined(USE_VALGRIND) && (VALGRIND_REDZONE != 0) #if defined(USE_VALGRIND) && (VALGRIND_REDZONE != 0)
char mbk_valgrind_redzone[VALGRIND_REDZONE]; char mbk_valgrind_redzone[VALGRIND_REDZONE];
#endif #endif
MemHeader(size_t size) MemHeader(size_t size)
: pool(NULL), hdrLength(size) : pool(NULL), hdrLength(size)
{ {
fb_assert(size < MAX_USHORT); fb_assert(size < MAX_USHORT);
fb_assert(!(size & MEM_MASK)); fb_assert(!(size & MEM_MASK));
skipping to change at line 514 skipping to change at line 531
return MEM_ALIGN(sizeof(MemMediumHunk)); return MEM_ALIGN(sizeof(MemMediumHunk));
} }
}; };
class MemBigHunk class MemBigHunk
{ {
public: public:
MemBigHunk* next; MemBigHunk* next;
MemBigHunk** prev; MemBigHunk** prev;
const size_t length; const size_t length;
MemBlock block; MemBlock* block;
MemBigHunk(MemBigHunk** top, size_t l) MemBigHunk(MemBigHunk** top, size_t l)
: next(NULL), prev(NULL), length(l), block(MemBlock::HUGE_BLOCK, : next(NULL), prev(NULL), length(l),
length - hdrSize()) block(new(((UCHAR*) this) + hdrSize()) MemBlock(MemBlock::HUGE_
BLOCK, length - hdrSize()))
{ {
SemiDoubleLink::push(top, this); SemiDoubleLink::push(top, this);
} }
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
void print_contents(FILE* file, MemPool* pool, bool used_only, void print_contents(FILE* file, MemPool* pool, bool used_only,
const char* filter_path, const size_t filter_len) throw() const char* filter_path, const size_t filter_len) throw()
{ {
fprintf(file, "Big hunk %p: memory=%p length=%" SIZEFORMAT "\n", fprintf(file, "Big hunk %p: memory=%p length=%" SIZEFORMAT "\n",
this, &block, length); this, block, length);
block.print_contents(true, file, used_only, filter_path, filter_l block->print_contents(true, file, used_only, filter_path, filter_
en); len);
if (next) if (next)
next->print_contents(file, pool, used_only, filter_path, filter_len); next->print_contents(file, pool, used_only, filter_path, filter_len);
} }
#endif #endif
static size_t hdrSize() static size_t hdrSize()
{ {
return offsetof(MemBigHunk, block); return MEM_ALIGN(sizeof(MemBigHunk));
} }
void validate() void validate()
{ {
SemiDoubleLink::validate(this); SemiDoubleLink::validate(this);
block.assertBig(); block->assertBig();
fb_assert(block.getSize() + hdrSize() == length); fb_assert(block->getSize() + hdrSize() == length);
} }
}; };
enum GetSlotFor { SLOT_ALLOC, SLOT_FREE }; enum GetSlotFor { SLOT_ALLOC, SLOT_FREE };
#if ALLOC_ALIGNMENT == 8
const unsigned char lowSlots[] = const unsigned char lowSlots[] =
{ {
0, // 24 0, // 24
1, // 32 1, // 32
2, // 40 2, // 40
3, // 48 3, // 48
4, // 56 4, // 56
5, // 64 5, // 64
6, // 72 6, // 72
7, // 80 7, // 80
skipping to change at line 712 skipping to change at line 731
472, // 21 472, // 21
528, // 22 528, // 22
592, // 23 592, // 23
664, // 24 664, // 24
744, // 25 744, // 25
832, // 26 832, // 26
928, // 27 928, // 27
1024, // 28 1024, // 28
}; };
const int SLOT_SHIFT = 3;
#elif ALLOC_ALIGNMENT == 16
const unsigned char lowSlots[] =
{
0, // 32
1, // 48
2, // 64
3, // 80
4, // 96
5, // 112
6, // 128
7, // 144
8, // 160
9, // 176
9, // 192
10, // 208
10, // 224
11, // 240
11, // 256
12, // 272
12, // 288
13, // 304
13, // 320
14, // 336
14, // 352
14, // 368
15, // 384
15, // 400
15, // 416
16, // 432
16, // 448
16, // 464
17, // 480
17, // 496
17, // 512
17, // 528
18, // 544
18, // 560
18, // 576
18, // 592
19, // 608
19, // 624
19, // 640
19, // 656
19, // 672
20, // 688
20, // 704
20, // 720
20, // 736
20, // 752
21, // 768
21, // 784
21, // 800
21, // 816
21, // 832
21, // 848
22, // 864
22, // 880
22, // 896
22, // 912
22, // 928
22, // 944
23, // 960
23, // 976
23, // 992
23, // 1008
23, // 1024
};
const unsigned short lowLimits[] =
{
32, // 0
48, // 1
64, // 2
80, // 3
96, // 4
112, // 5
128, // 6
144, // 7
160, // 8
192, // 9
224, // 10
256, // 11
288, // 12
320, // 13
368, // 14
416, // 15
464, // 16
528, // 17
592, // 18
672, // 19
752, // 20
848, // 21
944, // 22
1024, // 23
};
const int SLOT_SHIFT = 4;
#endif
const size_t TINY_SLOTS = FB_NELEM(lowLimits); const size_t TINY_SLOTS = FB_NELEM(lowLimits);
const unsigned short* TINY_BLOCK_LIMIT = &lowLimits[TINY_SLOTS - 1]; const unsigned short* TINY_BLOCK_LIMIT = &lowLimits[TINY_SLOTS - 1];
// Access to slots for small (<= 1Kb) blocks // Access to slots for small (<= 1Kb) blocks
class LowLimits class LowLimits
{ {
public: public:
#if ALLOC_ALIGNMENT == 8
static const unsigned TOTAL_ELEMENTS = 29; // TINY_SLOTS static const unsigned TOTAL_ELEMENTS = 29; // TINY_SLOTS
#elif ALLOC_ALIGNMENT == 16
static const unsigned TOTAL_ELEMENTS = 24; // TINY_SLOTS
#endif
static const unsigned TOP_LIMIT = 1024; // TINY_BLOCK_LIM IT static const unsigned TOP_LIMIT = 1024; // TINY_BLOCK_LIM IT
static unsigned getSlot(size_t size, GetSlotFor mode) static unsigned getSlot(size_t size, GetSlotFor mode)
{ {
// add 2 asserts as long as we have not found better way to decla re consts // add 2 asserts as long as we have not found better way to decla re consts
fb_assert(TOTAL_ELEMENTS == TINY_SLOTS); fb_assert(TOTAL_ELEMENTS == TINY_SLOTS);
fb_assert(TOP_LIMIT == *TINY_BLOCK_LIMIT); fb_assert(TOP_LIMIT == *TINY_BLOCK_LIMIT);
const size_t LOW_LIMIT = lowLimits[0]; const size_t LOW_LIMIT = lowLimits[0];
fb_assert(size <= TOP_LIMIT); fb_assert(size <= TOP_LIMIT);
if (size < LOW_LIMIT) if (size < LOW_LIMIT)
size = LOW_LIMIT; size = LOW_LIMIT;
fb_assert(MEM_ALIGN(size) == size); fb_assert(MEM_ALIGN(size) == size);
unsigned slot = lowSlots[(size - LOW_LIMIT) >> 3]; unsigned slot = lowSlots[(size - LOW_LIMIT) >> SLOT_SHIFT];
fb_assert(size <= lowLimits[slot]); fb_assert(size <= lowLimits[slot]);
if (lowLimits[slot] > size && mode == SLOT_FREE) if (lowLimits[slot] > size && mode == SLOT_FREE)
{ {
if (!slot) if (!slot)
return ~0; return ~0;
--slot; --slot;
} }
return slot; return slot;
} }
skipping to change at line 1516 skipping to change at line 1639
public: public:
static MemPool* defaultMemPool; static MemPool* defaultMemPool;
MemPool(); MemPool();
MemPool(MemPool& parent, MemoryStats& stats); MemPool(MemPool& parent, MemoryStats& stats);
virtual ~MemPool(void); virtual ~MemPool(void);
private: private:
static const size_t minAllocation = 65536; static const size_t minAllocation = 65536;
static const size_t roundingSize = 8; static const size_t roundingSize = ALLOC_ALIGNMENT;
FreeObjects<LinkedList, LowLimits> smallObjects; FreeObjects<LinkedList, LowLimits> smallObjects;
Vector<MemBlock*, 16> parentRedirected; Vector<MemBlock*, 16> parentRedirected;
FreeObjects<DoubleLinkedList, MediumLimits> mediumObjects; FreeObjects<DoubleLinkedList, MediumLimits> mediumObjects;
MemBigHunk* bigHunks; MemBigHunk* bigHunks;
Mutex mutex; Mutex mutex;
int blocksAllocated; int blocksAllocated;
int blocksActive; int blocksActive;
bool pool_destroying, parent_redirect; bool pool_destroying, parent_redirect;
// Statistics group for the pool // Statistics group for the pool
MemoryStats* stats; MemoryStats* stats;
// Parent pool if present // Parent pool if present
MemPool* parent; MemPool* parent;
// Memory used // Memory used
AtomicCounter used_memory, mapped_memory; AtomicCounter used_memory, mapped_memory;
private: private:
#ifdef VALIDATE_POOL
class Validator
{
public:
Validator(MemPool* p) :
m_pool(p)
{
m_pool->validate();
}
~Validator()
{
m_pool->validate();
}
private:
MemPool* m_pool;
};
#else
class Validator
{
public:
Validator(MemPool*) {}
};
#endif // VALIDATE_POOL
MemBlock* alloc(size_t from, size_t& length, bool flagRedirect) throw (OO M_EXCEPTION); MemBlock* alloc(size_t from, size_t& length, bool flagRedirect) throw (OO M_EXCEPTION);
void releaseBlock(MemBlock *block) throw (); void releaseBlock(MemBlock *block) throw ();
public: public:
void* allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION); void* allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION);
MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS) throw (OOM_EX CEPTION); MemBlock* allocate2(size_t from, size_t& size ALLOC_PARAMS) throw (OOM_EX CEPTION);
private: private:
virtual void memoryIsExhausted(void) throw (OOM_EXCEPTION); virtual void memoryIsExhausted(void) throw (OOM_EXCEPTION);
void* allocRaw(size_t length) throw (OOM_EXCEPTION); void* allocRaw(size_t length) throw (OOM_EXCEPTION);
skipping to change at line 1596 skipping to change at line 1745
return defaultMemPool; return defaultMemPool;
} }
static void cleanup() static void cleanup()
{ {
defaultMemPool->~MemPool(); defaultMemPool->~MemPool();
defaultMemPool = NULL; defaultMemPool = NULL;
while (extents_cache.getCount()) while (extents_cache.getCount())
releaseRaw(true, extents_cache.pop(), DEFAULT_ALLOCATION, false); releaseRaw(true, extents_cache.pop(), DEFAULT_ALLOCATION, false);
#ifndef WIN_NT
unsigned oldCount = 0;
for(;;)
{
unsigned newCount = 0;
FailedBlock* oldList = failedList;
if (oldList)
{
fb_assert(oldList->prev);
oldList->prev = &oldList;
failedList = NULL;
}
while (oldList)
{
++newCount;
FailedBlock* fb = oldList;
SemiDoubleLink::pop(oldList);
releaseRaw(true, fb, fb->blockSize, false);
}
if (newCount == oldCount)
break;
oldCount = newCount;
}
#endif // WIN_NT
} }
// Statistics // Statistics
void increment_usage(size_t size) throw () void increment_usage(size_t size) throw ()
{ {
stats->increment_usage(size); stats->increment_usage(size);
used_memory += size; used_memory += size;
} }
void decrement_usage(size_t size) throw () void decrement_usage(size_t size) throw ()
skipping to change at line 1800 skipping to change at line 1975
if (cache_mutex) if (cache_mutex)
{ {
cache_mutex->~Mutex(); cache_mutex->~Mutex();
cache_mutex = NULL; cache_mutex = NULL;
} }
} }
MemPool::MemPool() MemPool::MemPool()
: pool_destroying(false), parent_redirect(false), stats(MemoryPool::defau lt_stats_group), parent(NULL) : pool_destroying(false), parent_redirect(false), stats(MemoryPool::defau lt_stats_group), parent(NULL)
{ {
fb_assert(offsetof(MemBlock, body) == MEM_ALIGN(offsetof(MemBlock, body)) );
initialize(); initialize();
} }
MemPool::MemPool(MemPool& p, MemoryStats& s) MemPool::MemPool(MemPool& p, MemoryStats& s)
: pool_destroying(false), parent_redirect(true), stats(&s), parent(&p) : pool_destroying(false), parent_redirect(true), stats(&s), parent(&p)
{ {
initialize(); initialize();
} }
void MemPool::initialize() void MemPool::initialize()
skipping to change at line 1965 skipping to change at line 2141
void MemoryPool::setStatsGroup(MemoryStats& newStats) throw () void MemoryPool::setStatsGroup(MemoryStats& newStats) throw ()
{ {
pool->setStatsGroup(newStats); pool->setStatsGroup(newStats);
} }
MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) throw ( OOM_EXCEPTION) MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) throw ( OOM_EXCEPTION)
{ {
MutexEnsureUnlock guard(mutex, "MemPool::alloc"); MutexEnsureUnlock guard(mutex, "MemPool::alloc");
guard.enter(); guard.enter();
Validator vld(this);
// If this is a small block, look for it there // If this is a small block, look for it there
MemBlock* block = smallObjects.allocateBlock(this, from, length); MemBlock* block = smallObjects.allocateBlock(this, from, length);
if (block) if (block)
return block; return block;
if (parent_redirect && flagRedirect && length < PARENT_REDIRECT_THRESHOLD ) if (parent_redirect && flagRedirect && length < PARENT_REDIRECT_THRESHOLD )
{ {
guard.leave(); guard.leave();
block = parent->alloc(from, length, false); block = parent->alloc(from, length, false);
skipping to change at line 2012 skipping to change at line 2190
/* /*
* OK, we've got a "big block" on hands. To maximize confusing, the ind icated * OK, we've got a "big block" on hands. To maximize confusing, the ind icated
* "length" of a free big block is the length of MemHeader plus body*/ * "length" of a free big block is the length of MemHeader plus body*/
fb_assert(from == 0); fb_assert(from == 0);
size_t hunkLength = MemBigHunk::hdrSize() + offsetof(MemBlock, body) + le ngth; size_t hunkLength = MemBigHunk::hdrSize() + offsetof(MemBlock, body) + le ngth;
// Allocate the new hunk // Allocate the new hunk
MemBigHunk* hunk = new(allocRaw(hunkLength)) MemBigHunk(&bigHunks, hunkLe ngth); MemBigHunk* hunk = new(allocRaw(hunkLength)) MemBigHunk(&bigHunks, hunkLe ngth);
return &hunk->block; return hunk->block;
} }
MemBlock* MemPool::allocate2(size_t from, size_t& size MemBlock* MemPool::allocate2(size_t from, size_t& size
#ifdef DEBUG_GDS_ALLOC #ifdef DEBUG_GDS_ALLOC
, const char* fileName, int line , const char* fileName, int line
#endif #endif
) throw (OOM_EXCEPTION) ) throw (OOM_EXCEPTION)
{ {
size_t length = from ? size : ROUNDUP(size + VALGRIND_REDZONE, roundingSi ze) + GUARD_BYTES; size_t length = from ? size : ROUNDUP(size + VALGRIND_REDZONE, roundingSi ze) + GUARD_BYTES;
MemBlock* memory = alloc(from, length, true); MemBlock* memory = alloc(from, length, true);
skipping to change at line 2044 skipping to change at line 2222
#endif #endif
#ifdef MEM_DEBUG #ifdef MEM_DEBUG
memset(&memory->body, INIT_BYTE, size); memset(&memory->body, INIT_BYTE, size);
memset(&memory->body + size, GUARD_BYTE, memory->getSize() - offsetof(Mem Block,body) - size); memset(&memory->body + size, GUARD_BYTE, memory->getSize() - offsetof(Mem Block,body) - size);
#endif #endif
++blocksAllocated; ++blocksAllocated;
++blocksActive; ++blocksActive;
fb_assert((U_IPTR)(&memory->body) % ALLOC_ALIGNMENT == 0);
return memory; return memory;
} }
void* MemPool::allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION) void* MemPool::allocate(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
{ {
MemBlock* memory = allocate2(0, size ALLOC_PASS_ARGS); MemBlock* memory = allocate2(0, size ALLOC_PASS_ARGS);
increment_usage(memory->getSize()); increment_usage(memory->getSize());
return &memory->body; return &memory->body;
skipping to change at line 2137 skipping to change at line 2316
corrupt("guard bytes overwritten"); corrupt("guard bytes overwritten");
} }
#endif #endif
--blocksActive; --blocksActive;
const size_t length = block->getSize(); const size_t length = block->getSize();
MutexEnsureUnlock guard(mutex, "MemPool::release"); MutexEnsureUnlock guard(mutex, "MemPool::release");
guard.enter(); guard.enter();
Validator vld(this);
// If length is less than threshold, this is a small block // If length is less than threshold, this is a small block
if (smallObjects.deallocateBlock(block)) if (smallObjects.deallocateBlock(block))
return; return;
// Redirected to parent block? // Redirected to parent block?
if (block->redirected()) if (block->redirected())
{ {
FB_SIZE_T pos; FB_SIZE_T pos;
if (parentRedirected.find(block, pos)) if (parentRedirected.find(block, pos))
parentRedirected.remove(pos); parentRedirected.remove(pos);
skipping to change at line 2197 skipping to change at line 2378
} }
} }
#endif #endif
size = FB_ALIGN(size, get_map_page_size()); size = FB_ALIGN(size, get_map_page_size());
#ifdef WIN_NT #ifdef WIN_NT
void* result = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); void* result = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
if (!result) if (!result)
{
#else // WIN_NT #else // WIN_NT
void* result = NULL;
if (failedList)
{
MutexLockGuard guard(*cache_mutex, "MemPool::allocRaw");
for (FailedBlock* fb = failedList; fb; fb = fb->next)
{
if (fb->blockSize == size)
{
result = fb;
SemiDoubleLink::pop(fb);
break;
}
}
}
if (!result)
{
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS) #if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON #define MAP_ANONYMOUS MAP_ANON
#endif #endif
#ifdef MAP_ANONYMOUS #ifdef MAP_ANONYMOUS
void* result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP _ANONYMOUS, -1, 0); result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | M AP_ANONYMOUS, -1, 0);
#else // MAP_ANONYMOUS #else // MAP_ANONYMOUS
if (dev_zero_fd < 0) if (dev_zero_fd < 0)
dev_zero_fd = os_utils::open("/dev/zero", O_RDWR); dev_zero_fd = os_utils::open("/dev/zero", O_RDWR);
void* result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_ result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, de
zero_fd, 0); v_zero_fd, 0);
#endif // MAP_ANONYMOUS #endif // MAP_ANONYMOUS
if (result == MAP_FAILED) if (result == MAP_FAILED)
#endif // WIN_NT #endif // WIN_NT
{ {
// failure happens! // failure happens!
memoryIsExhausted(); memoryIsExhausted();
return NULL; return NULL;
}
} }
#ifdef USE_VALGRIND #ifdef USE_VALGRIND
// Let Valgrind forget that block was zero-initialized // Let Valgrind forget that block was zero-initialized
VALGRIND_DISCARD(VALGRIND_MAKE_WRITABLE(result, size)); VALGRIND_DISCARD(VALGRIND_MAKE_WRITABLE(result, size));
#endif #endif
increment_mapping(size); increment_mapping(size);
return result; return result;
} }
skipping to change at line 2321 skipping to change at line 2522
else else
{ {
// Let Valgrind forget about unmapped block // Let Valgrind forget about unmapped block
VALGRIND_DISCARD(handle); VALGRIND_DISCARD(handle);
} }
#endif #endif
size = FB_ALIGN(size, get_map_page_size()); size = FB_ALIGN(size, get_map_page_size());
#ifdef WIN_NT #ifdef WIN_NT
if (!VirtualFree(block, 0, MEM_RELEASE)) if (!VirtualFree(block, 0, MEM_RELEASE))
{
#else // WIN_NT #else // WIN_NT
#if (defined SOLARIS) && (defined HAVE_CADDR_T) #if (defined SOLARIS) && (defined HAVE_CADDR_T)
if (munmap((caddr_t) block, size)) int rc = munmap((caddr_t) block, size);
#else #else
if (munmap(block, size)) int rc = munmap(block, size);
#endif #endif
if (rc)
{
if (errno == ENOMEM)
{
FailedBlock* failed = (FailedBlock*) block;
failed->blockSize = size;
MutexLockGuard guard(*cache_mutex, "MemPool::releaseRaw")
;
SemiDoubleLink::push(&failedList, failed);
return;
}
#endif // WIN_NT #endif // WIN_NT
corrupt("OS memory deallocation error"); corrupt("OS memory deallocation error");
}
} }
void MemPool::globalFree(void* block) throw () void MemPool::globalFree(void* block) throw ()
{ {
deallocate(block); deallocate(block);
} }
void* MemoryPool::calloc(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION) void* MemoryPool::calloc(size_t size ALLOC_PARAMS) throw (OOM_EXCEPTION)
{ {
void* block = allocate(size ALLOC_PASS_ARGS); void* block = allocate(size ALLOC_PASS_ARGS);
 End of changes. 36 change blocks. 
26 lines changed or deleted 244 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)