static HEAP s_Shmem_Attach(int which) { void* shmem = 0; /*dummy init for compiler not to complain*/ int shmid; HEAP heap; #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] attaching", which + 1)); #endif /*LBSM_DEBUG*/ if ((shmid = shmget(k_ShmemKey[which], 0, 0)) >= 0 && (shmid == s_Shmid[which] || ((shmem = shmat(shmid, 0, SHM_RDONLY)) && shmem != (void*)(-1)))) { if (shmid != s_Shmid[which]) { struct shmid_ds shm_ds; #ifdef LBSM_DEBUG CORE_LOGF(eLOG_Trace, ("LBSM shmem[%d] attached", which + 1)); #endif /*LBSM_DEBUG*/ s_Shmid[which] = shmid; if (s_Shmem[which]) shmdt(s_Shmem[which]); s_Shmem[which] = shmem; s_ShmemSize[which] = (shmctl(shmid, IPC_STAT, &shm_ds) < 0 ? 0 : shm_ds.shm_segsz); } heap = (s_ShmemSize[which] ? HEAP_AttachFast(s_Shmem[which], s_ShmemSize[which], which+1) : HEAP_Attach (s_Shmem[which], which+1)); } else heap = 0; return heap; }
int main(int argc, const char* argv[]) { SHEAP_Block* blk; int r, j, i, n; HEAP heap; char* c; /* CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel); */ CORE_SetLOGFILE(stderr, 0/*false*/); if (argc > 1) g_NCBI_ConnectRandomSeed = atoi(argv[1]); else g_NCBI_ConnectRandomSeed = (int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND; CORE_LOGF(eLOG_Note, ("Using seed %d", g_NCBI_ConnectRandomSeed)); HEAP_Options(eOff/*slow*/, eOn/*newalk*/); srand(g_NCBI_ConnectRandomSeed); for (j = 1; j <= 3; j++) { CORE_LOGF(eLOG_Note, ("Creating heap %d", j)); if (!(heap = HEAP_Create(0, 0, 4096, s_Expand, 0))) CORE_LOG(eLOG_Error, "Cannot create heap"); for (n = 0; n < 1000 && (rand() & 0xFFFF) != 0x1234; n++) { r = rand() & 7; if (r == 1 || r == 3) { int/*bool*/ fast = rand() & 1; i = rand() & 0xFF; if (i) { CORE_LOGF(eLOG_Note, ("Allocating%s data size %d", fast ? " fast" : "", i)); blk = fast ? HEAP_AllocFast(heap, i) : HEAP_Alloc(heap, i); if (blk) { CORE_LOGF(eLOG_Note, ("Done @%u, size %u", HEAP_ADDR(blk, heap), blk->size)); } else CORE_LOG(eLOG_Error, "Allocation failed"); c = (char*) blk + sizeof(*blk); while (i--) *c++ = rand(); s_Walk(heap, 0); } else { assert(!(fast ? HEAP_AllocFast(heap, i) : HEAP_Alloc(heap, i))); } } else if (r == 2 || r == 4) { blk = 0; do { if (!(blk = HEAP_Walk(heap, blk))) break; } while (rand() & 7); if (blk && (short) blk->flag) { unsigned size = blk->size; unsigned data_size = size - sizeof(*blk); CORE_LOGF(eLOG_Note, ("Freeing @%u, size %u, data size %u", HEAP_ADDR(blk, heap), size, data_size)); assert(data_size); HEAP_Free(heap, blk); CORE_LOG(eLOG_Note, "Done"); s_Walk(heap, 0); } } else if (r == 5) { const SHEAP_Block* prev = 0; unsigned ok = 0; blk = 0; for (;;) { if (!(blk = HEAP_Walk(heap, blk))) break; if ((short) blk->flag && (rand() & 7)) { char buf[32]; unsigned size = blk->size; int/*bool*/ fast = rand() & 1; unsigned data_size = size - sizeof(*blk); if (!fast || !prev) *buf = '\0'; else sprintf(buf, ", prev @%u", HEAP_ADDR(prev, heap)); CORE_LOGF(eLOG_Note, ("Freeing%s%s @%u%s in walk," " size %u, data size %u", fast ? " fast" : "", ok ? " more" : "", HEAP_ADDR(blk,heap), buf, size, data_size)); assert(data_size); if (fast) HEAP_FreeFast(heap, blk, prev); else HEAP_Free(heap, blk); CORE_LOG(eLOG_Note, "Done"); s_Walk(heap, 0); ok = 1; if (prev && !((short) prev->flag)) continue; } prev = blk; } if (!ok) s_Walk(heap, "the"); else CORE_LOG(eLOG_Note, "Done with freeing while walking"); } else if (r == 6 || r == 7) { HEAP newheap; if (r == 6) { int/*bool*/ fast = rand() & 1; if (fast) { CORE_LOG(eLOG_Note, "Attaching heap fast"); newheap = HEAP_AttachFast(HEAP_Base(heap), HEAP_Size(heap), 0); } else { CORE_LOG(eLOG_Note, "Attaching heap"); newheap = HEAP_Attach(HEAP_Base(heap), 0); } } else { CORE_LOG(eLOG_Note, "Copying heap"); newheap = HEAP_Copy(heap, 0, 0); } if (!newheap) { CORE_LOGF(eLOG_Error, ("%s failed", r == 6 ? "Attach" : "Copy")); } else s_Walk(newheap, r == 6 ? "attached" : "copied"); HEAP_Detach(newheap); } else { TNCBI_Size size = HEAP_Size(heap); HEAP newheap; CORE_LOG(eLOG_Note, "Trimming heap"); newheap = HEAP_Trim(heap); CORE_LOGF(eLOG_Note, ("Heap %strimmed: %u -> %u", newheap ? "" : "NOT ", size, HEAP_Size(newheap))); if (newheap) { heap = newheap; s_Walk(heap, "trimmed"); } } } HEAP_Destroy(heap); CORE_LOGF(eLOG_Note, ("Heap %d done", j)); } CORE_LOG(eLOG_Note, "Test completed"); CORE_SetLOG(0); return 0; }