static void large_free(malloc_t *heap, void *ptr) { uintptr_t addri = (uintptr_t) ptr; malloc_hdr_t *hdr; (void) addri; #ifndef DISABLE_HEAP_GUARD if ((addri & (PAGE_SIZE - 1)) != sizeof(malloc_hdr_t)) heap_error("BAD FREE: large address is not aligned ptr=%08X\n", addri); #endif hdr = (malloc_hdr_t *)(ptr - sizeof(malloc_hdr_t)); #ifndef DISABLE_HEAP_GUARD if (hdr->heap != heap) heap_error("BAD FREE: wrong heap address ptr=%08X (%08X != %08X)\n", addri, hdr->heap, heap); if (hdr->size_flags < LARGE_SIZE || hdr->size_flags > (MAX_SIZE + PAGE_SIZE) || hdr->size_flags & (PAGE_SIZE - 1)) heap_error("BAD FREE: wrong block size ptr=%08X (%08X)\n", addri, hdr->size_flags); #endif deallocate(hdr, hdr->size_flags); }
static void small_free(malloc_t *heap, void *ptr) { uintptr_t addri = (uintptr_t) ptr; malloc_small_free_t *hdr = (malloc_small_free_t *) (addri - sizeof(malloc_hdr_t)); malloc_small_free_t *prev, *next; small_run_t *block = (small_run_t *)(addri & ~(RUN_SIZE - 1)); (void) block; #ifndef DISABLE_HEAP_GUARD if (addri & 7) heap_error("BAD SMALL FREE: address is not aligned ptr=%08X\n", addri); if (hdr->hdr.size_flags & 1) heap_error("BAD SMALL FREE: double free ptr=%08x\n", addri); if (hdr->hdr.size_flags > LARGE_SIZE || hdr->hdr.size_flags < SMALL_SIZE) heap_error("BAD SMALL FREE: corrupted size ptr=%08x\n", addri); /* TODO: verify block */ #endif if (hdr->hdr.prev_size == 0) prev = NULL; else prev = (malloc_small_free_t *) ((uintptr_t)hdr - hdr->hdr.prev_size); next = (malloc_small_free_t *) ((uintptr_t)hdr + hdr->hdr.size_flags); #ifndef DISABLE_HEAP_GUARD if (prev != NULL && (prev->hdr.size_flags & ~1) != hdr->hdr.prev_size) heap_error("BAD SMALL FREE: heap corruption prev=%08X ptr=%08X\n", (uintptr_t) prev, addri); if (next->hdr.prev_size != hdr->hdr.size_flags) heap_error("BAD SMALL FREE: heap corruption next=%08X ptr=%08X\n", (uintptr_t) next, addri); #endif if (prev != NULL && (prev->hdr.size_flags & 1)) { small_unlink_free(heap, size_to_bin(prev->hdr.size_flags & ~1), prev); /* combine blocks */ prev->hdr.size_flags += hdr->hdr.size_flags; hdr = prev; next->hdr.prev_size = hdr->hdr.size_flags; } if (next->hdr.size_flags & 1) { small_unlink_free(heap, size_to_bin(next->hdr.size_flags & ~1), next); /* combine blocks */ hdr->hdr.size_flags += next->hdr.size_flags; next = (malloc_small_free_t *) ((uintptr_t)hdr + hdr->hdr.size_flags); next->hdr.prev_size = hdr->hdr.size_flags; } small_insert_free(heap, size_to_bin(hdr->hdr.size_flags), hdr); }
sheap_ele_t SHeap::delete_min(void) { if (is_empty()) heap_error("Somebody tried to delete_min while empty."); return tree->delete_min(); }
sheap_ele_t SHeap::query_min(void) { if (is_empty()) heap_error("Somebody tried to query_min while empty."); return tree->query_min(); }
SHeap::SHeap(void) { tree = new SplayTree; if (tree == NULL) heap_error("Out of memory. Could not create heap."); return; }
void SHeap::delete_ele(sheap_ele_t ele, sheap_key_t key) { int err; err = tree->delete_node(key, ele); if (err == 1) heap_error("delete_ele() failed. (Not found)."); return; }
void SHeap::insert(sheap_ele_t new_ele, sheap_key_t key) { int err; err=tree->insert(key, new_ele); if (err == 1) heap_error("insert: Failed to insert."); return; }
static void small_insert_free(malloc_t *heap, int bin, malloc_small_free_t *hdr) { #ifndef DISABLE_HEAP_GUARD if ((hdr->hdr.size_flags & 1) == 1) heap_error("BAD SMALL UNLINK: block is already free hdr=%08X\n", (uintptr_t) hdr); #endif hdr->hdr.size_flags |= 1; /* if we insert in-order, then allocations become best-fit */ hdr->prev = NULL; hdr->next = &heap->free_list[bin]->small; heap->free_list[bin] = (malloc_free_t *) hdr; if (hdr->next != NULL) hdr->next->prev = hdr; }
/* Drain events in the heap. If this operation stalls after exceeding a limit * in the number of events, return non-zero. Zero is success. */ static int esim_drain_heap(void) { int count = 0; struct esim_event_t *event; struct esim_event_info_t *event_info; long long when; /* Extract all elements from heap */ while (1) { /* Extract event */ when = heap_extract(esim_event_heap, (void **) &event); if (heap_error(esim_event_heap)) break; /* Process it */ count++; esim_time = when; event_info = list_get(esim_event_info_list, event->id); assert(event_info && event_info->handler); event_info->handler(event->id, event->data); esim_event_free(event); /* Interrupt heap draining after exceeding a given number of * events. This can happen if the event handlers of processed * events keep scheduling new events, causing the heap to never * finish draining. */ if (count == ESIM_MAX_FINALIZATION_EVENTS) { esim_dump(stderr, 20); warning("%s: number of finalization events exceeds %d - stopped.\n%s", __FUNCTION__, ESIM_MAX_FINALIZATION_EVENTS, esim_err_finalization); return 1; } } /* Success */ return 0; }
static void small_unlink_free(malloc_t *heap, int bin, malloc_small_free_t *hdr) { #ifndef DISABLE_HEAP_GUARD if ((hdr->hdr.size_flags & 1) == 0) heap_error("BAD SMALL UNLINK: block is not free hdr=%08X\n", (uintptr_t) hdr); #endif hdr->hdr.size_flags &= ~1; if (hdr->prev != NULL) hdr->prev->next = hdr->next; if (hdr->next != NULL) hdr->next->prev = hdr->prev; if (&heap->free_list[bin]->small == hdr) heap->free_list[bin] = (malloc_free_t *) hdr->next; #ifndef DISABLE_HEAP_GUARD hdr->prev = NULL; hdr->next = NULL; #endif }