int traverseBFS(Graph graph, int start, Dllist close) { Dllist node, queue; JRB visited; int *output; int temp; int i, n, counter = 0; visited = make_jrb(); queue = new_dllist(); dll_append(queue, new_jval_i(start)); while(!dll_empty(queue)) { node = dll_first(queue); temp = jval_i(node->val); dll_delete_node(node); if(jrb_find_int(visited, temp) == NULL) { counter++; // reportFunc(temp); jrb_insert_int(visited, temp, new_jval_i(temp)); n = outdegree(graph, temp, output); for(i = 0; i < n; i++) { if(jrb_find_int(visited, output[i]) == NULL) { dll_append(queue, new_jval_i(output[i])); } } } } return counter; }
// Finds the smallest available pid // Returns a new pid for a process. int get_new_pid() { int i; Jval pid; current_pid++; // Attempt to find a smaller pid for (i = 1; i <= current_pid; i++) { found_node = jrb_find_int(pid_tree, i); if (found_node == NULL) { current_pid = i; break; } } // Increment pid until one is found while (found_node != NULL) { current_pid++; found_node = jrb_find_int(pid_tree, current_pid); } // Add pid to tree pid.v = (int *)current_pid; jrb_insert_int(pid_tree, current_pid, pid); return current_pid; }
void kt_exit() { JRB tmp; InitKThreadSystem(); /* * unroll stack and escape */ if(Debug & KT_DEBUG) { printf("longjmping to 0x%x exitbuf\n",ktRunning->func); } /* Now, do one of two things. If this is the main (original) thread, you simply want to set its state to dead, and reschedule. You don't want to clean up its stack, because its stack is the main stack. If this is any other thread, then longjmp to its exitbuf. This jumps you down to the bottom of the thread's stack, and the thread will put itself on the ktFree_me list, so that it can be cleaned up */ if (ktRunning == ktOriginal) { ktRunning->state = DEAD; /* Nuke it from ktActive */ tmp = jrb_find_int(ktActive, ktRunning->tid); if (tmp == NULL) { fprintf(stderr, "Panic: Original thread not in ktActive\n"); exit(1); } jrb_delete_node(tmp); /* If there is a thread waiting on me, wake it up */ tmp = jrb_find_int(ktBlocked, ktRunning->tid); if (tmp != NULL) { WakeKThread((K_t)tmp->val.v); } KtSched(); /* This should never return, because this thread will never be rescheduled */ fprintf(stderr, "Error: main thread returned after calling kt_exit()\n"); exit(1); } else { longjmp(ktRunning->exitbuf,1); } }
/* * for self-test */ void PermuteVertices(int *g, int size, int v1, int v2) { JRB v1_a; JRB v2_b; JRB rb; int i; int j; v1_a = make_jrb(); v2_b = make_jrb(); for(i=0; i < size; i++) { for(j=i+1; j < size; j++) { if(i == v1) { rb = jrb_find_int(v1_a,j); if(rb == NULL) { jrb_insert_int(v1_a,j,(Jval)g[i*size+j]); } } if(j == v1) { rb = jrb_find_int(v1_a,i); if(rb == NULL) { jrb_insert_int(v1_a,i,(Jval)g[i*size+j]); } } if(i == v2) { rb = jrb_find_int(v2_b,j); if(rb == NULL) { jrb_insert_int(v2_b,j,(Jval)g[i*size+j]); } } if(j == v2) { rb = jrb_find_int(v2_b,i); if(rb == NULL) { jrb_insert_int(v2_b,i,(Jval)g[i*size+j]); } } } } jrb_traverse(rb,v1_a) { j = rb->key.i; /* * leave edges between swapped nodes alone */ if(j > v2) { g[v2*size+j] = rb->val.i; } else if(j < v2) { g[j*size+v2] = rb->val.i; } }
/* return jrb holding frequency of characters */ JRB makeStatsTree(char *buffer, int size) { // make jrb to count characters JRB stats; JRB found; // result of searching int val; int i; stats = make_jrb(); for(i = 0; i < size; i++){ found = jrb_find_int(stats, buffer[i]); if(!found){ /* if not found, insert buffer[i] to the tree with val as 1 */ jrb_insert_int(stats, buffer[i], ji(1)); }else{ /* if found, increase val of that node by 1 */ val = jval_i(found->val) + 1; found->val = ji(val); } //end if else }// end for return stats; }
void kt_joinall() { K_t me; JRB jb; InitKThreadSystem(); /* Jim: I'm changing semantics. If there is already a joinall thread, flag it as an error */ if(jrb_find_int(ktBlocked,0) != NULL) { fprintf(stderr, "Error: two joinall threads\n"); exit(1); } /* * 0 is the sleep key for joinall */ BlockKThread(ktRunning,0); /* * cause the scheduler to block */ KtSched(); return; }
void kt_kill(void *t) { K_t kt; int tid; JRB tmp; tid = (int) t; tmp = jrb_find_int(ktActive, tid); /* Hell, this might not be right either. If the thread is not in the active tree, then assume it's dead */ if (tmp == NULL) return; kt = (K_t) tmp->val.v; kt->die_now = 1; if((kt->state == BLOCKED) || (kt->state == SLEEPING)) { /* * if I'm blocked on a semaphore and I get killed, * better bump the semaphore count */ if(kt->ks != NULL) { kt->ks->val++; } WakeKThread(kt); } return; }
void kill_kt_sem(kt_sem iks) { Ksem ks = (Ksem)iks; InitKThreadSystem(); /* * if there are threads blocked on this semaphore, panic */ if(jrb_find_int(ktBlocked,ks->sid) != NULL) { if(Debug & KT_DEBUG) { fprintf(stderr, "kill_kt_sem: deletion with waiting threads, val: %d\n", ks->val); fflush(stderr); } exit(1); } free(ks); return; }
int deepFirstSearch(Graph graph, int start, int stop, Dllist close) { Dllist node, stack; JRB visited; int output[100]; int temp; int i, n; visited = make_jrb(); stack = new_dllist(); dll_prepend(stack, new_jval_i(start)); while(!dll_empty(stack)) { node = dll_first(stack); temp = jval_i(node->val); dll_delete_node(node); if(jrb_find_int(visited, temp) == NULL) { // reportFunc(temp); dll_append(close, new_jval_i(temp)); jrb_insert_int(visited, temp, new_jval_i(temp)); if(compare(temp, stop) == 0) { jrb_free_tree(visited); free_dllist(stack); return 1; } n = outdegree(graph, temp, output); for(i = 0; i < n; i++) { if(jrb_find_int(visited, output[i]) == NULL) { dll_prepend(stack, new_jval_i(output[i])); } } } } jrb_free_tree(visited); free_dllist(stack); return 0; }
// Finds and deletes node with given pid // Return 0 on success, else -1 int destroy_pid(int pid) { found_node = jrb_find_int(pid_tree, pid); if (found_node != NULL) { jrb_delete_node(found_node); return 0; } else { return -1; } }
/* * block and wait for the thread (passed as i_join) to complete */ void kt_join(void *i_join) { K_t me; JRB target; int tid; InitKThreadSystem(); tid = (int) i_join; if (tid <= 0) { fprintf(stderr, "kt_join() -- bad argument\n"); exit(1); } /* * see if the thread I want to wait for exists */ target = jrb_find_int(ktActive,tid); /* * if not, we assume that the thread is dead, and simply return. * Unfortunately, that might not be right, but it's the best we * can do without burning too much memory. */ if(target == NULL) return; if (jrb_find_int(ktBlocked, tid) != NULL) { fprintf(stderr, "Called kt_join on a thread twice\n"); exit(1); } BlockKThread(ktRunning,tid); KtSched(); return; }
int UShortestPath(Graph graph, int start, int stop, Dllist close) { Dllist node, queue, stackVisit; JRB visited; int output[100]; int temp; int i, n; visited = make_jrb(); queue = new_dllist(); stackVisit = new_dllist(); dll_append(queue, new_jval_i(start)); while(!dll_empty(queue)) { node = dll_first(queue); temp = jval_i(node->val); dll_delete_node(node); if(jrb_find_int(visited, temp) == NULL) { jrb_insert_int(visited, temp, new_jval_i(temp)); dll_prepend(stackVisit, new_jval_i(temp)); if(temp == stop) { return solution(graph, start, stop, stackVisit, close); } n = outdegree(graph, temp, output); for(i = 0; i < n; i++) { if(jrb_find_int(visited, output[i]) == NULL) { dll_append(queue, new_jval_i(output[i])); } } } } return -1; }
void V_kt_sem(kt_sem iks) { Ksem ks = (Ksem)iks; K_t wake_kt; InitKThreadSystem(); ks->val++; if(ks->val <= 0) { wake_kt = jval_v(jrb_val(jrb_find_int(ktBlocked,ks->sid))); WakeKThread(wake_kt); } return; }
Elevator *get_elevator(int id, JRB elevators) { Elevator *e; JRB tmp; tmp = jrb_find_int(elevators, id); if (tmp != NULL) return (Elevator *) tmp->val.v; e = talloc(Elevator, 1); e->time = 0; e->id = id; e->door = 0; e->floor = 1; e->state = 'R'; jrb_insert_int(elevators, id, new_jval_v((void *) e)); return e; }
void process_files(Dllist dir_list, JRB inode, JRB paths, char *name, JRB links){ int dup_inode, dup_path; char buf[PATH_MAX+1]; tar *t; dup_inode = 1; dup_path = 1; t = (tar*) malloc(sizeof(tar)); strcpy(t->name,realpath(name, buf)); if(lstat(t->name, &t->istat) < 0){ fprintf(stderr,"ERROR: %s No such file or directory\n",t->name); exit(1); } if(jrb_find_str(paths,realpath(t->name,buf)) != NULL){ //my problem could be here dup_path = 0; jrb_insert_str(links,strdup(name), new_jval_v(jrb_find_str(paths,realpath(t->name,buf)))); // printf("Ignoring Duplicate %s\n",t->name); } if(jrb_find_int(inode, t->istat.st_ino) != NULL){ dup_inode = 0; // jrb_insert_str(links,strdup(t->name), // new_jval_v(jrb_find_str(paths,realpath(t->name,buf)))); // printf("Ignoring Duplicate %s\n",t->name); } if(dup_path && dup_inode) { jrb_insert_str(paths,strdup(realpath(t->name,buf)),new_jval_v(t)); jrb_insert_int(inode,(int)t->istat.st_ino,new_jval_v(t)); } if(S_ISDIR(t->istat.st_mode)){ trav_dir(dir_list, inode, paths, name); } }
main() { JRB level_1, level_2; JRB bn, bn2; IS is; is = new_inputstruct(NULL); level_1 = make_jrb(); while (get_line(is) >= 0) { bn = jrb_find_int(level_1, atoi(is->text1)); if (bn == NULL) { bn = jrb_insert_int(level_1, atoi(is->text1), new_jval_v((void *)make_jrb())); } level_2 = (JRB ) jval_v(bn->val); jrb_insert_str(level_2, strdup(is->text1), new_jval_v(NULL)); } jrb_traverse(bn, level_1) { level_2 = (JRB ) jval_v(bn->val); jrb_traverse(bn2, level_2) { printf("%s", bn2->key.s); }
void KtSched() { K_t kt; JRB jb; unsigned int sp; unsigned int now; JRB tmp; Dllist dtmp; /* * start by recording the current stack contents in case * I'm descheduled * * this is where I return to when I'm rescheduled */ if(setjmp(ktRunning->jmpbuf) != 0) { FreeFinishedThreads(); /* * if we are being killed by another thread, jump through * the exitbuf */ if(ktRunning->die_now) { /* Jim: This used to longjmp to the exitbuf, but I changed it for two reasons: 1. It wasn't being removed from ktActive 2. Hell will be paid if it is ktOriginal. I believe kt_exit() is cleaner. I have not tested it. I should. */ kt_exit(); /* not reached */ } return; } start: if (!jrb_empty(ktSleeping)) { now = time(0); while(!jrb_empty(ktSleeping)) { kt = (K_t) jval_v(jrb_val(jrb_first(ktSleeping))); if(kt->wake_time > now) { break; } WakeKThread(kt); } } /* * if there is nothing left to run, exit. However, if there * are sleepers or a joinall, deal with them appropriately */ if(dll_empty(ktRunnable)) { /* * first, check for sleepers and deal with them */ if(!jrb_empty(ktSleeping)) { kt = jval_v(jrb_val(jrb_first(ktSleeping))); sleep(kt->wake_time - now); goto start; } /* * next, see if there is a joinall thread waiting */ jb = jrb_find_int(ktBlocked,0); if(jb != NULL) { WakeKThread((K_t)jval_v(jrb_val(jb))); goto start; } if(!jrb_empty(ktBlocked)) { if(Debug & KT_DEBUG) { fprintf(stderr, "All processes blocked, exiting\n"); fflush(stderr); } exit(1); } else { if(Debug & KT_DEBUG) { fprintf(stderr, "No runnable threads, exiting\n"); fflush(stderr); } exit(0); } fprintf(stderr, "We shouldn't get here\n"); exit(1); } /* Grab the first job of the ready queue */ dtmp = dll_first(ktRunnable); kt = (K_t) dtmp->val.v; dll_delete_node(dtmp); /* If it is runnable, run it */ if(kt->state == RUNNABLE) { ktRunning = kt; ktRunning->state = RUNNING; longjmp(ktRunning->jmpbuf,1); /* This doesn't return */ } /* * if we have never run before, set up initial stack and go */ if(kt->state == STARTING) { if(setjmp(kt->jmpbuf) == 0) { /* * get double word aligned SP -- stacks grow from high * to low */ sp = (unsigned int)&((kt->stack[kt->stack_size-1])); while((sp % 8) != 0) sp--; #ifdef LINUX /* * keep double word aligned but put in enough * space to handle local variables for KtSched */ kt->jmpbuf->__jmpbuf[JB_BP] = (int)sp; kt->jmpbuf->__jmpbuf[JB_SP] = (int)sp-1024; PTR_MANGLE(kt->jmpbuf->__jmpbuf[JB_SP]); #endif #ifdef SOLARIS /* * keep double word aligned but put in enough * space to handle local variables for KtSched */ kt->jmpbuf[JB_FP] = (int)sp; kt->jmpbuf[JB_SP] = (int)sp-1024; #endif /* * set ktRunning while we still have local variables */ kt->state = RUNNING; ktRunning = kt; /* * now jump onto the new stack */ longjmp(kt->jmpbuf,1); } else { /* * here we are on a new, clean stack -- touch nothing, * set the state, and call * * ktRunning is global so there is no local variable * problem * * borrow this stack to try and free the last thread * if there was one */ FreeFinishedThreads(); if(setjmp(ktRunning->exitbuf) == 0) { /* * if we were killed before we ran, skip the * function call */ if(ktRunning->die_now == 0) { ktRunning->func(ktRunning->arg); } } /* * we are back and this thread is done * * make it inactive */ jb = jrb_find_int(ktActive,ktRunning->tid); if(jb == NULL) { if(Debug & KT_DEBUG) { fprintf(stderr, "KtSched: panic -- inactive return\n"); fflush(stderr); } exit(1); } jrb_delete_node(jb); /* * look to see if there is a thread waiting for this * one to exit -- careful with locals */ jb = jrb_find_int(ktBlocked,ktRunning->tid); if(jb != NULL) { WakeKThread((K_t)jval_v(jrb_val(jb))); } /* * all we can do now is to commit suicide * * don't touch the locals; * * and don't free the stack we are running on */ FreeFinishedThreads(); ktRunning->state = DEAD; dll_append(ktFree_me,new_jval_v(ktRunning)); ktRunning = NULL; goto start; } } /* The only way we get here is if there was a thread on the runnable queue whose state was not RUNNABLE or STARTING. Flag that as an error */ fprintf(stderr, "Error: non-STARTING or RUNNABLE thread on the ready queue\n"); exit(1); }