120 #define NCBI_USE_ERRCODE_X Connect_HeapMgr
122 #if defined(NCBI_OS_MSWIN) && defined(_WIN64)
124 # pragma warning (disable : 4311)
130 #define abs(a) ((a) < 0 ? (a) : -(a))
133 # if NCBI_PLATFORM_BITS == 64
135 # define HEAP_PACKED __attribute__((packed))
136 # elif defined(_CRAYC)
139 # error "Don't know how to pack on this 64-bit platform"
174 #define _HEAP_ALIGN_EX(a, b) ((((unsigned long)(a) + ((b) - 1)) / (b)) * (b))
175 #define _HEAP_ALIGN_2(a, b) (( (unsigned long)(a) + ((b) - 1)) \
176 & (unsigned long)(~((b) - 1)))
177 #define _HEAP_SIZESHIFT 4
178 #define HEAP_BLOCKS(s) ((s) >> _HEAP_SIZESHIFT)
179 #define HEAP_EXTENT(b) ((b) << _HEAP_SIZESHIFT)
180 #define HEAP_ALIGN(a) _HEAP_ALIGN_2(a, HEAP_EXTENT(1))
181 #define HEAP_MASK (~(HEAP_EXTENT(1) - 1))
182 #define HEAP_PREV_BIT 8
183 #define HEAP_NEXT_BIT 4
186 #define HEAP_SIZE(s) ((s) & (unsigned long) HEAP_MASK)
187 #define HEAP_FLAG(s) ((s) & (unsigned long)(~HEAP_MASK))
188 #define HEAP_NEXT(b) ((SHEAP_HeapBlock*) \
189 ((char*)(b) + (b)->head.size))
190 #define HEAP_PREV(b) ((SHEAP_HeapBlock*) \
191 ((char*)(b) - HEAP_SIZE((b)->head.flag)))
192 #define HEAP_INDEX(b, base) ((TNCBI_Size)((b) - (base)))
193 #define HEAP_ISLAST(b) ((b)->head.flag & HEAP_LAST)
194 #define HEAP_ISUSED(b) ((b)->head.flag & HEAP_USED)
196 #define HEAP_CHECK(heap) \
197 assert(!heap->base == !heap->size); \
198 assert(heap->used <= heap->size); \
199 assert(heap->free <= heap->size); \
200 assert(heap->last <= heap->size); \
201 assert(heap->used == heap->size || heap->free < heap->size)
203 #if ~HEAP_MASK != (HEAP_PREV_BIT | HEAP_NEXT_BIT | HEAP_LAST | HEAP_USED) \
204 || HEAP_BLOCKS(~HEAP_MASK) != 0
205 # error "HEAP_MASK is invalid!"
225 static int x_Parity(
unsigned int v)
230 v = (v & 0x11111111U) * 0x11111111U;
231 return (v >> 28) & 1;
237 return (0x6996 >> v) & 1;
274 (
"Heap Create: Storage too small:"
275 " provided %u, required %u+",
288 heap->auxarg =
heap->resize ? auxarg : 0;
296 (
"Heap Create: Unaligned base (0x%08lX)",
320 (
"Heap Attach: Unaligned base (0x%08lX)", (
long) base));
327 heap->serial = serial;
330 (
"Heap Attach: Heap size truncation (%u->%u)"
331 " can result in missing data",
342 if (base && (!maxsize || maxsize >
sizeof(
SHEAP_Block))) {
350 (
"Heap Attach: Heap corrupt @%u (0x%08X, %u)",
352 b->head.flag,
b->head.size));
356 size +=
b->head.size;
361 (
"Heap Attach: Runaway heap @%u (0x%08X, %u)"
362 " size=%u vs. maxsize=%u",
364 b->head.flag,
b->head.size,
407 if (!hint && need < (e->
head.
size >> 1)) {
411 if (b < heap->base ||
heap->base +
heap->size <=
b) {
418 if (need <= b->
head.size) {
427 f =
b->head.size < need ? 0 :
b;
428 for (
b =
heap->base +
b->prevfree; ;
b =
heap->base +
b->prevfree) {
430 if (b < heap->base ||
heap->base +
heap->size <=
b) {
437 if (
b == e ||
b->head.size < need)
446 char _id[32], msg[80];
448 sprintf(msg,
" (0x%08X, %u)",
b->head.flag,
b->head.size);
452 (
"Heap Find%s: Heap corrupt @%u/%u%s",
476 if (
b->head.size <
f->head.size) {
479 f->nextfree =
b->nextfree;
491 f->prevfree =
b->prevfree;
498 #if defined(_DEBUG) && !defined(NDEBUG)
499 # define s_HEAP_Unlink(b) { b->prevfree = b->nextfree = ~((TNCBI_Size) 0); }
501 # define s_HEAP_Unlink(b)
518 unsigned int last = 0;
528 assert(!need ||
b->head.size < need);
530 free +=
b->head.size;
533 assert(
f != p && (u || (!
n && !need)));
536 heap->base[
b->prevfree].nextfree =
b->nextfree;
537 heap->base[
b->nextfree].prevfree =
b->prevfree;
539 heap->free =
b->prevfree;
544 heap->base[
f->prevfree].nextfree =
f->nextfree;
545 heap->base[
f->nextfree].prevfree =
f->prevfree;
546 }
else if (
heap->free !=
f->prevfree) {
547 heap->base[
f->prevfree].nextfree =
f->nextfree;
548 heap->base[
f->nextfree].prevfree =
f->prevfree;
549 heap->free =
f->prevfree;
571 if (need && need <=
free)
587 f->head.flag = (p ? p->head.size : 0) |
last;
613 f->head.size -=
size;
623 f->head.flag =
b->head.flag;
624 f->head.size = save -
size;
635 memset((
char*)
b + need, 0,
size);
669 n =
heap->base +
f->nextfree;
676 n->prevfree =
f->prevfree;
677 heap->base[
f->prevfree].nextfree =
f->nextfree;
679 heap->free =
f->prevfree;
703 (
"Heap Alloc%s: Unaligned base (0x%08lX)",
708 dsize = hsize - dsize;
709 memset(base +
heap->size, 0, dsize);
710 f = base +
heap->last;
714 f->head.size = hsize;
724 f = base +
heap->size;
726 f->head.size = dsize;
730 if (
f != base +
heap->free) {
733 }
else if (
heap->free !=
f->prevfree) {
736 heap->free =
f->prevfree;
741 f->head.size += dsize;
774 b->head.size +=
n->head.size;
781 if (
heap->free ==
n->prevfree) {
785 b->prevfree =
heap->free;
786 b->nextfree =
heap->free;
789 heap->free =
n->prevfree;
791 heap->base[
n->nextfree].prevfree =
n->prevfree;
792 heap->base[
n->prevfree].nextfree =
n->nextfree;
846 (
"Heap Free%s: Heap corrupt @%u/%u (0x%08X, %u)",
848 heap->size,
b->head.flag,
b->head.size));
854 (
"Heap Free%s: Freeing free block @%u",
909 if (!p || p < heap->base || e <= p)
914 (
"Heap Free%s: Lame hint%s for block @%u",
921 (
"Heap Free%s: Freeing free block @%u",
957 if (!
b ||
b->head.size <
heap->chunk) {
960 }
else if (!(
size =
b->head.size %
heap->chunk)) {
978 (
"Heap Trim%s: Unaligned base (0x%08lX)",
1022 if (p < heap->base || e <= p
1033 if (e <=
b ||
b <= p
1037 if (
b != e || (
b && !p)) {
1049 (
n < e || (
heap->chunk && b < heap->base +
heap->last))) {
1052 sprintf(msg,
" %s @%u", l < e &&
HEAP_NEXT(l) == e
1053 ?
"expected" :
"invalid",
heap->last);
1068 for (
i = 0;
i <
heap->size; ++
i) {
1082 if (
self || (c <=
b &&
b <= s)){
1114 if (
heap->size <=
b->prevfree ||
1115 heap->size <=
b->nextfree
1119 }
else if (
b->prevfree !=
b->nextfree ||
1120 b !=
heap->base +
b->nextfree) {
1121 for (
i = 0;
i <
heap->size; ++
i) {
1123 b =
heap->base +
b->nextfree;
1125 heap->size <=
b->nextfree ||
1126 s !=
heap->base +
b->prevfree) {
1134 b =
heap->base +
b->nextfree;
1136 if (!c || !
b ||
b != c) {
1138 sprintf(msg,
" @%u/%u (%u, <-%u, %u->)",
1145 b && c ?
"broken" :
"corrupt", msg));
1154 for (
i = 0; c < e &&
i <
heap->size; ++
i) {
1159 (
"Heap Walk%s: Used block @%u within"
1188 (
"Heap Walk%s: Adjacent free blocks"
1268 char* base = (
char*)
copy +
sizeof(*
copy);
1282 copy->serial = serial;
1300 return heap->refcnt;
1309 if (
heap->refcnt && --
heap->refcnt)
1310 return heap->refcnt;
1324 if (!
heap->chunk && !
heap->refcnt) {
1327 }
else if (
heap->resize)
1369 size +=
b->head.size;
1370 b =
heap->base +
b->prevfree;
1372 #if defined(_DEBUG) && !defined(NDEBUG)
1376 alt_size +=
b->head.size;
1377 b =
heap->base +
b->nextfree;
1395 return heap->serial;
static int heap[2 *(256+1+29)+1]
static DLIST_TYPE *DLIST_NAME() last(DLIST_LIST_TYPE *list)
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
SHEAP_Block * HEAP_Next(const HEAP heap, const SHEAP_Block *ptr)
void * HEAP_Base(const HEAP heap)
void HEAP_Options(ESwitch fast, ESwitch unused)
SHEAP_Block * HEAP_Alloc(HEAP heap, TNCBI_Size size, int tail)
HEAP HEAP_Copy(const HEAP heap, size_t extra, int serial)
SHEAP_Block * HEAP_Walk(const HEAP heap, const SHEAP_Block *ptr)
HEAP HEAP_Create(void *base, TNCBI_Size size, TNCBI_Size chunk, FHEAP_Resize resize, void *auxarg)
unsigned int HEAP_Destroy(HEAP heap)
void HEAP_Free(HEAP heap, SHEAP_Block *ptr)
int HEAP_Serial(const HEAP heap)
HEAP HEAP_AttachFast(const void *base, TNCBI_Size size, int serial)
HEAP HEAP_Attach(const void *base, TNCBI_Size maxsize, int serial)
void *(* FHEAP_Resize)(void *old_base, TNCBI_Size new_size, void *auxarg)
void HEAP_FreeFast(HEAP heap, SHEAP_Block *ptr, const SHEAP_Block *prev)
unsigned int HEAP_AddRef(HEAP heap)
TNCBI_Size HEAP_Idle(const HEAP heap)
HEAP HEAP_Trim(HEAP heap)
unsigned int HEAP_Detach(HEAP heap)
TNCBI_Size HEAP_Size(const HEAP heap)
TNCBI_Size HEAP_Used(const HEAP heap)
enum ENcbiSwitch ESwitch
Aux.
unsigned int TNCBI_Size
Fixed-size analogs of size_t and time_t (mainly for IPC)
unsigned int
A callback function used to compare two keys in a database.
const struct ncbi::grid::netcache::search::fields::SIZE size
void resize(vector< SMethodDef > &container)
static SHEAP_HeapBlock * s_HEAP_Collect(HEAP heap, TNCBI_Size need)
static SHEAP_HeapBlock * x_HEAP_Walk(const HEAP heap, const SHEAP_Block *ptr)
static SHEAP_HeapBlock * s_HEAP_Walk(const HEAP heap, const SHEAP_Block *ptr)
static SHEAP_Block * s_HEAP_Take(HEAP heap, SHEAP_HeapBlock *b, SHEAP_HeapBlock *n, TNCBI_Size size, TNCBI_Size need, int tail)
#define _HEAP_ALIGN_2(a, b)
#define _HEAP_ALIGN_EX(a, b)
#define HEAP_INDEX(b, base)
static SHEAP_HeapBlock * s_HEAP_Find(HEAP heap, TNCBI_Size need, SHEAP_HeapBlock *hint)
static void s_HEAP_Free(HEAP heap, SHEAP_HeapBlock *p, SHEAP_HeapBlock *b, SHEAP_HeapBlock *n)
static const char * s_HEAP_Id(char *buf, HEAP h)
static void s_HEAP_Link(HEAP heap, SHEAP_HeapBlock *f, SHEAP_HeapBlock *hint)
#define CORE_LOGF_X(subcode, level, fmt_args)
#define CORE_LOG_X(subcode, level, message)
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
double f(double x_, const double &y_)
voidp calloc(uInt items, uInt size)