void releaseHeap(Heap *h, serverstate ss) { restoreHeap(h,ss); LOCK_LOCK(STACKPOOLMUTEX); // if ( heapPoolIndex < MAX_HEAP_POOL_SZ ) if ( heapPoolIndex < maxHeapPoolSz ) { if (!heapPool) { heapPool = (Heap **) calloc(maxHeapPoolSz, sizeof(Heap *)); if (!heapPool) { LOCK_UNLOCK(STACKPOOLMUTEX); deleteHeap(h); return; } } heapPool[heapPoolIndex++] = h; LOCK_UNLOCK(STACKPOOLMUTEX); } else { LOCK_UNLOCK(STACKPOOLMUTEX); deleteHeap(h); } return; }
void T(report_all)(void) { LOCK_LOCK(&lock); T(report_all_unsafe)(); LOCK_UNLOCK(&lock); }
unsigned int getMaxHeapPoolSz(void) { unsigned int i; LOCK_LOCK(STACKPOOLMUTEX); i = maxHeapPoolSz; LOCK_UNLOCK(STACKPOOLMUTEX); return i; }
void setMaxHeapPoolSz(unsigned int i) { unsigned int j; static Heap **tmp; LOCK_LOCK(STACKPOOLMUTEX); if (maxHeapPoolSz == i) { LOCK_UNLOCK(STACKPOOLMUTEX); return; } if (!heapPool) { maxHeapPoolSz = i; LOCK_UNLOCK(STACKPOOLMUTEX); return; } tmp = calloc(i, sizeof(Heap *)); if (!tmp) { LOCK_UNLOCK(STACKPOOLMUTEX); // log something return; } for (j = 0; j < maxHeapPoolSz; j++) { if (j < i) { tmp[j] = heapPool[j]; } else { if (j < heapPoolIndex) deleteHeap(heapPool[j]); } } heapPoolIndex = heapPoolIndex > i ? i : heapPoolIndex; free(heapPool); heapPool = tmp; LOCK_UNLOCK(STACKPOOLMUTEX); return; }
Heap* getHeap(serverstate ss) { Heap* h; LOCK_LOCK(STACKPOOLMUTEX); if ( heapPoolIndex ) { // Sound as heapPoolIndex != 0 --> heapPool != NULL h = heapPool[--heapPoolIndex]; LOCK_UNLOCK(STACKPOOLMUTEX); } else // allocate new heap { int hid = heapid_counter++; LOCK_UNLOCK(STACKPOOLMUTEX); h = newHeap(ss); h->heapid = hid; } return h; }
static void T(init_common)(void) { (void) LOCK_INIT(&lock); (void) LOCK_LOCK(&lock); (void) LOCK_UNLOCK(&lock); (void) pthread_key_create(&thread_key, T(clean_key)); (void) pthread_setspecific(thread_key, NULL); main_thread = pthread_self(); (void) memset(&lo_guard, '[', sizeof (lo_guard)); }
void clearHeapCache() { Heap *h; LOCK_LOCK(STACKPOOLMUTEX); while ( heapPoolIndex ) { // Sound as heapPoolIndex != 0 --> heapPool != NULL h = heapPool[--heapPoolIndex]; deleteHeap(h); } LOCK_UNLOCK(STACKPOOLMUTEX); return; }
size_t size_free_list() { Rp *rp; size_t i=0; LOCK_LOCK(FREELISTMUTEX); for ( rp = freelist ; rp ; rp = rp-> n ) i++; LOCK_UNLOCK(FREELISTMUTEX); return i; }
void T(free)(void *chunk, const char *here, long lineno) { track_list *list; track_data *track; if (chunk == NULL) { LOGFREE(chunk, here, lineno); return; } track = &((track_data *) chunk)[-1]; LOGTRACKAT(track, here, lineno); /* Check the pointer and core data are valid. */ if (track->crc != TRACK_CRC(track)) { /* The rest of the data is suspect. */ (void) fprintf(stderr, HERE_FMT "buffer under run or bad pointer!\n", HERE_ARG); abort(); } /* Did something run into us from below? */ if (track->lo_guard != lo_guard) { (void) fprintf( stderr, HERE_FMT "buffer guard corrupted! size=%zu %s:%ld\n", HERE_ARG, track->size, track->here, track->lineno ); abort(); } /* Maintain list of allocated memory per thread, including main() */ list = pthread_getspecific(thread_key); if (track->prev == NULL) list->head = track->next; else track->prev->next = track->next; if (track->next != NULL) track->next->prev = track->prev; (void) pthread_setspecific(thread_key, list); (free)(track); (void) LOCK_LOCK(&lock); free_count++; (void) LOCK_UNLOCK(&lock); }
void T(clean_key)(void *data) { track_list *list; LOGTRACE(); if (data != NULL) { list = data; LOCK_LOCK(&lock); list->prev->next = list->next; list->next->prev = list->prev; LOCK_UNLOCK(&lock); T(report)(list); (free)(list); (void) pthread_setspecific(thread_key, NULL); } }
void * T(malloc)(size_t size, const char *here, long lineno) { track_list *list; track_data *track; if (track_hook__exit == NULL) T(init)(); if ((track = (malloc)(sizeof (*track) + size + (size == 0))) == NULL) { LOGMALLOC(NULL, size, here, lineno); return NULL; } (void) LOCK_LOCK(&lock); malloc_count++; track->id = malloc_count; (void) LOCK_UNLOCK(&lock); track->size = size; track->here = here; track->lineno = lineno; track->lo_guard = lo_guard; track->crc = TRACK_CRC(track); /* Maintain list of allocated memory per thread, including main() */ list = (track_list *)pthread_getspecific(thread_key); if (list == NULL) { if ((list = (malloc)(sizeof (*list))) == NULL) { (free)(track); return NULL; } list->thread = pthread_self(); list->head = NULL; /* Each thread maintains an allocation list and each * allocation list is a member of a circular double * link list of lists. This allows us to dump all * the current allocations for all threads any time. */ LOCK_LOCK(&lock); if (main_list == NULL) { list->prev = list; list->next = list; main_list = list; } else { list->prev = main_list->prev; list->next = main_list; main_list->prev->next = list; main_list->prev = list; } LOCK_UNLOCK(&lock); } /* Push allocation to head of list. */ track->prev = NULL; track->next = list->head; if (list->head != NULL) list->head->prev = track; list->head = track; (void) pthread_setspecific(thread_key, list); LOGTRACKAT(track, here, lineno); return &track[1]; }
virtual void Release() override { LOCK_UNLOCK(_lock); }