/* * Called when the infrastructure removes a queue (e.g. flowset * is reconfigured). Nothing to do if we did not 'own' the queue, * otherwise remove it from the right heap and adjust the sum * of weights. */ static int wf2qp_free_queue(struct dn_queue *q, int safe) { struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q; struct wf2qp_si *si = (struct wf2qp_si *)(q->_si + 1); if (alg_fq->S >= alg_fq->F + 1) return 0; /* nothing to do, not in any heap */ /* queue is in a scheduler heap */ if (safe) /* do not delete in safe mode */ return 1; si->wsum -= q->fs->fs.par[0]; if (si->wsum > 0) si->inv_wsum = ONE_FP/si->wsum; /* extract from the heap. XXX TODO we may need to adjust V * to make sure the invariants hold. */ if (q->mq.head == NULL) { heap_extract(&si->idle_heap, q); } else if (DN_KEY_LT(si->V, alg_fq->S)) { heap_extract(&si->ne_heap, q); } else { heap_extract(&si->sch_heap, q); } return 0; }
void outputSorted(const Person people[], int numPeople, int (* compare)(const void *pKey1, const void *pKey2)) { Heap heap; void *data; int i; /* Initialize heap */ heap_init(&heap, compare, NULL); /* Add people to heap */ for (i = 0; i < numPeople; ++i) if (heap_insert(&heap, &people[i]) != 0) fatalError("Failed to insert person into heap"); /* Extract and output people from heap */ while (heap_size(&heap) > 0) { if (heap_extract(&heap, &data) != 0) fatalError("Failed to extract person from heap"); outputPerson((const Person *)data); } /* Destroy heap */ heap_destroy(&heap); }
/* * Primary function for DI APSP. */ void di_apsp(int n, float* dist, float* graph, int* p, int* q, std::vector<int>* L, std::vector<int>* R, std::list<int>* bucket_heap, int* b_num, std::list<int>::iterator* iters) { // Initialize di_init(n, dist, graph, p, q, L, R, bucket_heap, b_num, iters); int u, v, pair; //Main loop while (1) { // Get min (u,v) pair from the heap. // Break the loop if heap was empty. pair = heap_extract(bucket_heap, b_num, n, iters); if (pair < 0) break; u = pair/n; v = pair%n; // Add to relevant lists L[p[u*n + v]*n + v].push_back(u); R[u*n + q[u*n + v]].push_back(v); // Examine through the lists. di_lists(n, u, v, dist, graph, p, q, L, R, bucket_heap, b_num, iters); } }
int * dijkstra(graph g, int from, int*tree, int (*add)(int, int)){ int * somme, i, act;/*Commistione linguistica che bonato ama! xD*/ heap_t *heap; somme = malloc(sizeof(int) * g->v); assert(somme != NULL); /*Piazzo tutto a -1 che in binario è 11111111....1111 ... fino alla nausea... 1111*/ memset(somme, 0xff, g->v * sizeof(int)); /*Good! Ora però la prima va a 0!*/ somme[from] = 0; /*Ci siamo quasi...*/ /*ora le heap!*/ heap = heap_make(somme, g->v, heapcmp, sizeof(int)); /*Metto a TRUE la flag *connected*/ g->connesso = 1; /*Ultimissima cosa: inizializzo l'albero delle visite ad una foresta di alberi di un solo elemento*/ for(i = 0; i < g->v; i++) tree[i] = i; /* Ora il ciclo, prepariamo l'assorbente xD*/ while(!heap_is_empty(heap)){ /* Estraggo il primo elemento*/ from = heap_extract(heap); /* Se la distanza per arrivare è ancora infinita (-1), significa che questa parte del * Grafo non è mai stata raggiunta da nessun arco e quindi è disconnessa dalla componente * In cui è presente il nodo di partenza, e quindi, visto che questo è il massimo possibili * tutti gli altri elementi nella heap avranno lo stesso valore, quindi interrompo qui * l'esecuzione */ if(somme[from] == -1) { g->connesso = 0;/* Segno che il grafo non è connesso*/ /*interrompo il ciclo*/ break; } /*E itero tra tutto */ for(i = 0; i < g->v; i++){ if(g->adj[from][i]){ /*Mi calcolo la distanza attuale + quella dell'arco tramite una funzione esterna*/ act = add(somme[from], g->adj[from][i]); /*Se la somma è a -1 (non è ancora stato aggiornato) oppure il nuovo valore e' inferiore a quello vecchio, lo metto uguale e aggiorno l'albero delle visite*/ if(somme[i] == -1 || somme[i] > act){ somme[i] = act; tree[i] = from; /*Ho aggiornato: devo fare un fix della heap che potrebbe essere andata a farsi fottere!*/ heap_fix(heap, i); } } } } heap_free(heap);/*Questa non mi cancella l'array somme, quindi sono contento xD*/ /*Bene! abbiamo finito! :)*/ return somme; }
void *match_thread(void *thread_args) { long i; float score; heap_t *heap = NULL; thread_args_t *args = (thread_args_t *)thread_args; if (args->limit) { // Reserve one extra slot so that we can do an insert-then-extract even // when "full" (effectively allows use of min-heap to maintain a // top-"limit" list of items). heap = heap_new(args->limit + 1, cmp_score); } for ( i = args->thread_index; i < args->path_count; i += args->thread_count ) { args->matches[i].path = RARRAY_PTR(args->haystacks)[i]; if (args->needle_bitmask == UNSET_BITMASK) { args->matches[i].bitmask = UNSET_BITMASK; } if (!NIL_P(args->last_needle) && args->matches[i].score == 0.0) { // Skip over this candidate because it didn't match last // time and it can't match this time either. continue; } args->matches[i].score = calculate_match( args->matches[i].path, args->needle, args->case_sensitive, args->always_show_dot_files, args->never_show_dot_files, args->recurse, args->needle_bitmask, &args->matches[i].bitmask ); if (args->matches[i].score == 0.0) { continue; } if (heap) { if (heap->count == args->limit) { score = ((match_t *)HEAP_PEEK(heap))->score; if (args->matches[i].score >= score) { heap_insert(heap, &args->matches[i]); (void)heap_extract(heap); } } else { heap_insert(heap, &args->matches[i]); } } } return heap; }
static int wf2qp_enqueue(struct dn_sch_inst *_si, struct dn_queue *q, struct mbuf *m) { struct dn_fsk *fs = q->fs; struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1); struct wf2qp_queue *alg_fq; uint64_t len = m->m_pkthdr.len; if (m != q->mq.head) { if (dn_enqueue(q, m, 0)) /* packet was dropped */ return 1; if (m != q->mq.head) /* queue was already busy */ return 0; } /* If reach this point, queue q was idle */ alg_fq = (struct wf2qp_queue *)q; if (DN_KEY_LT(alg_fq->F, alg_fq->S)) { /* F<S means timestamps are invalid ->brand new queue. */ alg_fq->S = si->V; /* init start time */ si->wsum += fs->fs.par[0]; /* add weight of new queue. */ si->inv_wsum = ONE_FP/si->wsum; } else { /* if it was idle then it was in the idle heap */ heap_extract(&si->idle_heap, q); alg_fq->S = MAX64(alg_fq->F, si->V); /* compute new S */ } alg_fq->F = alg_fq->S + len * alg_fq->inv_w; /* if nothing is backlogged, make sure this flow is eligible */ if (si->ne_heap.elements == 0 && si->sch_heap.elements == 0) si->V = MAX64(alg_fq->S, si->V); /* * Look at eligibility. A flow is not eligibile if S>V (when * this happens, it means that there is some other flow already * scheduled for the same pipe, so the sch_heap cannot be * empty). If the flow is not eligible we just store it in the * ne_heap. Otherwise, we store in the sch_heap. * Note that for all flows in sch_heap (SCH), S_i <= V, * and for all flows in ne_heap (NEH), S_i > V. * So when we need to compute max(V, min(S_i)) forall i in * SCH+NEH, we only need to look into NEH. */ if (DN_KEY_LT(si->V, alg_fq->S)) { /* S>V means flow Not eligible. */ if (si->sch_heap.elements == 0) D("++ ouch! not eligible but empty scheduler!"); heap_insert(&si->ne_heap, alg_fq->S, q); } else { heap_insert(&si->sch_heap, alg_fq->F, q); } return 0; }
/* * This file implements a WF2Q+ scheduler as it has been in dummynet * since 2000. * The scheduler supports per-flow queues and has O(log N) complexity. * * WF2Q+ needs to drain entries from the idle heap so that we * can keep the sum of weights up to date. We can do it whenever * we get a chance, or periodically, or following some other * strategy. The function idle_check() drains at most N elements * from the idle heap. */ static void idle_check(struct wf2qp_si *si, int n, int force) { struct dn_heap *h = &si->idle_heap; while (n-- > 0 && h->elements > 0 && (force || DN_KEY_LT(HEAP_TOP(h)->key, si->V))) { struct dn_queue *q = HEAP_TOP(h)->object; struct wf2qp_queue *alg_fq = (struct wf2qp_queue *)q; heap_extract(h, NULL); /* XXX to let the flowset delete the queue we should * mark it as 'unused' by the scheduler. */ alg_fq->S = alg_fq->F + 1; /* Mark timestamp as invalid. */ si->wsum -= q->fs->fs.par[0]; /* adjust sum of weights */ if (si->wsum > 0) si->inv_wsum = ONE_FP/si->wsum; } }
/* 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; }
int main() { int n, m; scanf("%d%d", &n, &m); edge es[2*m]; for (int i = 0; i < m; i++) { int vi, ui, w; scanf("%d%d%d", &vi, &ui, &w); vertex *v = &vs[vi], *u = &vs[ui]; es[2*i] = (edge){u, w, v->a}; v->a = &es[2*i]; es[2*i+1] = (edge){v, w, u->a}; u->a = &es[2*i+1]; } const int inf = (int)1e9; for (vertex *v = vs; v != vs+n; v++) { v->i = v - vs; v->d = inf; v->b = false; heap_insert(v); } int s; scanf("%d", &s); vs[s]->d = 0; for (int i = 0; i < n; i++) { vertex *v = heap_extract(); v->b = true; for (edge *e = v->a; e != NULL; e = e->n) { vertex *u = e->v; if (!u->b && v->d + e->w < u->d) { u->d = v->d + e->w; heap_decrease(u); } } } return 0; }
int heapsort(int h[], int tam) { int count, veri=0, custo=0; build_heap(h,tam); //somaglobal = 0; if(tam!=0) { while(tam>0) { count = tam; tam = heap_extract(h,count); veri++; if(veri == 2) { tam++; h[tam]+=h[tam+1]; //val_global = h[tam]; custo+=h[tam]; heapify(h,0,tam); veri = 0; } } custo+=(h[tam]+h[tam+1]); } else custo = 0; return custo; }
int main(int argc, char *argv[]) { struct dn_heap h; int i, n, n2, n3; test_hash(); return 0; /* n = elements, n2 = cycles */ n = (argc > 1) ? atoi(argv[1]) : 0; if (n <= 0 || n > 1000000) n = 100; n2 = (argc > 2) ? atoi(argv[2]) : 0; if (n2 <= 0) n = 1000000; n3 = (argc > 3) ? atoi(argv[3]) : 0; bzero(&h, sizeof(h)); heap_init(&h, n, -1); while (n2-- > 0) { uint64_t prevk = 0; for (i=0; i < n; i++) heap_insert(&h, n3 ? n-i: random(), (void *)(100+i)); for (i=0; h.elements > 0; i++) { uint64_t k = h.p[0].key; if (k < prevk) panic("wrong sequence\n"); prevk = k; if (0) printf("%d key %llu, val %p\n", i, h.p[0].key, h.p[0].object); heap_extract(&h, NULL); } } return 0; }
int main(int argc, char **argv) { Heap heap; void *data; int intval[30], i; /***************************************************************************** * * * Initialize the heap. * * * *****************************************************************************/ heap_init(&heap, compare_int, NULL); /***************************************************************************** * * * Perform some heap operations. * * * *****************************************************************************/ i = 0; intval[i] = 5; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 10; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 20; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 1; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 25; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 22; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; intval[i] = 9; fprintf(stdout, "Inserting %03d\n", intval[i]); if (heap_insert(&heap, &intval[i]) != 0) return 1; print_heap(&heap); i++; while (heap_size(&heap) > 0) { if (heap_extract(&heap, (void **) &data) != 0) return 1; fprintf(stdout, "Extracting %03d\n", *(int *) data); print_heap(&heap); } /***************************************************************************** * * * Destroy the heap. * * * *****************************************************************************/ fprintf(stdout, "Destroying the heap\n"); heap_destroy(&heap); return 0; }
Character *turn_dequeue() { return heap_extract(h); }
void evg_compute_unit_free(struct evg_compute_unit_t *compute_unit) { struct heap_t *event_queue; struct evg_uop_t *uop; int i; /* CF Engine - free uops in fetch buffer, instruction buffer, and complete queue */ for (i = 0; i < evg_gpu_max_wavefronts_per_compute_unit; i++) { evg_uop_free(compute_unit->cf_engine.fetch_buffer[i]); evg_uop_free(compute_unit->cf_engine.inst_buffer[i]); } evg_uop_list_free(compute_unit->cf_engine.complete_queue); /* CF Engine - free structures */ free(compute_unit->cf_engine.fetch_buffer); free(compute_unit->cf_engine.inst_buffer); linked_list_free(compute_unit->cf_engine.complete_queue); /* ALU Engine - free uops in event queue (heap) */ event_queue = compute_unit->alu_engine.event_queue; while (heap_count(event_queue)) { heap_extract(event_queue, (void **) &uop); uop->write_subwavefront_count++; if (uop->write_subwavefront_count == uop->subwavefront_count) evg_uop_free(uop); } /* ALU Engine - free uops in fetch queue, instruction buffer, execution buffer, * and event queue. Also free CF instruction currently running. */ evg_uop_list_free(compute_unit->alu_engine.pending_queue); evg_uop_list_free(compute_unit->alu_engine.finished_queue); evg_uop_list_free(compute_unit->alu_engine.fetch_queue); evg_uop_free(compute_unit->alu_engine.inst_buffer); evg_uop_free(compute_unit->alu_engine.exec_buffer); /* ALU Engine - structures */ linked_list_free(compute_unit->alu_engine.pending_queue); linked_list_free(compute_unit->alu_engine.finished_queue); linked_list_free(compute_unit->alu_engine.fetch_queue); heap_free(compute_unit->alu_engine.event_queue); /* TEX Engine - free uop in fetch queue, instruction buffer, write buffer. */ evg_uop_list_free(compute_unit->tex_engine.pending_queue); evg_uop_list_free(compute_unit->tex_engine.finished_queue); evg_uop_list_free(compute_unit->tex_engine.fetch_queue); evg_uop_free(compute_unit->tex_engine.inst_buffer); evg_uop_list_free(compute_unit->tex_engine.load_queue); /* TEX Engine - structures */ linked_list_free(compute_unit->tex_engine.pending_queue); linked_list_free(compute_unit->tex_engine.finished_queue); linked_list_free(compute_unit->tex_engine.fetch_queue); linked_list_free(compute_unit->tex_engine.load_queue); /* Compute unit */ linked_list_free(compute_unit->wavefront_pool); free(compute_unit->work_groups); /* List of mapped work-groups */ mod_free(compute_unit->local_memory); free(compute_unit); }
__inline int pqueue_extract(PQueue queue,ElmtType* data) { return heap_extract(queue, data); }
int main() { // int j; int func; int value; char cmd[1024]; printf("Please input the heap size : "); scanf("%d",&size); printf("\n"); heap = build_heap(size); maxheap(heap); do{ printf("1) Insert 2) Delete 3) Extract max 4) Top Value 5) Print Heap 6)Free:"); for(func = 0; func<=0 || func > 7; sscanf(cmd,"%d",&func)){ scanf("%s",cmd); printf("\n"); } switch(func){ case 1: printf("please input new value for insert:"); scanf("%d ",&value); printf("\n"); heap_insert(heap,value); break; case 2: printf("please input heap-index to delete:"); scanf("%d ",&value); printf("\n"); heap_delete(value); break; case 3: heap_extract(); break; case 4: heap_top(heap); break; case 5: heap_print(); break; case 6: free(heap->array); //free(heap); size = 0; break; } }while(1); return 0; }
/* XXX invariant: sch > 0 || V >= min(S in neh) */ static struct mbuf * wf2qp_dequeue(struct dn_sch_inst *_si) { /* Access scheduler instance private data */ struct wf2qp_si *si = (struct wf2qp_si *)(_si + 1); struct mbuf *m; struct dn_queue *q; struct dn_heap *sch = &si->sch_heap; struct dn_heap *neh = &si->ne_heap; struct wf2qp_queue *alg_fq; if (sch->elements == 0 && neh->elements == 0) { /* we have nothing to do. We could kill the idle heap * altogether and reset V */ idle_check(si, 0x7fffffff, 1); si->V = 0; si->wsum = 0; /* should be set already */ return NULL; /* quick return if nothing to do */ } idle_check(si, 1, 0); /* drain something from the idle heap */ /* make sure at least one element is eligible, bumping V * and moving entries that have become eligible. * We need to repeat the first part twice, before and * after extracting the candidate, or enqueue() will * find the data structure in a wrong state. */ m = NULL; for(;;) { /* * Compute V = max(V, min(S_i)). Remember that all elements * in sch have by definition S_i <= V so if sch is not empty, * V is surely the max and we must not update it. Conversely, * if sch is empty we only need to look at neh. * We don't need to move the queues, as it will be done at the * next enqueue */ if (sch->elements == 0 && neh->elements > 0) { si->V = MAX64(si->V, HEAP_TOP(neh)->key); } while (neh->elements > 0 && DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) { q = HEAP_TOP(neh)->object; alg_fq = (struct wf2qp_queue *)q; heap_extract(neh, NULL); heap_insert(sch, alg_fq->F, q); } if (m) /* pkt found in previous iteration */ break; /* ok we have at least one eligible pkt */ q = HEAP_TOP(sch)->object; alg_fq = (struct wf2qp_queue *)q; m = dn_dequeue(q); heap_extract(sch, NULL); /* Remove queue from heap. */ si->V += (uint64_t)(m->m_pkthdr.len) * si->inv_wsum; alg_fq->S = alg_fq->F; /* Update start time. */ if (q->mq.head == 0) { /* not backlogged any more. */ heap_insert(&si->idle_heap, alg_fq->F, q); } else { /* Still backlogged. */ /* Update F, store in neh or sch */ uint64_t len = q->mq.head->m_pkthdr.len; alg_fq->F += len * alg_fq->inv_w; if (DN_KEY_LEQ(alg_fq->S, si->V)) { heap_insert(sch, alg_fq->F, q); } else { heap_insert(neh, alg_fq->S, q); } } } return m; }
uint64_t pq_extract( rtems_task_argument tid, int key ) { return heap_extract(tid, key); }
/* * The timer handler for dummynet. Time is computed in ticks, but * but the code is tolerant to the actual rate at which this is called. * Once complete, the function reschedules itself for the next tick. */ void dummynet_task(void *context, int pending) { struct timeval t; struct mq q = { NULL, NULL }; /* queue to accumulate results */ CURVNET_SET((struct vnet *)context); DN_BH_WLOCK(); /* Update number of lost(coalesced) ticks. */ tick_lost += pending - 1; getmicrouptime(&t); /* Last tick duration (usec). */ tick_last = (t.tv_sec - dn_cfg.prev_t.tv_sec) * 1000000 + (t.tv_usec - dn_cfg.prev_t.tv_usec); /* Last tick vs standard tick difference (usec). */ tick_delta = (tick_last * hz - 1000000) / hz; /* Accumulated tick difference (usec). */ tick_delta_sum += tick_delta; dn_cfg.prev_t = t; /* * Adjust curr_time if the accumulated tick difference is * greater than the 'standard' tick. Since curr_time should * be monotonically increasing, we do positive adjustments * as required, and throttle curr_time in case of negative * adjustment. */ dn_cfg.curr_time++; if (tick_delta_sum - tick >= 0) { int diff = tick_delta_sum / tick; dn_cfg.curr_time += diff; tick_diff += diff; tick_delta_sum %= tick; tick_adjustment++; } else if (tick_delta_sum + tick <= 0) { dn_cfg.curr_time--; tick_diff--; tick_delta_sum += tick; tick_adjustment++; } /* serve pending events, accumulate in q */ for (;;) { struct dn_id *p; /* generic parameter to handler */ if (dn_cfg.evheap.elements == 0 || DN_KEY_LT(dn_cfg.curr_time, HEAP_TOP(&dn_cfg.evheap)->key)) break; p = HEAP_TOP(&dn_cfg.evheap)->object; heap_extract(&dn_cfg.evheap, NULL); if (p->type == DN_SCH_I) { serve_sched(&q, (struct dn_sch_inst *)p, dn_cfg.curr_time); } else { /* extracted a delay line */ transmit_event(&q, (struct delay_line *)p, dn_cfg.curr_time); } } if (dn_cfg.expire && ++dn_cfg.expire_cycle >= dn_cfg.expire) { dn_cfg.expire_cycle = 0; dn_drain_scheduler(); dn_drain_queue(); } DN_BH_WUNLOCK(); dn_reschedule(); if (q.head != NULL) dummynet_send(q.head); CURVNET_RESTORE(); }