void delist(struct cell *cell) { if (cell && cell->next && cell->next->next) { cell->next= cell->next->next; delist(cell->next->next); } }
void destroyLinkedList(linkedList *LinkedList) { while (delist(LinkedList)) ; if (LinkedList) free(LinkedList); }
unsigned Sweepable::SweepAll() { unsigned count = 0; // iterate until both sweep lists are empty. Entries can be added or removed // from either list during sweeping, so we drain the lists without holding // iterators across any sweep() callbacks. do { while (t_sweep.next != &t_sweep) { count++; auto n = t_sweep.next; n->delist(); n->init(); auto s = reinterpret_cast<Sweepable*>( uintptr_t(n) - offsetof(Sweepable, m_sweepNode) ); s->sweep(); } while (!t_objects.empty()) { // drain each bucket before moving to the next, avoiding O(n) begin() for (unsigned i = 0; i < t_objects.bucket_count(); i++) { for (auto it = t_objects.begin(i); it != t_objects.end(i); it = t_objects.begin(i)) { count++; auto obj = it->first; auto sweeper = it->second; t_objects.erase(obj); sweeper(obj); } } } } while (t_sweep.next != &t_sweep); return count; }
NEVER_INLINE void StringData::releaseDataSlowPath() { assert(isProxy()); assert(checkSane()); proxy()->apcstr->getHandle()->unreference(); delist(); MM().freeSmallSize(this, sizeof(StringData) + sizeof(Proxy)); }
NEVER_INLINE void StringData::releaseDataSlowPath() { assert(!isFlat()); assert(isShared()); assert(checkSane()); sharedPayload()->shared->getHandle()->unreference(); delist(); MM().freeSmallSize(this, sizeof(StringData) + sizeof(SharedPayload)); }
void TimerQueue::event::detach(void) { TimerQueue *tq = list(); if(tq) { tq->modify(); clear(); delist(); tq->update(); } }
/* * Change to smart-malloced string. Then returns a mutable slice of * the usable string buffer (minus space for the null terminator). */ MutableSlice StringData::escalate(uint32_t cap) { assert(isShared() && !isStatic() && cap >= m_len); char *buf = (char*)smart_malloc(cap + 1); StringSlice s = slice(); memcpy(buf, s.ptr, s.len); buf[s.len] = 0; m_big.shared->decRef(); delist(); m_data = buf; setModeAndCap(Mode::Smart, cap + 1); // clear precomputed hashcode m_hash = 0; assert(checkSane()); return MutableSlice(buf, cap); }
HOT_FUNC void StringData::releaseDataSlowPath() { assert(!isSmall()); assert(checkSane()); auto const loadedMode = mode(); if (LIKELY(loadedMode == Mode::Smart)) { smart_free(m_data); return; } if (loadedMode == Mode::Shared) { assert(checkSane()); m_big.shared->decRef(); delist(); return; } assert(loadedMode == Mode::Malloc); assert(checkSane()); free(m_data); }
int main() { int i, j; void *a, *b, *c, *d, *e; for (i= 0; i < 10000; ++i) { a= 0; GC_PROTECT(a); b= 0; GC_PROTECT(b); c= 0; GC_PROTECT(c); d= 0; GC_PROTECT(d); e= 0; GC_PROTECT(e); #if !VERBOSE # define printf(...) #endif //#define GC_malloc malloc //#define GC_free free a= GC_malloc(RAND(1)); printf("%p\n", a); ++objs; b= GC_malloc(RAND(10)); printf("%p\n", b); ++objs; c= GC_malloc(RAND(100)); printf("%p\n", c); ++objs; d= GC_malloc(RAND(1000)); printf("%p\n", d); ++objs; e= GC_malloc(RAND(10000)); printf("%p\n", e); ++objs; GC_free(a); a= 0; GC_free(b); b= 0; // GC_free(c); GC_free(d); d= 0; GC_free(e); e= 0; a= GC_malloc(RAND(100)); printf("%p\n", a); ++objs; b= GC_malloc(RAND(200)); printf("%p\n", b); ++objs; c= GC_malloc(RAND(300)); printf("%p\n", c); ++objs; d= GC_malloc(RAND(400)); printf("%p\n", d); ++objs; e= GC_malloc(RAND(500)); printf("%p\n", e); ++objs; GC_free(e); e= 0; GC_free(d); d= 0; // GC_free(c); GC_free(b); b= 0; GC_free(a); a= 0; a= GC_malloc(RAND(4)); printf("%p\n", a); ++objs; b= GC_malloc(RAND(16)); printf("%p\n", b); ++objs; c= GC_malloc(RAND(64)); printf("%p\n", c); ++objs; d= GC_malloc(RAND(256)); printf("%p\n", d); ++objs; e= GC_malloc(RAND(1024)); printf("%p\n", e); ++objs; GC_free(e); e= 0; GC_free(b); b= 0; // GC_free(c); GC_free(d); d= 0; GC_free(a); a= 0; a= GC_malloc(RAND(713)); printf("%p\n", a); ++objs; b= GC_malloc(RAND(713)); printf("%p\n", b); ++objs; c= GC_malloc(RAND(713)); printf("%p\n", c); ++objs; d= GC_malloc(RAND(713)); printf("%p\n", d); ++objs; e= GC_malloc(RAND(713)); printf("%p\n", e); ++objs; GC_free(a); a= 0; GC_free(c); c= 0; // GC_free(e); GC_free(d); d= 0; GC_free(b); b= 0; #undef printf if (i % 1000 == 0) printf("alloc: %ld bytes in %ld objects; alive: %ld bytes in %ld objects\n", bytes, objs, GC_count_bytes(), GC_count_objects()); GC_gcollect(); if (i % 1000 == 0) printf(" gc: %ld bytes in %ld objects; alive: %ld bytes in %ld objects\n", bytes, objs, GC_count_bytes(), GC_count_objects()); GC_UNPROTECT(a); } { a= 0; GC_PROTECT(a); for (i= 0; i < 10; ++i) { for (j= 0; j < 100; ++j) { a= mklist(2000); delist(a); #if VERBOSE { struct cell *c= a; printf("----\n"); while (c) { printf("%p %d %p\n", c, c->tag >> 1, c->next); c= c->next; } } #endif } printf("alloc: %ld bytes in %ld objects; alive: %ld bytes in %ld objects\n", bytes, objs, GC_count_bytes(), GC_count_objects()); GC_gcollect(); printf(" gc: %ld bytes in %ld objects; alive: %ld bytes in %ld objects\n", bytes, objs, GC_count_bytes(), GC_count_objects()); } GC_UNPROTECT(a); } printf("alive: %ld bytes in %ld objects\n", GC_count_bytes(), GC_count_objects()); GC_gcollect(); printf(" gc: %ld bytes in %ld objects\n", GC_count_bytes(), GC_count_objects()); printf(" gc: %ld collections\n", GC_collections); return 0; }