static int priq_request_ifclassq(struct ifclassq *ifq, cqrq_t req, void *arg) { struct priq_if *pif = (struct priq_if *)ifq->ifcq_disc; int err = 0; IFCQ_LOCK_ASSERT_HELD(ifq); switch (req) { case CLASSQRQ_PURGE: priq_purge(pif); break; case CLASSQRQ_PURGE_SC: priq_purge_sc(pif, (cqrq_purge_sc_t *)arg); break; case CLASSQRQ_EVENT: priq_event(pif, (cqev_t)arg); break; case CLASSQRQ_THROTTLE: err = priq_throttle(pif, (cqrq_throttle_t *)arg); break; case CLASSQRQ_STAT_SC: err = priq_stat_sc(pif, (cqrq_stat_sc_t *)arg); break; } return (err); }
/* this is O(n log n), but probably not the best */ void priq_combine(pri_queue q, pri_queue q2) { int i; q_elem_t *e = q2->buf + 1; for (i = q2->n - 1; i >= 1; i--, e++) priq_push(q, e->data, e->pri); priq_purge(q2); }
/** * Shortest Path solution implemented using the Dijkstra algorithm */ int dijkstra(Graph *graph, int source, pri_queue priq, Energy *distance, int previous[], Energy shortest_distance) { int vertex, adjacent, v; Energy alt; int *visited = calloc(graph->list_size, sizeof(int)); for(v = 0; v < graph->list_size; distance[v++] = ENERGY_MAX); previous[source] = NONE; distance[source] = graph->vertexes[source].pixel->energy; visited[source] = 1; priq_purge(priq); priq_push(priq, source, distance[source]); int dest = NONE; while(priq_size(priq)) { vertex = priq_pop(priq); v = 0; adjacent = graph->vertexes[vertex].adj[v++]; if(adjacent == NONE) { dest = vertex; break; } #ifdef OPT_GRAPH_SHORTEST_PATH_BREAK else if (distance[vertex] >= shortest_distance) { dest = BREAK; break; } #endif do { if(adjacent >= 0 && !visited[adjacent]) { alt = distance[vertex] + graph->vertexes[adjacent].pixel->energy; if(alt < distance[adjacent]) { distance[adjacent] = alt; previous[adjacent] = vertex; priq_push(priq, adjacent, alt); } } adjacent = graph->vertexes[vertex].adj[v++]; } while(adjacent != NONE); visited[vertex] = 1; } free(visited); return dest; }
static int priq_request(struct ifaltq *ifq, int req, void *arg) { struct priq_if *pif = (struct priq_if *)ifq->altq_disc; switch (req) { case ALTRQ_PURGE: priq_purge(pif); break; } return (0); }
static int altq_priq_request(struct ifaltq *altq, enum altrq req, void *arg) { struct priq_if *pif = (struct priq_if *)altq->altq_disc; switch (req) { case ALTRQ_PURGE: priq_purge(pif); break; case ALTRQ_PURGE_SC: case ALTRQ_THROTTLE: /* not supported for ALTQ instance */ break; case ALTRQ_EVENT: priq_event(pif, (cqev_t)arg); break; } return (0); }
static int priq_request(struct ifaltq_subque *ifsq, int req, void *arg) { struct ifaltq *ifq = ifsq->ifsq_altq; struct priq_if *pif = (struct priq_if *)ifq->altq_disc; crit_enter(); switch (req) { case ALTRQ_PURGE: if (ifsq_get_index(ifsq) == PRIQ_SUBQ_INDEX) { priq_purge(pif); } else { /* * Race happened, the unrelated subqueue was * picked during the packet scheduler transition. */ ifsq_classic_request(ifsq, ALTRQ_PURGE, NULL); } break; } crit_exit(); return (0); }