mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43:02 +01:00
New C++ memory pool
This commit is contained in:
parent
73147b110b
commit
6b0113844e
224
src/common/memory/allocators.cpp
Normal file
224
src/common/memory/allocators.cpp
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* PROGRAM: Client/Server Common Code
|
||||||
|
* MODULE: memory_pool.cpp
|
||||||
|
* DESCRIPTION: Memory Pool Manager
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Interbase Public
|
||||||
|
* License Version 1.0 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy
|
||||||
|
* of the License at http://www.Inprise.com/IPL.html
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an
|
||||||
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||||
|
* or implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code was created by Inprise Corporation
|
||||||
|
* and its predecessors. Portions created by Inprise Corporation are
|
||||||
|
* Copyright (C) Inprise Corporation.
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
|
* Contributor(s): ______________________________________.
|
||||||
|
*
|
||||||
|
* 2001.11.29 John Bellardo: Reworked all routines to create the MemoryPool
|
||||||
|
* class as part of the C++ conversion. Additionally the class now handles
|
||||||
|
* generic memory allocations instead of typed-only allocations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../../common/memory/allocators.h"
|
||||||
|
#include "../../include/fb_exception.h"
|
||||||
|
#include "../../jrd/gds.h"
|
||||||
|
#include "../../jrd/gdsassert.h"
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
class InitMemoryPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InitMemoryPool() { loadPool(); }
|
||||||
|
static void loadPool()
|
||||||
|
{
|
||||||
|
if (!FB_MemoryPool)
|
||||||
|
FB_MemoryPool = new BootstrapMemoryPool;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
class BootstrapMemoryPool : public MemoryPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BootstrapMemoryPool() : MemoryPool(102400) {}
|
||||||
|
void* operator new(size_t s)
|
||||||
|
{
|
||||||
|
void* mem = malloc(s);
|
||||||
|
if (!mem) {
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
void operator delete(void *mem) { free(mem); }
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
MemoryPool *FB_MemoryPool = 0;
|
||||||
|
static InitMemoryPool poolLoader;
|
||||||
|
static int badNewCount = 0;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
#ifdef DEBUG_GDS_ALLOC
|
||||||
|
|
||||||
|
void* API_ROUTINE gds__alloc_debug(SLONG size_request,
|
||||||
|
TEXT* filename,
|
||||||
|
ULONG lineno)
|
||||||
|
#else
|
||||||
|
|
||||||
|
void* API_ROUTINE gds__alloc(SLONG size_request)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
poolLoader.loadPool();
|
||||||
|
return FB_MemoryPool->allocate(size_request);
|
||||||
|
} catch(...) {}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ULONG API_ROUTINE gds__free(void* blk)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
poolLoader.loadPool();
|
||||||
|
return FB_MemoryPool->deallocate(blk);
|
||||||
|
} catch(...) {}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
|
||||||
|
// Our implementations for the global operators new/delete.
|
||||||
|
|
||||||
|
/** operator new[] implementation to trap all calls to the default operator
|
||||||
|
new. You MUST allocate all memory from a pool. Since there is no way
|
||||||
|
to specifiy a pool to the default operator new it just throws an assert.
|
||||||
|
If you are using std::* classes you need to use allocators.
|
||||||
|
**/
|
||||||
|
void* operator new(size_t s)
|
||||||
|
{
|
||||||
|
// We MUST have a pool to allocate from, otherwise there is
|
||||||
|
// an error.
|
||||||
|
// TMN: No it's not. The Dinkum C++ library as shipped with
|
||||||
|
// MSVC (5 & 6) allocates a few small objects from the global heap.
|
||||||
|
#if defined(DEV_BUILD)
|
||||||
|
if (++badNewCount > 1)
|
||||||
|
{
|
||||||
|
printf("You MUST allocate all memory from a pool. Don't use the default global new().\n");
|
||||||
|
#if !defined(_MSC_VER)
|
||||||
|
throw std::bad_alloc();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif // DEV_BUILD
|
||||||
|
poolLoader.loadPool();
|
||||||
|
return FB_MemoryPool->allocate(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** operator new[] implementation to trap all calls to the default operator
|
||||||
|
new. You MUST allocate all memory from a pool. Since there is no way
|
||||||
|
to specifiy a pool to the default operator new it just throws an assert.
|
||||||
|
If you are using std::* classes you need to use allocators.
|
||||||
|
**/
|
||||||
|
void* operator new[](size_t s)
|
||||||
|
{
|
||||||
|
// We MUST have a pool to allocate from, otherwise there is
|
||||||
|
// an error
|
||||||
|
#ifdef DEV_BUILD
|
||||||
|
if (++badNewCount > 1)
|
||||||
|
{
|
||||||
|
printf("You MUST allocate all memory from a pool. Don't use the default global new[]().\n");
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
poolLoader.loadPool();
|
||||||
|
return FB_MemoryPool->allocate(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generic operator new to allocate memory from a given pool. Works with
|
||||||
|
all objects that don't define their own operator new.
|
||||||
|
**/
|
||||||
|
void* operator new(size_t s, MemoryPool& p)
|
||||||
|
{
|
||||||
|
return p.allocate(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** operator delete to handle exceptions thrown while contructing object with
|
||||||
|
our custom operator new.
|
||||||
|
**/
|
||||||
|
void operator delete(void* mem, MemoryPool& p)
|
||||||
|
{
|
||||||
|
if (mem) {
|
||||||
|
MemoryPool::deallocate(mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** standard operator delete called to free object without their own
|
||||||
|
implementation of operator delete.
|
||||||
|
**/
|
||||||
|
void operator delete(void* mem)
|
||||||
|
{
|
||||||
|
if (mem) {
|
||||||
|
MemoryPool::deallocate(mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// no implmentation of these two functions in dev build to force link
|
||||||
|
// errors if they are used.
|
||||||
|
#ifndef DEV_BUILD
|
||||||
|
/** This operator new traps the standard libraries placement new. It simply
|
||||||
|
pops an assert to prevent inadvertant use. Use the reference versions
|
||||||
|
of operator new() instead.
|
||||||
|
**/
|
||||||
|
void* operator new[](size_t s, MemoryPool* p)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** This operator new traps the standard libraries placement new. It simply
|
||||||
|
pops an assert to prevent inadvertant use. Use the reference versions
|
||||||
|
of operator new() instead.
|
||||||
|
**/
|
||||||
|
void* operator new(size_t s, MemoryPool* p)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Generic operator new to allocate memory from a given pool. Works with
|
||||||
|
all objects that don't define their own operator new.
|
||||||
|
**/
|
||||||
|
void* operator new[](size_t s, MemoryPool& p)
|
||||||
|
{
|
||||||
|
return p.allocate(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** operator delete[] to handle exceptions thrown while contructing object with
|
||||||
|
our custom operator new.
|
||||||
|
**/
|
||||||
|
void operator delete[](void* mem, MemoryPool& p)
|
||||||
|
{
|
||||||
|
if (mem) {
|
||||||
|
MemoryPool::deallocate(mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** standard operator delete[] called to free object without their own
|
||||||
|
implementation of operator delete.
|
||||||
|
**/
|
||||||
|
void operator delete[](void* mem)
|
||||||
|
{
|
||||||
|
if (mem) {
|
||||||
|
MemoryPool::deallocate(mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
132
src/common/memory/allocators.h
Normal file
132
src/common/memory/allocators.h
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* PROGRAM: Client/Server Common Code
|
||||||
|
* MODULE: memory_pool.h
|
||||||
|
* DESCRIPTION: Memory Pool Manager
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Interbase Public
|
||||||
|
* License Version 1.0 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy
|
||||||
|
* of the License at http://www.Inprise.com/IPL.html
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an
|
||||||
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||||
|
* or implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code was created by Inprise Corporation
|
||||||
|
* and its predecessors. Portions created by Inprise Corporation are
|
||||||
|
* Copyright (C) Inprise Corporation.
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
|
* Contributor(s): ______________________________________.
|
||||||
|
* 2001.11.29 John Bellardo: Reworked all routines to create the MemoryPool
|
||||||
|
* class as part of the C++ conversion. Additionally the class now handles
|
||||||
|
* generic memory allocations instead of typed-only allocations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_ALLOCATORS_H
|
||||||
|
#define COMMON_ALLOCATORS_H
|
||||||
|
|
||||||
|
#include "../common/memory/memory_pool.h"
|
||||||
|
#include "../jrd/gds_proto.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#ifdef DEBUG_GDS_ALLOC
|
||||||
|
void* API_ROUTINE gds__alloc_debug(SLONG size_request,
|
||||||
|
TEXT* filename,
|
||||||
|
ULONG lineno);
|
||||||
|
#else
|
||||||
|
void* API_ROUTINE gds__alloc(SLONG size_request);
|
||||||
|
#endif
|
||||||
|
extern ULONG API_ROUTINE gds__free(void* blk);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MemoryPool *FB_MemoryPool;
|
||||||
|
|
||||||
|
void* operator new(size_t);
|
||||||
|
void* operator new[](size_t);
|
||||||
|
|
||||||
|
void* operator new(size_t, MemoryPool&);
|
||||||
|
void operator delete(void* mem, MemoryPool&);
|
||||||
|
void* operator new[](size_t s, MemoryPool&);
|
||||||
|
void operator delete[](void* mem, MemoryPool&);
|
||||||
|
|
||||||
|
void* operator new(size_t, MemoryPool*);
|
||||||
|
void* operator new[](size_t s, MemoryPool*);
|
||||||
|
|
||||||
|
void operator delete(void* mem);
|
||||||
|
void operator delete[](void* mem);
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is the allocator template provided to be used with the STL.
|
||||||
|
Since the STL is the client of this class look to its documentation
|
||||||
|
to determine what the individual functions and typedefs do.
|
||||||
|
|
||||||
|
In order to use the allocator class you need to instansiate the
|
||||||
|
C++ container template with the allocator. For example if you
|
||||||
|
want to use a std::vector<int> the declaration would be:
|
||||||
|
|
||||||
|
std::vector<int, MemoryPool::allocator<int> >
|
||||||
|
|
||||||
|
The allocator, by default, allocates all memory from the process
|
||||||
|
wide pool FB_MemoryPool. Typically this is NOT the behavior you
|
||||||
|
want. Selection of the correct pool to allocate your memory from is
|
||||||
|
important. If you select a pool to far down in (a statement pool,
|
||||||
|
for example) you memory may be freed before you are done with it.
|
||||||
|
On the other hand if you always use the global pool you will
|
||||||
|
either leak memory or have to make sure you always delete the objects
|
||||||
|
you create.
|
||||||
|
|
||||||
|
If you decide to allocate the memory from a pool other than the global
|
||||||
|
pool you need to pass an allocator object to the constructor for
|
||||||
|
the STL object. For example:
|
||||||
|
|
||||||
|
std::vector<int, MemoryPool::allocator<int> > vec(MemoryPool::allocator<int>(poolRef, type));
|
||||||
|
The type is an optional parameter that defaults to 0.
|
||||||
|
**/
|
||||||
|
namespace Firebird
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
class allocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef size_t size_type;
|
||||||
|
typedef ptrdiff_t difference_type;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef const T* const_pointer;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef const T& const_reference;
|
||||||
|
typedef T value_type;
|
||||||
|
|
||||||
|
allocator(MemoryPool& p, SSHORT t = 0) : pool(&p), type(t) {}
|
||||||
|
allocator(MemoryPool *p = FB_MemoryPool, SSHORT t = 0) : pool(p), type(t) {}
|
||||||
|
|
||||||
|
pointer allocate(size_type s, const void * = 0)
|
||||||
|
{ return (pointer) (pool ? pool->allocate(sizeof(T) * s) : gds__alloc(sizeof(T)*s)); }
|
||||||
|
void deallocate(pointer p, size_type s)
|
||||||
|
{ if (pool) MemoryPool::deallocate(p); else gds__free(p); }
|
||||||
|
void construct(pointer p, const T& v) { new(p) T(v); }
|
||||||
|
void destroy(pointer p) { p->~T(); }
|
||||||
|
|
||||||
|
size_type max_size() const { return (size_type)-1 / sizeof(T); }
|
||||||
|
|
||||||
|
pointer address(reference X) const {return &X; }
|
||||||
|
const_pointer address(const_reference X) const {return &X; }
|
||||||
|
|
||||||
|
template <class _Tp1> struct rebind {
|
||||||
|
typedef Firebird::allocator<_Tp1> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const allocator<T>& rhs)
|
||||||
|
{
|
||||||
|
return pool == rhs.pool && type == rhs.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemoryPool *pool;
|
||||||
|
SSHORT type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COMMON_ALLOCATORS_H
|
1667
src/common/memory/memory_pool.cpp
Normal file
1667
src/common/memory/memory_pool.cpp
Normal file
File diff suppressed because it is too large
Load Diff
129
src/common/memory/memory_pool.h
Normal file
129
src/common/memory/memory_pool.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* PROGRAM: Client/Server Common Code
|
||||||
|
* MODULE: memory_pool.h
|
||||||
|
* DESCRIPTION: Memory Pool Manager
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Interbase Public
|
||||||
|
* License Version 1.0 (the "License"); you may not use this file
|
||||||
|
* except in compliance with the License. You may obtain a copy
|
||||||
|
* of the License at http://www.Inprise.com/IPL.html
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an
|
||||||
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
||||||
|
* or implied. See the License for the specific language governing
|
||||||
|
* rights and limitations under the License.
|
||||||
|
*
|
||||||
|
* The Original Code was created by Inprise Corporation
|
||||||
|
* and its predecessors. Portions created by Inprise Corporation are
|
||||||
|
* Copyright (C) Inprise Corporation.
|
||||||
|
*
|
||||||
|
* All Rights Reserved.
|
||||||
|
* Contributor(s): ______________________________________.
|
||||||
|
* 2001.11.29 John Bellardo: Reworked all routines to create the MemoryPool
|
||||||
|
* class as part of the C++ conversion. Additionally the class now handles
|
||||||
|
* generic memory allocations instead of typed-only allocations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MEMORY_POOL_H
|
||||||
|
#define MEMORY_POOL_H
|
||||||
|
|
||||||
|
#include "../include/fb_types.h"
|
||||||
|
#include "../jrd/ib_stdio.h"
|
||||||
|
|
||||||
|
extern class MemoryPool *FB_MemoryPool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
For various reasons Firebird has chosen to do its own heap management.
|
||||||
|
The MemoryPool class is the result of that decision. Basically a memory
|
||||||
|
pool object is the same as a single heap. Objects can be allocated
|
||||||
|
out of the heap and returned to the heap. Just like all requests
|
||||||
|
for dynamic memory must reference a heap, all such requests in Firebird
|
||||||
|
must reference a memory pool.
|
||||||
|
|
||||||
|
Memory pools are implemented in such a way they never return their memory
|
||||||
|
back to the host operating system. Instead they keep track of that
|
||||||
|
memory internally and use it to satisify future allocation requests.
|
||||||
|
|
||||||
|
Every memory pool has no initial pool space. It grows dynamically as
|
||||||
|
more allocation requests are made. Every time the pool needs more space
|
||||||
|
it goes to the operating system and requests another chunk of memory.
|
||||||
|
That chunk is usually more than what is needed to satisify the pending
|
||||||
|
allocation request. The minimum requested size can vary from memory
|
||||||
|
pool to memory pool and is call the extend size.
|
||||||
|
|
||||||
|
The option also exists to have a pool contact another pool if it needs
|
||||||
|
more memory instead of going to the operating system. This allows the
|
||||||
|
creation of pool hierarchies.
|
||||||
|
|
||||||
|
All the memory in the pool can be freed at once which is a speed savings,
|
||||||
|
but at the current time the destructors for any objects in the pool
|
||||||
|
will NOT get called. So they need to be explicitly deleted BEFORE the
|
||||||
|
pool is released.
|
||||||
|
|
||||||
|
To make it easier to allocate memory from the memory pools a number
|
||||||
|
of implementations of the operator new are provided in the file
|
||||||
|
common/memory/allocators.h. Basically, to allocate memory from a pool
|
||||||
|
use the following code:
|
||||||
|
|
||||||
|
obj = new(poolReference) Obj;
|
||||||
|
|
||||||
|
If you use the STL you must also use allocators to ensure all the memory
|
||||||
|
allocated by the STL ends up in a heap. The template
|
||||||
|
MemoryPool::allocator<T> has been written to be used with the STL objects.
|
||||||
|
Sometimes the template types can get out of control when using allocators.
|
||||||
|
So there are some convience templates provided in the Firebird namespace
|
||||||
|
that mimic the std classes, but use Firebird allocators.
|
||||||
|
|
||||||
|
The details of how the memory is managed (not just how you get the memory
|
||||||
|
you need) can be found in the documentation for the FBMemoryPool class.
|
||||||
|
|
||||||
|
If any memory operation fail an exception is raised.
|
||||||
|
**/
|
||||||
|
class MemoryPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MemoryPool(size_t = 0, MemoryPool* = 0);
|
||||||
|
virtual ~MemoryPool();
|
||||||
|
|
||||||
|
/// Free all memory from the pool, but leave the pool in a state to
|
||||||
|
/// allocate more memory.
|
||||||
|
void release_pool(void);
|
||||||
|
|
||||||
|
/// Allocates at least the given number of bytes from the pool and
|
||||||
|
/// returns a pointer to the memory.
|
||||||
|
void* allocate(size_t, SSHORT = 0);
|
||||||
|
|
||||||
|
/// Deallocates memory that has been allocated from ANY MemoryPool.
|
||||||
|
static int deallocate(void*);
|
||||||
|
|
||||||
|
/// Allocate memory directly from the OS
|
||||||
|
static void* malloc_from_system(size_t);
|
||||||
|
/// Deallocate memory allocated directly from the OS
|
||||||
|
static SLONG free_from_system(void* mem);
|
||||||
|
|
||||||
|
/// Pool debugging calls
|
||||||
|
void print_contents(IB_FILE*, const char* (*)(int) = 0,
|
||||||
|
void (*)(int, void*, IB_FILE*, const char*) = 0);
|
||||||
|
/// Verify the structural integrity of the pool
|
||||||
|
bool verify_pool(bool = false);
|
||||||
|
|
||||||
|
/// Get the minimum extend size for the pool.
|
||||||
|
size_t extendSize();
|
||||||
|
/// Set the minimum extend size for the pool
|
||||||
|
void setExtendSize(size_t);
|
||||||
|
|
||||||
|
/// Returns the type associated with the allocated memory.
|
||||||
|
static SSHORT blk_type(const void* mem);
|
||||||
|
/// Returns the pool the memory was allocated from.
|
||||||
|
static MemoryPool* blk_pool(const void* mem);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class FBMemoryPool *pimpl;
|
||||||
|
class MemoryPool *parent;
|
||||||
|
size_t extend_inc;
|
||||||
|
|
||||||
|
void* allocate_int(size_t, SSHORT);
|
||||||
|
friend class FBMemoryPool;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // JRD_MEMORY_POOL_H
|
21
src/common/mp/AtomicCounter.h
Normal file
21
src/common/mp/AtomicCounter.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef ATOMIC_COUNTER_H
|
||||||
|
#define ATOMIC_COUNTER_H
|
||||||
|
|
||||||
|
class AtomicCounter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AtomicCounter(int);
|
||||||
|
~AtomicCounter();
|
||||||
|
|
||||||
|
operator int() const;
|
||||||
|
const AtomicCounter &operator +=(int);
|
||||||
|
const AtomicCounter &operator -=(int);
|
||||||
|
const AtomicCounter &operator ++(int);
|
||||||
|
const AtomicCounter &operator --(int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const AtomicCounter &operator =
|
||||||
|
int counter;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
0
src/common/mp/crit_section_guard.h
Normal file
0
src/common/mp/crit_section_guard.h
Normal file
0
src/common/mp/crit_section_lock.h
Normal file
0
src/common/mp/crit_section_lock.h
Normal file
0
src/common/mp/mutex.h
Normal file
0
src/common/mp/mutex.h
Normal file
0
src/common/mp/semaphore.h
Normal file
0
src/common/mp/semaphore.h
Normal file
0
src/common/mp/thread.h
Normal file
0
src/common/mp/thread.h
Normal file
Loading…
Reference in New Issue
Block a user