m_Value +=
delta;
184 #ifdef NCBI_NO_THREADS 201 #ifdef NCBI_WIN32_THREADS 202TlsSetValue(
key,
nullptr);
204pthread_setspecific(
key,
nullptr);
208 #ifdef NCBI_WIN32_THREADS 212TlsSetValue(
key,
nullptr);
227 # ifdef NCBI_WIN32_THREADS 233 # ifndef NCBI_WIN32_THREADS 234pthread_setspecific(
key, 0);
247 #ifdef NCBI_NO_THREADS 256 # ifdef NCBI_WIN32_THREADS 263 # ifdef NCBI_WIN32_THREADS 267pthread_setspecific(
key,
set);
292 if( it->first == ptr ) {
300s_LastNewPtr =
set.front().first;
311 if( s_LastNewPtr ) {
317s_LastNewType =
type;
324 void* last_ptr = s_LastNewPtr;
334 if( s_LastNewPtr != ptr ) {
356 #ifdef USE_SINGLE_ALLOC 357 #define SINGLE_ALLOC_THRESHOLD ( 2*1024) 358 #define SINGLE_ALLOC_POOL_SIZE (1024*1024) 362 static char* single_alloc_pool = 0;
363 static size_tsingle_alloc_pool_size = 0;
365 void* single_alloc(
size_t size)
367 if(
size> SINGLE_ALLOC_THRESHOLD ) {
368return ::operator
new(
size);
370sx_SingleAllocMutex.Lock();
371 size_tpool_size = single_alloc_pool_size;
373 if(
size> pool_size ) {
374pool_size = SINGLE_ALLOC_POOL_SIZE;
375pool = (
char*)
malloc(pool_size);
377sx_SingleAllocMutex.Unlock();
380single_alloc_pool = pool;
381single_alloc_pool_size = pool_size;
384pool = single_alloc_pool;
386single_alloc_pool = pool +
size;
387single_alloc_pool_size = pool_size -
size;
388sx_SingleAllocMutex.Unlock();
396 #if defined(_DEBUG) && !defined(NCBI_COMPILER_MSVC) 397 # define ALLOC_FILL_MODE_INIT CObject::eAllocFillPattern 398 # define ALLOC_FILL_MODE_DEFAULT CObject::eAllocFillPattern 400 # define ALLOC_FILL_MODE_INIT CObject::eAllocFillZero 401 # define ALLOC_FILL_MODE_DEFAULT CObject::eAllocFillNone 403 #if defined(NCBI_COMPILER_MSVC) 404 # define ALLOC_FILL_BYTE_PATTERN 0xcd 406 # define ALLOC_FILL_BYTE_PATTERN 0xaa 412 const char*
env= ::getenv(
"NCBI_MEMORY_FILL");
464memset(ptr, 0,
size);
472 void* CObject::operator
new(
size_t size)
477 #ifdef USE_SINGLE_ALLOC 478 void* ptr = single_alloc(
size);
483 void* ptr = ::operator
new(
size);
492s_heap_obj->push_front(ptr);
496 # if USE_COMPLEX_MASK 507 voidCObject::operator
delete(
void* ptr)
515magic =
static_cast<CObject*
>(ptr)->m_Counter;
531::operator
delete(ptr);
536 void* CObject::operator
new(
size_t size,
void* place)
545 voidCObject::operator
delete(
void*
_DEBUG_ARG(ptr),
void*
)
566 if( !memory_pool ) {
567 return operator new(
size);
569 void* ptr = memory_pool->Allocate(
size);
571 return operator new(
size);
577 # if USE_COMPLEX_MASK 594magic =
static_cast<CObject*
>(ptr)->m_Counter;
611memory_pool->Deallocate(ptr);
616 void* CObject::operator
new[](
size_t size)
618 # ifdef NCBI_OS_MSWIN 619 void* ptr = ::operator
new(
size);
621 void* ptr = ::operator
new[](
size);
628 voidCObject::operator
delete[](
void* ptr)
631::operator
delete(ptr);
633::operator
delete[](ptr);
639 # define ObjFatal Fatal 641 # define ObjFatal Critical 661 "Bad s_LastNewType="<<
type<<
662 " at "<<StackTrace);
684 boolinStack =
false;
686 const void* ptr =
dynamic_cast<const void*
>(
this);
689list<const void*>::iterator
i=
690find( s_heap_obj->begin(), s_heap_obj->end(), ptr);
691inStack = (
i== s_heap_obj->end());
693s_heap_obj->erase(
i);
697 # if USE_COMPLEX_MASK 698inStack = GetSecondCounter(
this)->m_Value != main_counter;
703 const char* stackObjectPtr = &stackObject;
704 const char* objectPtr =
reinterpret_cast<const char*
>(
this);
705 # if defined STACK_GROWS_UP 707(objectPtr < stackObjectPtr) &&
709 # elif defined STACK_GROWS_DOWN 711(objectPtr > stackObjectPtr) &&
760 "Referenced CObject may not be deleted"<<StackTrace);
766 "CObject is already deleted"<<StackTrace);
771 "CObject is corrupted"<<StackTrace);
790 "CObject::CheckReferenceOverflow: " 791 "CObject's reference counter overflow");
797 "CObject::CheckReferenceOverflow: " 798 "CObject is already deleted");
803 "CObject::CheckReferenceOverflow: " 804 "CObject is corrupted");
846 "CObject was referenced again"<<StackTrace);
851 "CObject is already deleted"<<StackTrace);
855 "CObject is corrupted"<<StackTrace);
873 "CObject::ReleaseReference: " 874 "CObject is already deleted");
878 "CObject::ReleaseReference: " 879 "CObject is corrupted");
892 "CObject::DoNotDeleteThisObject: " 893 "CObject is allocated in heap");
915 "CObject::DoNotDeleteThisObject: " 916 "CObject is already deleted");
920 "CObject::DoNotDeleteThisObject: " 921 "CObject is corrupted");
928 #ifndef USE_SINGLE_ALLOC 935 "CObject::DoDeleteThisObject: " 936 "CObject is not allocated in heap");
946 static const TCounteCheckBits = eStateBitsValid | eStateBitsHeapSignature;
947 if( (
count& eCheckBits) == eCheckBits ) {
948 if( !(
count& eStateBitsInHeap) ) {
958 "object was created without heap signature"<<StackTrace);
964 "CObject::DoDeleteThisObject: " 965 "CObject is already deleted");
969 "CObject::DoDeleteThisObject: " 970 "CObject is corrupted");
1007 if( TAbortOnNull::GetDefault() ) {
1022 if( TAbortOnNull::GetDefault() ) {
1027 string(
"Attempt to access NULL pointer: ")+
type.
name());
1033 #ifndef NCBI_OBJECT_LOCKER_INLINE 1052 unsignedtotal_locks = 0;
1056 "("<<it->first<<
","<<
m_Object<<
")" 1057 " @ "<< *it->second);
1059 unsignedtotal_unlocks = 0;
1063 "("<<it->first<<
","<<
m_Object<<
")" 1064 " @ "<< *it->second);
1066 if( total_locks ) {
1069 if( total_unlocks ) {
1121 m_Locks[object].Locked(locker,
object);
1145 object->AddReference();
1163 object->RemoveReference();
1170 ERR_POST(
Note<<
"UnlockRelease<"<<
typeid(*object).name()<<
">" 1171 "("<<
this<<
", "<<
object<<
")" 1172 " @ "<< StackTrace);
1175 object->ReleaseReference();
1233 "Type "<<
type.
name()<<
" must be derived from CObject");
1241 case eDeleted:
return "eDeleted";
1244 case eNoRef:
return "eNoRef";
1293: m_Ptr(
NULL), m_WeakPtr(ptr)
1338 "Type "<<
type.
name()<<
" must be derived from CWeakObject");
1346 #ifdef USE_DEBUG_NEW 1348 static bools_EnvFlag(
const char* env_var_name)
1350 const char*
value= getenv(env_var_name);
1358 unsignedseq_number;
1368 unsignedseq_number;
1372 static const size_tkAllocSizeBefore = 32;
1373 static const size_tkAllocSizeAfter = 32;
1375 static const charkAllocFillBeforeArray = 0xba;
1376 static const charkAllocFillBeforeOne = 0xbb;
1377 static const charkAllocFillInside = 0xdd;
1378 static const charkAllocFillAfter = 0xaa;
1379 static const charkAllocFillFree = 0xee;
1381 static const unsignedkAllocMagicHeader = 0x8b9b0b0b;
1382 static const unsignedkAllocMagicFooter = 0x9e8e0e0e;
1383 static const unsignedkFreedMagicHeader = 0x8b0bdead;
1384 static const unsignedkFreedMagicFooter = 0x9e0edead;
1387 staticNCBI_NS_NCBI::CAtomicCounter seq_number;
1388 static const size_tkLogSize = 64 * 1024;
1390 unsignedseq_number;
1404 staticSAllocLog alloc_log[kLogSize];
1407 static inlineSAllocHeader* get_header(
void* ptr)
1409 return(SAllocHeader*) ((
char*) ptr-kAllocSizeBefore);
1413 static inline void* get_guard_before(SAllocHeader* header)
1415 return(
char*) header +
sizeof(SAllocHeader);
1419 static inline size_tget_guard_before_size()
1421 returnkAllocSizeBefore -
sizeof(SAllocHeader);
1425 static inline size_tget_extra_size(
size_t size)
1427 return(-
size) & 7;
1431 static inline size_tget_guard_after_size(
size_t size)
1433 returnkAllocSizeAfter -
sizeof(SAllocFooter) + get_extra_size(
size);
1437 static inline void* get_ptr(SAllocHeader* header)
1439 return(
char*) header + kAllocSizeBefore;
1443 static inline void* get_guard_after(SAllocFooter* footer,
size_t size)
1445 return(
char*)footer-get_guard_after_size(
size);
1449 static inlineSAllocFooter* get_footer(SAllocHeader* header,
size_t size)
1451 return(SAllocFooter*)((
char*)get_ptr(header)+
size+get_guard_after_size(
size));
1455 static inline size_tget_total_size(
size_t size)
1457 return size+get_extra_size(
size) + (kAllocSizeBefore+kAllocSizeAfter);
1461 static inline size_tget_all_guards_size(
size_t size)
1463 returnget_total_size(
size) - (
sizeof(SAllocHeader)+
sizeof(SAllocFooter));
1467SAllocLog& start_log(
unsigned number, SAllocLog::EType
type)
1469SAllocLog& slot = alloc_log[
number% kLogSize];
1470slot.type = SAllocLog::eInit;
1471slot.completed =
false;
1472slot.seq_number =
number;
1480 voidmemchk(
const void* ptr,
char byte,
size_t size)
1482 for(
const char* p = (
const char*)ptr;
size; ++p, --
size) {
1490 void* s_alloc_mem(
size_t size,
bool array)
throw()
1492 unsigned number= seq_number.Add(1);
1497SAllocHeader* header;
1503 log.completed =
true;
1506SAllocFooter* footer = get_footer(header,
size);
1508header->magic = kAllocMagicHeader;
1509footer->magic = kAllocMagicFooter;
1510header->seq_number = footer->seq_number =
number;
1511header->size = footer->size =
size;
1512header->ptr = footer->ptr =
log.ptr = get_ptr(header);
1514std::memset(get_guard_before(header),
1515 array? kAllocFillBeforeArray: kAllocFillBeforeOne,
1516get_guard_before_size());
1517std::memset(get_guard_after(footer,
size),
1519get_guard_after_size(
size));
1520std::memset(get_ptr(header), kAllocFillInside,
size);
1522 log.completed =
true;
1523 returnget_ptr(header);
1527 voids_free_mem(
void* ptr,
bool array)
1529 unsigned number= seq_number.Add(1);
1531start_log(
number,
array? SAllocLog::eDeleteArr: SAllocLog::eDelete);
1535SAllocHeader* header = get_header(ptr);
1536 if( header->magic != kAllocMagicHeader ||
1537header->seq_number >=
number||
1538header->ptr != get_ptr(header) ) {
1541 size_t size=
log.size = header->size;
1542SAllocFooter* footer = get_footer(header,
size);
1543 if( footer->magic != kAllocMagicFooter ||
1544footer->seq_number != header->seq_number ||
1545footer->ptr != get_ptr(header) ||
1546footer->size !=
size) {
1550memchk(get_guard_before(header),
1551 array? kAllocFillBeforeArray: kAllocFillBeforeOne,
1552get_guard_before_size());
1553memchk(get_guard_after(footer,
size),
1555get_guard_after_size(
size));
1557header->magic = kFreedMagicHeader;
1558footer->magic = kFreedMagicFooter;
1559footer->seq_number =
number;
1560 static boolno_clear = s_EnvFlag(
"DEBUG_NEW_NO_FILL_ON_DELETE");
1562std::memset(get_guard_before(header),
1564get_all_guards_size(
size));
1566 static boolno_free = s_EnvFlag(
"DEBUG_NEW_NO_FREE_ON_DELETE");
1572 log.completed =
true;
1576 void*
operator new(
size_t size)
throw(std::bad_alloc)
1578 void* ret = s_alloc_mem(
size,
false);
1580 throwstd::bad_alloc();
1585 void*
operator new(
size_t size,
conststd::nothrow_t&)
throw()
1587 returns_alloc_mem(
size,
false);
1591 void*
operator new[](
size_t size)
throw(std::bad_alloc)
1593 void* ret = s_alloc_mem(
size,
true);
1595 throwstd::bad_alloc();
1600 void*
operator new[](
size_t size,
conststd::nothrow_t&)
throw()
1602 returns_alloc_mem(
size,
true);
1606 void operator delete(
void* ptr)
throw()
1608s_free_mem(ptr,
false);
1612 void operator delete(
void* ptr,
conststd::nothrow_t&)
throw()
1614s_free_mem(ptr,
false);
1618 void operator delete[](
void* ptr)
throw()
1620s_free_mem(ptr,
true);
1624 void operator delete[](
void* ptr,
conststd::nothrow_t&)
throw()
1626s_free_mem(ptr,
true);
@ eEmpty
no filtering at all.
void SetFrame(const string &frame)
void Log(const string &name, const char *value, CDebugDumpFormatter::EValueType type=CDebugDumpFormatter::eValue, const string &comment=kEmptyStr)
void DumpLocks(bool clear=false)
void Unlocked(const CObjectCounterLocker *locker, const CObject *object)
void Locked(const CObjectCounterLocker *locker, const CObject *object)
map< const CObject *, SLocks > TLocks
const_iterator lower_bound(const key_type &key) const
const_iterator end() const
iterator insert(const value_type &val)
container_type::iterator iterator
container_type::value_type value_type
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
TNCBIAtomicValue TValue
Alias TValue for TNCBIAtomicValue.
TValue Add(int delta) THROWS_NONE
Atomically add value (=delta), and return new counter value.
#define ERR_FATAL_X(err_subcode, message)
NCBI_XNCBI_EXPORT void Abort(void)
Smart abort function.
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
@ eDiag_Critical
Critical error message.
void Error(CExceptionArgs_Base &args)
#define NCBI_EXCEPTION_VAR(name, exception_class, err_code, message)
Create an instance of the exception to be thrown later.
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
#define NCBI_EXCEPTION_THROW(exception_var)
Throw an existing exception object.
virtual void x_InitErrCode(CException::EErrCode err_code)
Helper method for initializing error code.
#define THROWS_NONE
Do not use 'throw' dynamic exception specification for C++11 compilers.
EErrCode
Error types that an application can generate.
TErrCode GetErrCode(void) const
#define NCBI_THROW_FMT(exception_class, err_code, message)
The same as NCBI_THROW but with message processed as output to ostream.
virtual const char * GetErrCodeString(void) const
Get error code interpreted as text.
void RemoveLastReference(TCount count) const
Remove the last reference.
void TransferLock(const CObject *object, const CObjectCounterLocker &old_locker) const
static const int eCounterStep
Skip over the "in heap" bits.
void Clear(void)
Set pointer to NULL from object's destructor.
void CleanWeakRefs(void) const
Method cleaning all CWeakRefs referencing at this moment to the object After calling to this method a...
Uint8 TCount
Alias for value type of counter.
static void ReportLockedObjects(bool clear=false)
Print all currently locked objects of monitored type.
virtual void DoDeleteThisObject(void)
Mark this object as allocated in heap â object can be deleted.
static void StopMonitoring(void)
Stop lock/unlock monitoring.
EAllocFillMode
Control filling of newly allocated memory.
virtual const char * GetErrCodeString(void) const override
Translate from the error code value to its string representation.
static void SetAllocFillMode(EAllocFillMode mode)
CPtrToObjectProxy(CWeakObject *ptr)
static EAllocFillMode GetAllocFillMode(void)
void InitCounter(void)
Initialize counter.
bool x_AddWeakReference(CObject *obj)
Add reference to the object in "weak" manner.
virtual ~CObject(void)
Destructor.
virtual void DoNotDeleteThisObject(void)
Mark this object as not allocated in heap â do not delete this object.
void Relock(const CObject *object) const
void ReleaseReference(void) const
Remove reference without deleting object.
static bool ObjectStateReferencedOnlyOnce(TCount count)
Check if object can be referenced only once.
static NCBI_XNCBI_EXPORT void ThrowNullPointerException(void)
Define method to throw null pointer exception.
virtual void DebugDump(CDebugDumpContext ddc, unsigned int depth) const
Define method for dumping debug information.
virtual ~CWeakObject(void)
static const TCount eCounterBitsCanBeDeleted
Define possible object states.
void Reset(void)
Reset reference object.
void x_InitErrCode(CException::EErrCode err_code) override
Helper method for initializing error code.
void UnlockRelease(const CObject *object) const
virtual void DeleteThis(void)
Virtual method "deleting" this object.
static bool ObjectStateValid(TCount count)
Check if object state is valid.
static bool ObjectStateReferenced(TCount count)
Check if object can be referenced.
NCBI_XNCBI_EXPORT void CheckReferenceOverflow(TCount count) const
Report that counter has overflowed.
static void Delete(const CObject *object)
Check if object is allocated from some memory pool, and delete it correspondingly.
static bool ObjectStateIsAllocatedInPool(TCount count)
Check if object is allocated in memory pool.
static void ReportIncompatibleType(const type_info &type)
static const TCount eCounterValid
Minimal value for valid objects (reference counter is zero) Must be a single bit value.
static void MonitorObjectType(const type_info &type)
Set monitored object type, e.g.
CRef< CPtrToObjectProxy > m_SelfPtrProxy
Proxy object with pointer to this instance.
friend class CPtrToObjectProxy
CObject * GetLockedObject(void)
Lock the object and return pointer to it.
void Unlock(const CObject *object) const
atomic< Uint8 > TCounter
Counter type is CAtomiCounter.
static bool ObjectStateCanBeDeleted(TCount count)
Check if object can be deleted.
void Lock(const CObject *object) const
CObject(void)
Constructor.
static NCBI_XNCBI_EXPORT void ReportIncompatibleType(const type_info &type)
Report about trying to convert incompatible interface fo CObject.
static const TCount eCounterBitsInPlainHeap
Heap signature was found.
TCounter m_Counter
The actual reference counter.
static bool ObjectStateUnreferenced(TCount count)
Check if object can be referenced.
static const TCount eCounterStateMask
Valid object, and object in heap.
@ eDeleted
Attempt to delete a deleted object.
@ eRefDelete
Attempt to delete valid reference.
@ eCorrupted
Object corrupted error.
@ eRefOverflow
Reference overflow error.
@ eHeapState
Attempt to make incorrect in-heap state.
@ eRefUnref
Attempt to make a referenced object an unreferenced one.
@ eNoRef
Attempt to access an object that is unreferenced.
@ eParam_NoThread
Do not use per-thread values.
#define END_NCBI_SCOPE
End previously defined NCBI scope.
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
TFastMutexGuard CFastMutexGuard
...and backward compatibility
pthread_key_t TTlsKey
Define internal TLS key type.
unsigned int
A callback function used to compare two keys in a database.
Definition of all error codes used in corelib (xncbi.lib).
where both of them are integers Note
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
static void s_Cleanup(void *data)
Static variables safety - create on demand, destroy on application termination.
#define NCBI_CONST_UINT8(v)
Memory pool for fast allocation of memory for localized set of CObjects, e.g.
Multi-threading â mutexes; rw-locks; semaphore.
#define ALLOC_FILL_BYTE_PATTERN
static DECLARE_TLS_VAR(void *, s_LastNewPtr)
static CObject::EAllocFillMode sx_InitFillNewMemoryMode(void)
static const CObject::TCount eInitCounterInHeap
Initial counter value for in-heap objects.
static const CObject::TCount eMagicCounterPoolNew
Magic counter value for objects allocated in memory pool.
static void sx_PushLastNewPtrMultiple(void *ptr, CAtomicCounter::TValue type)
static TTlsKey sx_GetLastNewPtrMultipleKey(void)
static void sx_FillNewMemory(void *ptr, size_t size)
bool MonitoredType(const CObject *object)
static CObject::EAllocFillMode sm_AllocFillMode
static const CObject::TCount eInitCounterInPool
Initial counter value for objects allocated in memory pool.
static CAtomicCounter::TValue sx_PopLastNewPtrMultiple(void *ptr)
static const CAtomicCounter::TValue kLastNewTypeMultiple
#define ALLOC_FILL_MODE_INIT
NCBI_PARAM_DEF_EX(bool, NCBI, ABORT_ON_COBJECT_THROW, false, eParam_NoThread, NCBI_ABORT_ON_COBJECT_THROW)
static CSafeStatic< CLocksMonitor > sx_LocksMonitor
static TLastNewPtrMultiple & sx_GetLastNewPtrMultiple(void)
static const CObject::TCount eMagicCounterNew
Magic counter value for object allocated in heap.
NCBI_PARAM_DECL(bool, NCBI, ABORT_ON_COBJECT_THROW)
#define ALLOC_FILL_MODE_DEFAULT
static const CObject::TCount eMagicCounterPoolDeleted
Magic counter value for deleted object allocated in memory pool.
typedef NCBI_PARAM_TYPE(NCBI, ABORT_ON_NULL) TAbortOnNull
static bool sm_AllocFillMode_IsSet
static CAtomicCounter::TValue sx_PopLastNewPtr(void *ptr)
static const type_info * sx_MonitorType
static const CObject::TCount eMagicCounterDeleted
All magic counter values should have all their state bits off.
vector< TLastNewPtrMultipleInfo > TLastNewPtrMultiple
static void sx_PushLastNewPtr(void *ptr, CAtomicCounter::TValue type)
DEFINE_STATIC_FAST_MUTEX(s_WeakRefMutex)
pair< void *, CAtomicCounter::TValue > TLastNewPtrMultipleInfo
static const CObject::TCount eInitCounterNotInHeap
Initial counter value for non-heap objects.
static atomic< TTlsKey > s_LastNewPtrMultiple_key
static TTlsKey sx_GetLastNewPtrMultipleCurrentKey(void)
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
Multi-threading â classes, functions, and features.
Int4 delta(size_t dimension_, const Int4 *score_)
multimap< const CObjectCounterLocker *, AutoPtr< CStackTrace > > TUnlocks
int LockCount(void) const
multimap< const CObjectCounterLocker *, AutoPtr< CStackTrace > > TLocks
void Locked(const CObjectCounterLocker *locker, const CObject *object)
bool Unlocked(const CObjectCounterLocker *locker)
static void sx_Cleanup(void *ptr)
~SEraseLastNewPtrMultiple()
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4