int find_closest_on_hm_with_path(struct t_map* map, uint8_t sx, uint8_t sy, uint8_t* heatmap, uint8_t* viewarr, uint8_t* o_x, uint8_t* o_y) { uint16_t temp_patharr [ HEATMAP_SIZE ]; memset(temp_patharr, 255, sizeof temp_patharr); temp_patharr [sy * MAP_WIDTH + sx] = 0; struct pqueue_t* pq = pq_create(); pq_push(pq, (void*)((size_t)sy * MAP_WIDTH + sx + 1),0); // create a queue, set the source area to zero. //assumes the rest is already filled with 0xFFFF while (pq_size(pq)) { // while not empty int yx = (int)(size_t)(pq_pop(pq,NULL)) - 1; int x = (yx % MAP_WIDTH); int y = (yx / MAP_WIDTH); if (heatmap[yx]) { pq_destroy(pq); *o_y = y; *o_x = x; return 0; } int dir=0; //x and y now contain element with lowest priority for (dir=0; dir < MD_COUNT; dir++) { // for all neighbors int nx = x + movediff[dir][0]; int ny = y + movediff[dir][1]; if (!vtile(nx,ny)) continue; //this should be a valid tile! int cost = getcost(map,NULL,nx,ny,viewarr); if (cost == -1) continue; if (dir % 2) { cost = (cost * 3) / 2; } int alt = temp_patharr[y * MAP_WIDTH + x] + cost; if (alt < temp_patharr[ny * MAP_WIDTH + nx]) { temp_patharr[ny * MAP_WIDTH + nx] = alt; pq_push (pq, (void*) (ny * MAP_WIDTH + nx + 1), alt); } } } pq_destroy(pq); *o_x = 255; *o_y = 255; return 0; }
int main() { PQ_PTR pq = pq_create(10, 0); pq_insert(pq, 0, 5); pq_insert(pq, 1, 10); pq_insert(pq, 2, -3); pq_insert(pq, 3, 2); pq_insert(pq, 4, 20); pq_insert(pq, 5, -80); pq_insert(pq, 6, -40); pq_insert(pq, 7, 33); pq_insert(pq, 8, 120); pq_insert(pq, 9, 7); printf("size of queue: %d\n", pq_size(pq)); double p; int id; pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_remove_by_id(pq, 2); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_delete_top(pq, &id, &p); printf("first in queue: %d, %f\n", id, p); pq_free(pq); return 0; }
/** * lists processes in the form [Q ... ] * dirty function */ void list_proc(priority_queue pq) { printf("[Q"); int i, sz = pq_size(pq); process *procs[sz]; int pris[sz]; for(i = 0; i < sz; ++i) { procs[i] = pq_pop(pq, &pris[i]); printf(" %c", procs[i]->num); } for(i = 0; i < sz; ++i) pq_push(pq, procs[i], pris[i]); printf("]\n"); }
/** * rr simulation */ void s_rr(priority_queue q, v_memory vm, int num, int cs_t, float *a_wait_t, int *total_cs, int *total_t, int *total_d, int t_memmove, int t_slice) { int cur_t = 0; // current time int cur_cs_t = cs_t + 1; // current context switch time (-1 when not switching) int cur_s_t = 0; // current time-slice time int in_use = 0; // boolean for processor usage int procs_t[num]; // processor countdowns process *procs[num]; // processes in use process *tmp; // process to pop from waiting queue int active; // active processor in use int pri = 0; // rr priority (fcfs) char *algo; // fitting algorithm priority_queue pq; // processes queue // zero arrays int i; for(i = 0; i < num; ++i) { procs_t[i] = 0; procs[i] = 0; } // initialize stuff pq = pq_new(0); // print vm algorithm switch(vm.algo) { case 'f': algo = "First-Fit"; break; case 'n': algo = "Next-Fit"; break; case 'b': algo = "Best-Fit"; break; default: break; } printf("time 0ms: Simulator started for RR (t_slice %d) and %s\n", t_slice, algo); while(1) { // check process arrival times tmp = NULL; while(tmp == NULL) { tmp = pq_peek(q, NULL); if(tmp && tmp->a_t == cur_t) { int rc; // add process to system tmp = pq_pop(q, NULL); pq_push(pq, tmp, ++pri); rc = vm_add(&vm, *tmp); if(rc != 1) { // (defrag) event_call("", cur_t, tmp->num, 'a', NULL); event_call("", cur_t, 0, 'b', NULL); event_call("", cur_t, 0, '9', NULL); vm_print(vm); *total_d += vm_defrag(&vm, 10); event_call("", cur_t, 0, 'c', NULL); event_call("", cur_t, 0, '9', NULL); vm_print(vm); vm_add(&vm, *tmp); } // print event_call("", cur_t, tmp->num, '8', pq); event_call("", cur_t, 0, '9', NULL); vm_print(vm); tmp = NULL; } else { tmp = NULL; break; } } // switching context if(cur_cs_t > 0) --cur_cs_t; // switched context if(cur_cs_t == 0) { --cur_cs_t; // check if open process available and run it if possible if((pq_size(pq) != 0) && !in_use) { int procs_u = 0; while(procs[procs_u] != 0) ++procs_u; // get next open index in_use = 1; procs[procs_u] = pq_pop(pq, NULL); // pop the next open process change_status(procs[procs_u], 1); // set status to using cpu procs_t[procs_u] = procs[procs_u]->b_t + 1; // start process timer cur_s_t = t_slice + 1; // start t_slice timer if(procs[procs_u]->cur_t > 0) procs_t[procs_u] = procs[procs_u]->cur_t; active = procs_u; --procs[procs_u]->b_n; event_call("", cur_t, procs[procs_u]->num, '1', pq); } } // process timers for(i = 0; i < num; ++i) { if(procs[i] != 0) { // check timers if(procs_t[i] > 0) { --procs_t[i]; if(cur_s_t > 0) --cur_s_t; // handle timers if(procs_t[i] == 0) { // completed cpu burst if(procs[i]->status == 1) { change_status(procs[i], 2); procs_t[i] = procs[i]->io_t; if(procs[i]->cur_t > 0) procs[i]->cur_t = 0; // reset cur_t in_use = 0; cur_cs_t = cs_t; ++*total_cs; // if process does not require i/o if(procs_t[i] == 0) { if(procs[i]->b_n <= 0) { vm_del(&vm, procs[i]->num); event_call("", cur_t, procs[i]->num, '5', pq); event_call("", cur_t, procs[i]->num, 'd', NULL); event_call("", cur_t, procs[i]->num, '9', NULL); vm_print(vm); change_status(procs[i], 3); // terminate } else { change_status(procs[i], 0); pq_push(pq, procs[i], ++pri); event_call("", cur_t, procs[i]->num, '2', pq); procs[i] = 0; } } else { if(procs[i]->b_n != 0) { event_call("", cur_t, procs[i]->num, '2', pq); event_call("", cur_t, procs[i]->num, '3', pq); } // terminate process else { procs_t[i] = 0; change_status(procs[i], 3); vm_del(&vm, procs[i]->num); event_call("", cur_t, procs[i]->num, '5', pq); event_call("", cur_t, procs[i]->num, 'd', NULL); event_call("", cur_t, procs[i]->num, '9', NULL); vm_print(vm); } } } // completed i/o else if(procs[i]->status == 2) { change_status(procs[i], 0); if(!in_use) cur_cs_t = cs_t; // finished burst if(procs[i]->b_n <= 0) { // terminate on last burst if(pq_size(pq) != 0) { vm_del(&vm, procs[i]->num); event_call("", cur_t, procs[i]->num, '5', pq); event_call("", cur_t, procs[i]->num, 'd', NULL); event_call("", cur_t, procs[i]->num, '9', NULL); vm_print(vm); } change_status(procs[i], 3); } else { pq_push(pq, procs[i], ++pri); event_call("", cur_t, procs[i]->num, '4', pq); procs[i] = 0; } } } // check time slice expiration else if(cur_s_t == 0 && procs[i]->status == 1) { if(pq_size(pq) != 0) { procs[active]->cur_t = procs_t[active]; // store the current processing time ++procs[active]->b_n; // restore burst number since it hasnt finished change_status(procs[active], 0); // reset status pq_push(pq, procs[active], ++pri); // push back into queue preempt_call(cur_t, procs[active]->num, '0', pq); // print cur_cs_t = cs_t; // switch contexts ++*total_cs; // void existing processors procs_t[active] = 0; procs[active] = 0; in_use = 0; cur_s_t = -1; } } } } } // get statistics from all processes for(i = 1; i <= pq_size(pq); ++i) { if(((process*)(pq->buf[i].data))->status == 0) { ++*a_wait_t; } } if(pq_size(pq) == 0 && !in_use && done(procs_t, sizeof(procs_t) / sizeof(int))) { *total_t = cur_t; event_call("RR", cur_t, 0, '7', pq); return; } ++cur_t; } }