int main() { int arr[MAX] = { 9, 6, 3, 8, 5, 1, 4, 2, 0, 7 }; int i, heap[MAX]; printf("testing insert..."); for (i = 0; i < MAX; i++) { insert(heap, i, arr[i]); if (!check_heap(heap, i+1)) goto fail; } printf("[ok]\n"); printf("testing remove_min..."); for (i = 0; i < MAX; i++) { if (remove_min(heap, MAX - i) != i) goto fail; if (!check_heap(heap, MAX - i - 1)) goto fail; } printf("[ok]\n"); return 0; fail: printf("[failed]\n"); return -1; }
void check_heap(heap* storage, int i, int len) { if(i < 1) { return; } if(2*i <= len) { if(storage->order == ORDER_ASCENDING) { assert(storage->storage[2*i]->metadata.st_mtime <= storage->storage[i]->metadata.st_mtime); check_heap(storage, 2*i, len); } else { assert(storage->storage[2*i]->metadata.st_mtime >= storage->storage[i]->metadata.st_mtime); check_heap(storage, 2*i, len); } } if((2*i + 1) <= len) { if(storage->order == ORDER_ASCENDING) { assert(storage->storage[2*i + 1]->metadata.st_mtime <= storage->storage[i]->metadata.st_mtime); check_heap(storage, 2*i + 1, len); } else { assert(storage->storage[2*i + 1]->metadata.st_mtime >= storage->storage[i]->metadata.st_mtime); check_heap(storage, 2*i + 1, len); } } }
void Camera::callFrameHandlers(const Image &image) { check_heap(); // each frame handeler already checks the heap, may not need this call for (unsigned i = 0; i < m_frameHandlers.size(); i++) m_frameHandlers[i]->processFrame(image); check_heap(); }
TEST(Overflow, NHeapUnderflow) { check_heap(); char* ptr = new char[16]; ptr = ptr - 1; //ASSERT_DEATH({ *ptr = 'q'; check_heap(); //}, ""); }
TEST(Overflow, NoOverflow) { check_heap(); for (int i = 0; i < 27; ++i) { size_t size = 1 << i; void* ptr = malloc(size); check_heap(); free(ptr); check_heap(); } }
void *calloc(size_t p, size_t q) { int x, y; size_t r; /* find a node free that is p*q in size */ r = p * q; #ifdef TRACE_ALLOC lastsize = r; accum += r; printk("calloc %x %x %x ", p, q, accum); fflush(stderr); #endif for (x = 0; x < NODES; x++) { if (heap[x].base != NULL && heap[x].free == 1 && heap[x].len >= r) { break; } } /* if x == NODES we have no node */ if (x == NODES) { #ifdef DEBUG printk("Tried to allocate %lu bytes\n", r); check_heap(); #endif return NULL; } /* now we need a node where base == NULL */ for (y = 0; y < NODES; y++) { if (x != y && heap[y].base == NULL) { break; } } /* no room to split a node, can't allocate mem */ if (y == NODES) { #ifdef DEBUG printk("Tried to allocate %lu bytes\n", r); check_heap(); #endif return NULL; } /* now split node x into two parts of len-r, and r bytes, the former is free, the latter is not */ heap[x].len = heap[x].len - r; heap[y].base = heap[x].base + heap[x].len; heap[y].len = r; heap[y].free = 0; #ifdef TRACE_ALLOC printk("-> %x\n", heap[y].base); lastnum = (int)heap[y].base; #endif return memset(heap[y].base, 0, heap[y].len); }
/* Each thread executes the operations from its own array */ void *dowork(void *threadid) { long id = (long)threadid; int i; char *ptr; struct trace tr = ttrace[id]; int ops = tr.num_ops; for (i = 0; i < ops; i++) { switch(tr.ops[i].type) { case MALLOC: debug_print("thread%li: malloc block %d (size %d)\n", id, tr.ops[i].index, tr.ops[i].size); tr.blocks[tr.ops[i].index] = mymalloc(tr.ops[i].size); if (!tr.blocks[tr.ops[i].index]) { fprintf(stderr, "Error: Thread %li failed on allocation %i.\n", id, i); } check_heap(); break; case FREE: debug_print("thread%li: free block %d\n", id, tr.ops[i].index); ptr = tr.blocks[tr.ops[i].index]; if(myfree(ptr)) { fprintf(stderr, "Error: Thread%li failed on free (block %d).\n", id, i); } break; default: fprintf(stderr, "Error: bad instruction\n"); exit(1); } } pthread_exit(NULL); }
static void heapify(struct ptr_heap *heap, size_t i) { void **ptrs = heap->ptrs; size_t l, r, largest; for (;;) { void *tmp; l = left(i); r = right(i); if (l < heap->len && heap->gt(ptrs[l], ptrs[i])) largest = l; else largest = i; if (r < heap->len && heap->gt(ptrs[r], ptrs[largest])) largest = r; if (unlikely(largest == i)) break; tmp = ptrs[i]; ptrs[i] = ptrs[largest]; ptrs[largest] = tmp; i = largest; } check_heap(heap); }
void test2() { heap_t *heap = create_heap( compare_heap_uint8, default_heap_size ); uint8_t val1 = 100; uint8_t val2 = 22; push_to_heap( heap, &val1 ); push_to_heap( heap, &val2 ); uint8_t *ptr = pop_from_heap( heap ); if ( *ptr != val2 ) { printf( "Failed. (%d != %d) \n", *ptr, val2 ); abort(); } ptr = pop_from_heap( heap ); if ( *ptr != val1 ) { printf( "Failed. (%d != %d) \n", *ptr, val1 ); abort(); } if ( check_heap( heap ) ) { printf( "%s : Success.\n", __func__ ); } else { printf( "%s : Failed.\n", __func__ ); abort(); } }
void heapify(heap* storage, int i) { check_heap(storage, 1, i); if(i <= 1) { return; } info* first = storage->storage[1]; storage->storage[1] = storage->storage[i]; storage->storage[i] = first; for(int pos = 1; 2*pos < i;) { int new_pos = pos*2; if(storage->order == ORDER_ASCENDING) { // if parent node is smaller than one of its child nodes, // then swap parent node with the bigger one of the child nodes if(storage->storage[new_pos]->metadata.st_mtime > storage->storage[pos]->metadata.st_mtime || ((new_pos + 1) < i && storage->storage[new_pos + 1]->metadata.st_mtime > storage->storage[pos]->metadata.st_mtime)) { if((new_pos + 1) < i && storage->storage[new_pos + 1]->metadata.st_mtime > storage->storage[new_pos]->metadata.st_mtime) { new_pos++; } info* swap = storage->storage[new_pos]; storage->storage[new_pos] = storage->storage[pos]; storage->storage[pos] = swap; } else { break; } } else { // if parent node is bigger than one of its child nodes, // then swap parent node with the smaller one of the child nodes if(storage->storage[new_pos]->metadata.st_mtime < storage->storage[pos]->metadata.st_mtime || ((new_pos + 1) < i && storage->storage[new_pos + 1]->metadata.st_mtime < storage->storage[pos]->metadata.st_mtime)) { if((new_pos + 1) < i && storage->storage[new_pos + 1]->metadata.st_mtime < storage->storage[new_pos]->metadata.st_mtime) { new_pos++; } info* swap = storage->storage[new_pos]; storage->storage[new_pos] = storage->storage[pos]; storage->storage[pos] = swap; } else { break; } } pos = new_pos; } heapify(storage, i - 1); }
void run() { while (1) { check_heap(); for (int i= 0; i < 1000; i++) { void *buf = malloc(i*10); memset(buf, 0, i*10); free(buf); } } }
static void test_heap_randomized(void *ptr) { struct min_heap heap; struct event *inserted[1024]; struct event *e, *last_e; int i; min_heap_ctor_(&heap); for (i = 0; i < 1024; ++i) { inserted[i] = malloc(sizeof(struct event)); assert(inserted[i] != NULL); set_random_timeout(inserted[i]); min_heap_push_(&heap, inserted[i]); } check_heap(&heap); tt_assert(min_heap_size_(&heap) == 1024); for (i = 0; i < 512; ++i) { min_heap_erase_(&heap, inserted[i]); if (0 == (i % 32)) check_heap(&heap); } tt_assert(min_heap_size_(&heap) == 512); last_e = min_heap_pop_(&heap); while (1) { e = min_heap_pop_(&heap); if (!e) break; tt_want(evutil_timercmp(&last_e->ev_timeout, &e->ev_timeout, <=)); } tt_assert(min_heap_size_(&heap) == 0); end: for (i = 0; i < 1024; ++i) free(inserted[i]); min_heap_dtor_(&heap); }
// Returns 0 if no errors were found, otherwise returns the error int mm_checkheap(int verbose) { void *bp = (void *)(heap_listp+1); int flag=0; if (verbose) printf("Heap (%p):\n", heap_listp); flag=check_heap(1)|check_free_list(1); print_heap(bp); print_list(num); if(flag) return 1; return 0; }
void *bt_heap_replace_max(struct ptr_heap *heap, void *p) { void *res; if (unlikely(!heap->len)) { (void) heap_set_len(heap, 1); heap->ptrs[0] = p; check_heap(heap); return NULL; } /* Replace the current max and heapify */ res = heap->ptrs[0]; heap->ptrs[0] = p; heapify(heap, 0); return res; }
int bt_heap_insert(struct ptr_heap *heap, void *p) { void **ptrs; size_t pos; int ret; ret = heap_set_len(heap, heap->len + 1); if (unlikely(ret)) return ret; ptrs = heap->ptrs; pos = heap->len - 1; while (pos > 0 && heap->gt(p, ptrs[parent(pos)])) { /* Move parent down until we find the right spot */ ptrs[pos] = ptrs[parent(pos)]; pos = parent(pos); } ptrs[pos] = p; check_heap(heap); return 0; }
void *bt_heap_cherrypick(struct ptr_heap *heap, void *p) { size_t pos, len = heap->len; for (pos = 0; pos < len; pos++) if (unlikely(heap->ptrs[pos] == p)) goto found; return NULL; found: if (unlikely(heap->len == 1)) { (void) heap_set_len(heap, 0); check_heap(heap); return heap->ptrs[0]; } /* Replace p with previous last entry and heapify. */ heap_set_len(heap, heap->len - 1); /* len changed. previous last entry is at heap->len */ heap->ptrs[pos] = heap->ptrs[heap->len]; heapify(heap, pos); return p; }
int main() { int i; Heap h; struct Node nodes[15] = { { 14, NULL, NULL, NULL }, { 2, NULL, NULL, NULL }, { 6, NULL, NULL, NULL }, { 4, NULL, NULL, NULL }, { 12, NULL, NULL, NULL }, { 5, NULL, NULL, NULL }, { 11, NULL, NULL, NULL }, { 8, NULL, NULL, NULL }, { 9, NULL, NULL, NULL }, { 10, NULL, NULL, NULL }, { 13, NULL, NULL, NULL }, { 3, NULL, NULL, NULL }, { 7, NULL, NULL, NULL }, { 15, NULL, NULL, NULL }, { 1, NULL, NULL, NULL }, }; printf("testing insert...\n"); for (i = 0; i < 15; i++) { h.insert(&nodes[i]); if (!check_heap(h.get_root(), i+1)) goto fail; } printf("[ok]\n"); return 0; fail: printf("[failed]\n"); return -1; }
void test4() { heap_t *heap = create_heap( compare_heap_node, default_heap_size ); srandom(100); for ( int i = 0; i < 1000; i++ ) { node_t *node = ( node_t * )malloc( sizeof( node_t ) ); node->datapath_id = ( uint64_t )random(); push_to_heap( heap, node ); } #if 0 if ( check_heap( heap ) ) { printf( "Success.\n" ); } else { printf( "Failed.\n" ); abort(); } #endif uint64_t prev = 0; for ( int i = 0; i < 1000; i++ ) { node_t *node = pop_from_heap( heap ); printf( "%ld\n", node->datapath_id ); if ( prev > node->datapath_id ) { printf( "Failed.\n" ); abort(); } prev = node->datapath_id; free( node ); } return; }
void test3() { heap_t *heap = create_heap( compare_heap_uint8, default_heap_size ); srandom(100); for ( unsigned int i = 0; i < default_heap_size; i++ ) { uint8_t *val = ( uint8_t * )malloc( sizeof( uint8_t ) ); *val = ( uint8_t )( random() % UCHAR_MAX ); push_to_heap( heap, val ); } #if 0 if ( check_heap( heap ) ) { printf( "%s : Success.\n", __func__ ); } else { printf( "%s : Failed.\n", __func__ ); abort(); } #endif uint8_t prev = 0; for ( unsigned int i = 0; i < default_heap_size; i++ ) { uint8_t *val = pop_from_heap( heap ); printf( "%d\n", *val ); if ( prev > *val ) { printf( "Failed.\n" ); abort(); } prev = *val; free( val ); } return; }
void heapclean_agegroup0 (Task* task, Val** roots) { // =================== // // Do "garbage collection" on just agegroup0. // // 'roots' is a vector of live pointers into agegroup0, // harvested from the live register set, global variables // into the heap maintained by C code, etc. // // This fun is called (only) from: // // src/c/heapcleaner/call-heapcleaner.c // // NB: If we have multiple hostthreads running, // each has its own agegroup0, but we process // all of those during this call, by virtue // of being passed all the roots from all the // running hostthreads. Heap* heap = task->heap; Agegroup* age1 = heap->agegroup[0]; Vunt age1_tospace_top [ MAX_PLAIN_SIBS ]; // // Heapcleaner statistics support: We use this to note the // current start-of-freespace in each generation-one sib buffer. // At the bottom of this fn, the difference between this and // the new start-of-freespace gives us the amount of live stuff // we've copied into that sib. This is pure reportage; // our algorithms do not depend in any way on this information. long bytes_allocated = agegroup0_usedspace_in_bytes( task ); // INCREASE_BIGCOUNTER( &heap->total_bytes_allocated, bytes_allocated ); // // More heapcleaner statistics reportage. for (int i = 0; i < MAX_PLAIN_SIBS; i++) { // age1_tospace_top[i] = (Vunt) age1->sib[ i ]->tospace.first_free; } static int callcount = 0; ++callcount; #ifdef VERBOSE if (! (callcount & 0xf)) { // log_if ("Agegroup 1 before cleaning agegroup0: (call %d) -- heapclean-agegroup0.c", callcount); // for (int i = 0; i < MAX_PLAIN_SIBS; i++) { // log_if(" %s: to-space bottom = %#x, end of fromspace oldstuff = %#x, tospace.first_free = %#x", // sib_name__global[ i+1 ], // age1->sib[ i ]->tospace, age1->sib[ i ]->fromspace.seniorchunks_end, age1->sib[ i ]->tospace.first_free ); } } #endif // Scan the standard roots. These are pointers // to live data harvested from the live registers, // C globals etc, so all agegroup0 records pointed // to by them are definitely "live" (nongarbage): // { Sibid* b2s = book_to_sibid__global; // Cache global locally for speed. book_to_sibid__global def in src/c/heapcleaner/heapcleaner-initialization.c Val* rp; while ((rp = *roots++) != NULL) { // forward_to_agegroup1_if_in_agegroup0( b2s, age1, rp, task ); } } // The changelog records all writes to refcells or rw_vectors containing pointer data, // because such writes might introduce cross-generation pointers that we need to know // Scan the changelog -- if there are any new // about when doing partial heapcleanings. This makes each such write cost one CONS cell. // pointers into agegroup0 from other agegroups // // we need to know about them now: // Updates to tagged-integer values refcells or rw_vectors cannot introduce such pointers, // // so we do not track them in the changelog and they suffer no slowdown. // { for (int i = 0; i < MAX_HOSTTHREADS; i++) { // Potentially need to process one heap storelog per hostthread. // Hostthread* hostthread = hostthread_table__global[ i ]; // Task* task = hostthread->task; // if (hostthread->mode != HOSTTHREAD_IS_VOID) { // process_task_heap_changelog( task, heap ); } } } copy_all_remaining_reachable_values_in_agegroup0_to_agegroup1( age1, task ); ++heap->agegroup0_heapcleanings_count; null_out_newly_dead_weakrefs( heap ); // null_out_newly_dead_weakrefs def in src/c/heapcleaner/heapcleaner-stuff.c //////////////////////////////////////////////////////////// // At this point there is nothing left in the agegroup0 // buffer(s) that we care about, so we're done. Our caller // will reset the agegroup0 buffer(s) to empty and resume // allocating linearly in it/them from start to end. //////////////////////////////////////////////////////////// #ifdef VERBOSE if (! (callcount & 0xf)) { log_if ("Agegroup 1 after minorgc: (call %d) -- heapclean-agegroup0.c", callcount); for (int i = 0; i < MAX_PLAIN_SIBS; i++) { log_if (" %s: base = %#x, oldTop = %%#x, tospace.first_free = %#x", sib_name__global[i+1], age1->sib[i]->tospace, /* age1->sib[i]->oldTop, */ age1->sib[i]->tospace.first_free); } } #endif // Cleaner statistics stuff: { long bytes_copied = 0; for (int i = 0; i < MAX_PLAIN_SIBS; i++) { // int bytes = (Vunt) age1->sib[ i ]->tospace.first_free - age1_tospace_top[ i ]; bytes_copied += bytes; INCREASE_BIGCOUNTER( &heap->total_bytes_copied_to_sib[ 0 ][ i ], bytes ); } total_bytes_allocated__global += bytes_allocated; // Never used otherwise. total_bytes_copied__global += bytes_copied; // Never used otherwise. #ifndef VERBOSE if (! (callcount & 0xff)) { log_if ("DONE minorgc #%d: %d/%d (%5.2f%%) bytes copied; %%d updates (callcount %d) -- heapclean-agegroup0.c", callcount, bytes_copied, bytes_allocated, (bytes_allocated ? (double)(100*bytes_copied)/(double)bytes_allocated : 0.0) /* update_count__global - nUpdates */); } #endif } #ifdef CHECK_HEAP check_heap( heap, 1 ); // check_heap def in src/c/heapcleaner/check-heap.c #endif } // fun heapclean_agegroup0
int add(heap* storage, info* element) { int pos; if((storage->elem_count + 1) > storage->max_len) { check_heap(storage, 1, storage->elem_count); int last_pos = 0; // index to smallest (or biggest) element time_t last_time = element->metadata.st_mtime; for(int i = 1; i <= storage->elem_count; i++) { if(storage->order == ORDER_ASCENDING) { if(storage->storage[i]->metadata.st_mtime <= last_time) { last_pos = i; last_time = storage->storage[i]->metadata.st_mtime; } } else { if(storage->storage[i]->metadata.st_mtime >= last_time) { last_pos = i; last_time = storage->storage[i]->metadata.st_mtime; } } } if(last_pos == 0) { return 1; } pos = last_pos; } else { if(++(storage->elem_count) >= storage->len) { storage->len = (2*storage->len > storage->max_len) ? storage->max_len : 2*storage->len; info** new_storage = realloc(storage->storage, storage->len * sizeof(info*)); if(new_storage == NULL) { free(storage->storage); return 0; } storage->storage = new_storage; } pos = storage->elem_count; } for(; pos > 1; pos /= 2) { if(storage->order == ORDER_ASCENDING) { if(storage->storage[pos/2]->metadata.st_mtime < element->metadata.st_mtime) { storage->storage[pos] = storage->storage[pos/2]; } else { break; } } else { if(storage->storage[pos/2]->metadata.st_mtime > element->metadata.st_mtime) { storage->storage[pos] = storage->storage[pos/2]; } else { break; } } } storage->storage[pos] = element; check_heap(storage, 1, storage->elem_count); return 1; }
void MicrodiaCamera::backgroundLoop() { check_heap(); int len; int imgSize = width() * height(); int buffer_size = imgSize * 3; unsigned char buffer[buffer_size]; Image image(height(), width()); int consecutive_readerrs=0; bool external_camera_in_use; int external_camera_file; while (1) { check_heap(); external_camera_in_use = access( EXTERNAL_CAMERA_BUFFER, F_OK ) != -1; if( external_camera_in_use ) { // external camera buffer is in use // Wait for frame to be ready while(! (access(EXTERNAL_CAMERA_READY, F_OK) != -1) ) { // Check if the external camera has been disabled external_camera_in_use = access( EXTERNAL_CAMERA_BUFFER, R_OK ) != -1; if(! external_camera_in_use) break; } // If external camera is now disabled, go back to the beginning if(! external_camera_in_use) continue; // a new frame is ready for reading // open file external_camera_file = open(EXTERNAL_CAMERA_BUFFER, O_RDONLY); len = read(external_camera_file, buffer, buffer_size); // read in the image from the file // close file close(external_camera_file); // don't use this frame again remove(EXTERNAL_CAMERA_READY); } else { // use Microdia camera len = read(m_camDevice, buffer, buffer_size); // read in the image from the camera } if (len == -1) { // check for errors if (consecutive_readerrs >= 10) { //printf("%d consecutive read errors: try to reopen camera\n",consecutive_readerrs); // Break from loop and try to reopen camera closeCamera(); openCamera(); consecutive_readerrs=0; //break; } consecutive_readerrs++; QThread::yieldCurrentThread(); continue; } consecutive_readerrs=0; if (len != buffer_size){ printf("Error reading from camera: expected %d bytes, got %d bytes\n", buffer_size, len); continue; } check_heap(); Pixel565 *out = image.scanLine(0); // Copy to image unsigned char *in = buffer; for (int i = imgSize; i > 0; i--) { *(out++) = Pixel565::fromRGB8(in[2], in[1], in[0]); in += 3; } check_heap(); callFrameHandlers(image); if(m_processOneFrame || !m_processContinuousFrames){ m_processOneFrame = false; break; } } }
TEST(Overflow, NHeapOverflow) { check_heap(); char* ptr = new char[16]; ptr[16] = 'q'; check_heap(); }