예제 #1
3
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;
}
예제 #2
0
main()
{
  IS is;
  Queue q;
  Stack s;
  Dllist l;
  int i;
  Jval j;

  is = new_inputstruct(NULL);

  while (get_line(is) > 0) {
    q = new_queue();
    s = new_stack();
    l = new_dllist();
    for (i = 0; i < strlen(is->fields[0]); i++) {
      queue_enqueue(q, new_jval_c(is->fields[0][i]));
      stack_push(s, new_jval_c(is->fields[0][i]));
      dll_append(l, new_jval_c(is->fields[0][i]));
      dll_prepend(l, new_jval_c(is->fields[0][i]));
    }
    while (!queue_empty(q)) {
      j = queue_dequeue(q); printf("%c", j.c);
      j = stack_pop(s); printf("%c", j.c);
      printf("%c", l->flink->val.c); dll_delete_node(l->flink);
      printf("%c", l->flink->val.c); dll_delete_node(l->flink);
      printf(" ");
    }
    printf("\n");
    free_queue(q);
    free_stack(s);
    free_dllist(l);
  }
}
예제 #3
0
파일: 2.c 프로젝트: namnt1410/Emb_exp
int main (int argc, char **argv)
{
  struct msgbuff{
    long mtype;
    pid_t pid;
  }message;

  pid_t pid, npid;
  int i;

  int           msqid;
  key_t         keyx;
  struct msqid_ds msq;

  Dllist q = new_dllist();
  Dllist n;

  keyx = ftok(KEYFILE_PATH, (int)ID);

  msqid = msgget(keyx, 0666 | IPC_CREAT);

  if (msqid == -1) {
    perror("msgget");
    exit(1);
  }

  while(1) { 
    if((msgrcv(msqid, &message, sizeof(pid_t), 1, 0)) ==
       MSGQ_NG){
      perror("msgrcv");
      exit(1);
    }
    pid = message.pid;
    if(pid != 1) {
      if(dll_empty(q)) kill(pid, SIGUSR1);
      else {
        n = dll_first(q);
        npid = jval_i(dll_val(n));
        if(pid == npid) { 
          kill(pid, SIGUSR1);
          dll_delete_node(n);
        } else dll_append(q, new_jval_i(pid));
      }
    } else {
      if(!dll_empty(q)) { 
        n = dll_first(q);
        npid = jval_i(dll_val(n));
        kill(npid, SIGUSR1);
        dll_delete_node(n);
      }
    }
  }

  return 0;
}
예제 #4
0
PhysicalFrame* findFreePhysicalPage(MMUSim* sim){
  Dllist freeFrames;
  freeFrames = sim->freePhysicalFrames;
  Dllist usedFrames;
  usedFrames = sim->usedPhysicalFrames;
  JRB tree;
  tree = sim->frameTree;
  Dllist nil;
  nil = dll_nil(freeFrames);
  Dllist ffp;
  ffp = dll_first(freeFrames);

  if(ffp != nil){
    PhysicalFrame* freeFrame;
    freeFrame = ffp->val.v;
    dll_delete_node(ffp);
    dll_append(usedFrames, new_jval_v(freeFrame));

    if(sim->rep == 2){ // LRU, sort by time
      jrb_insert_int(tree,freeFrame->lastUsed,new_jval_v(freeFrame));
    } else if(sim->rep == 3){ // LFU, sort by lowCount
      jrb_insert_int(tree,freeFrame->useCount,new_jval_v(freeFrame));
    } else if (sim->rep == 4){ // MFU, sort by highCount
      jrb_insert_int(tree,freeFrame->useCount,new_jval_v(freeFrame));
    }  

    return freeFrame;
  } else {
    return -1;
  }

}
예제 #5
0
main(int argc, char **argv)
{
  IS is;
  int n;
  Dllist l;
  Dllist tmp;

  if (argc != 2) {
    fprintf(stderr, "usage: dlltail n\n");
    exit(1);
  }
  n = atoi(argv[1]);
  if (n < 0) {
    fprintf(stderr, "usage: dlltail n  -- n must be >= 0\n");
    exit(1);
  }

  is = new_inputstruct(NULL);
  l = new_dllist();

  while (get_line(is) >= 0) {
    dll_append(l, new_jval_s(strdup(is->text1)));
    if (is->line > n) {
      tmp = dll_first(l);
      free(jval_s(dll_val(tmp)));
      dll_delete_node(tmp);
    }
  }

  dll_traverse(tmp, l) printf("%s", jval_s(tmp->val));
}
예제 #6
0
파일: dl_lists.c 프로젝트: OPENDAP/bes
int dll_free_list(DLL_NODE_PTR head)
{
	DLL_NODE_PTR node = NULL;
	int count = 0;

	FF_VALIDATE(head);
	if (head == NULL)
		return(0);
	
	dll_rewind(&head);

	node = dll_first(head);
	while (!DLL_IS_HEAD_NODE(node))
	{
		dll_delete_node(node);

		count++;
		node = dll_first(head);
	}

#ifdef DLL_CHK
	assert(DLL_COUNT(head) == 0);
#endif

	head->next = head->previous = NULL;

#ifdef FF_CHK_ADDR
	head->check_address = NULL;
#endif

	memFree(head, "Header Node");          

	return(count);
}
예제 #7
0
파일: dllist.c 프로젝트: josborn8/libfdr
void free_dllist(Dllist l)
{
  while (!dll_empty(l)) {
    dll_delete_node(dll_first(l));
  }
  free(l);
}
예제 #8
0
void scheduler()
{

	//readyq = new_dllist();

	if(dll_empty(readyq))
	{
		//printf("empty ready q\n");
		current = NULL;
		noop();
	}


	//takes the first PCB off the readyq and calls run_user_code() on its registers
	else
	{
		// pop off and delete from readyq
		printf("non-empty q\n");
		current = (PCB *) jval_v(dll_val(dll_first(readyq)));
		printf("non-empty q\n");
		dll_delete_node(dll_first(readyq));
		printf("non-empty q\n");
		run_user_code(current->registers);
	}
}
예제 #9
0
파일: scheduler.c 프로젝트: Styxx/CS170-W16
void scheduler() {

  // Init no longer has children. Needs to close.
  if (jrb_empty(init->children)) {
    SYSHalt();
  }

  if(dll_empty(readyQ)) {
    noop_flag = 1;
    noop();
  } else {
    PCB *process;
    Dllist node;
    Jval registers;
    
    noop_flag = 0;
    process = (PCB *) malloc(sizeof(PCB));
    node = dll_first(readyQ);       // Get next node in queue
    dll_delete_node(node);          // Node in memory. Delete off readyQ
    
    // Get registers from node
    registers = dll_val(node);
    process = (PCB *)jval_v(registers);
    
    // Update current process
    currentProcess = process;
    User_Base = process->base;
    User_Limit = process->limit;
    
    run_user_code(process->registers);
  }
}
예제 #10
0
int solution(Graph graph, Jval start, Jval stop, Dllist stackVisit, Jval (*cloneFunc)(Jval),
	int (*compare)(Jval, Jval), void (*reportFunc)(Jval)) {

	Dllist stackRes;
	Dllist node;
	Jval nowNode, temp;
	int counter = 0;

	stackRes = new_dllist();
	node = dll_first(stackVisit);
	nowNode = cloneFunc(node->val);
	dll_delete_node(node);
	dll_prepend(stackRes, nowNode);

	while(!dll_empty(stackVisit)) {
		if(isAdjacent(graph, nowNode, start, compare)) {
			dll_prepend(stackRes, start);
			counter++;
			break;
		}

		do {
			node = dll_first(stackVisit);
			temp = cloneFunc(node->val);
			dll_delete_node(node);	

			if(isAdjacent(graph, nowNode, temp, compare)) {
				dll_prepend(stackRes, temp);
				nowNode = temp;
				counter++;
				break;
			}
		} while(!dll_empty(stackVisit));
	}

	printf("Solution: The shortest path between two node: \n");

	while(!dll_empty(stackRes)) {
		node = dll_first(stackRes);
		reportFunc(node->val);
		dll_delete_node(node);
	}

	free_dllist(stackVisit);

	return counter;
}
예제 #11
0
Jval* deQueue(Queue q) {
	Jval* v;
	if (dll_empty(q) || dll_empty(dll_first(q))) v = NULL;
	else {
		v = (Jval*)malloc(sizeof(Jval));
		memcpy(v,&dll_first(q)->val, sizeof(Jval));
		dll_delete_node(dll_first(q));
	}
	return v;
}
예제 #12
0
void
FreeFinishedThreads()
{
	Dllist curr;

        while (!dll_empty(ktFree_me)) 
        {
                curr = dll_first(ktFree_me);
		FreeKThread((K_t)curr->val.v);
		dll_delete_node(curr);
        }
        return;
}
예제 #13
0
//Each elevator is a while loop. 
//Check the global list and if it’s empty, block on the condition variable for blocking elevators. 
//When the elevator gets a person to service, it moves to the appropriate flo0or and opens its door. 
//It puts itself into the person’s e field, then signals the person and blocks until the person wakes it up. 
//When it wakes up, it goes to the person’s destination floor, opens its door, signals the person and blocks. 
//When the person wakes it up, it closes its door and re-executes its while loop.
//• Your elevator’s should call open door(), close door() from move to floor() appropriately. 
//All sleeping and printing should be done in elevator skeleton.c. 
//Thus, your final program that you hand in should not do any sleeping or any printing.
void *elevator(void *arg)
{
    Person *person_in_transit;
    for(;;)
    {

        pthread_mutex_lock(((Elevator*)arg)->es->lock);
        while (!((Queue*)((Elevator*)arg)->es->v)->count)
            pthread_cond_wait(((Queue*)((Elevator*)arg)->es->v)->cond, ((Elevator*)arg)->es->lock);
            if(!dll_empty(((Queue*)((Elevator*)arg)->es->v)->passengers)){
             person_in_transit = (Person*)jval_v(dll_val(dll_first(((Queue*)((Elevator*)arg)->es->v)->passengers)));
             dll_delete_node(dll_first(((Queue*)((Elevator*)arg)->es->v)->passengers));
            }
        // unlock the critial section.
        pthread_mutex_unlock(((Elevator*)arg)->es->lock);
       //move the elevator.
        --((Queue*)((Elevator*)arg)->es->v)->count;
        person_in_transit->from == ((Elevator*)arg)->onfloor?:move_to_floor(((Elevator*)arg), person_in_transit->from);
        //open the door
        open_door(((Elevator*)arg));
        //add the people to the elevator
        person_in_transit->e = ((Elevator*)arg); 
        //signal the person
        pthread_mutex_lock(person_in_transit->lock);
        pthread_cond_signal(person_in_transit->cond);
        pthread_mutex_unlock(person_in_transit->lock);
        // have the elevator wait
        pthread_mutex_lock(((Elevator*)arg)->lock);
        pthread_cond_wait(((Elevator*)arg)->cond, ((Elevator*)arg)->lock);
        pthread_mutex_unlock(((Elevator*)arg)->lock);
        // close door 
        close_door(((Elevator*)arg));
        // elevator moves
        move_to_floor(person_in_transit->e,person_in_transit->to);
        // open the door once move has completed.
        open_door(((Elevator*)arg));
        // signal the person
        pthread_mutex_lock(person_in_transit->lock);
        pthread_cond_signal(person_in_transit->cond);
        pthread_mutex_unlock(person_in_transit->lock);
        // block the elevator
        pthread_mutex_lock(((Elevator*)arg)->lock);
        pthread_cond_wait(((Elevator*)arg)->cond, ((Elevator*)arg)->lock);
        pthread_mutex_unlock(((Elevator*)arg)->lock);
        // close the door
        close_door(((Elevator*)arg));
        // restart. 
    }
}
예제 #14
0
int UShortestPath(Graph graph, Jval start, Jval stop, 
	Jval (*cloneFunc)(Jval), int (*compare)(Jval, Jval), void (*reportFunc)(Jval)) {

	Dllist node, queue, stackVisit;
	JRB visited;
	Jval *output;
	Jval temp, tmp;

	int i, n;

	visited = make_jrb();
	queue = new_dllist();
	stackVisit = new_dllist();
	dll_append(queue, start);

	if((output = myMalloc(sizeof(Jval), 100)) == NULL) {
		return 0;
	}

	while(!dll_empty(queue)) {
		node = dll_first(queue);
		temp = cloneFunc(node->val);
		dll_delete_node(node);

		if(jrb_find_gen(visited, temp, compare) == NULL) {
			jrb_insert_gen(visited, temp, temp, compare);
			dll_prepend(stackVisit, temp);
			
			if(compare(temp, stop) == 0) {
				return solution(graph, start, stop, stackVisit, cloneFunc, compare, reportFunc);
			}

			n = getAdjacentVertices(graph, temp, output, compare);
			for(i = 0; i < n; i++) {
				if(jrb_find_gen(visited, output[i], compare) == NULL) {
					dll_append(queue, output[i]);
				}
			}
		}
	}

	return -1;
}
예제 #15
0
void DFS(Graph graph, Jval start, Jval stop, 
	Jval (*cloneFunc)(Jval), int (*compare)(Jval, Jval), void (*reportFunc)(Jval)) {
	Dllist node, stack;
	JRB visited;
	Jval *output;
	Jval temp, tmp;

	int i, n;

	visited = make_jrb();
	stack = new_dllist();
	dll_prepend(stack, start);

	if((output = myMalloc(sizeof(Jval), 100)) == NULL) {
		return;
	}

	while(!dll_empty(stack)) {
		node = dll_first(stack);
		temp = cloneFunc(node->val);
		dll_delete_node(node);

		if(jrb_find_gen(visited, temp, compare) == NULL) {
			reportFunc(temp);
			jrb_insert_gen(visited, temp, temp, compare);
			
			if(compare(temp, stop) == 0) {
				jrb_free_tree(visited);
				free_dllist(stack);
				free(output);
				return;
			}

			n = getAdjacentVertices(graph, temp, output, compare);
			for(i = 0; i < n; i++) {
				if(jrb_find_gen(visited, output[i], compare) == NULL) {
					dll_prepend(stack, output[i]);
				}
			}
		}
	}
}
예제 #16
0
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;
}
void BFS_Visit(Graph_Struct Graph,char start[])
{
	Graph_Symbol_Table *Table;
	char *u,*v;
	JRB node_rbt,tree,ele;
	Dllist node_queue,queue = new_dllist();
	printf("%s ",start);
	
	u = malloc(MAX_LENGTH_STRING);
	v = malloc(MAX_LENGTH_STRING);
	
	Table = Search_On_Table(Graph,start);
	Table->colour = 'g';
	
	dll_append(queue, new_jval_s(start));
	while(!dll_empty(queue))
	{
		node_queue = dll_first(queue);
		u = jval_s(node_queue->val);
		dll_delete_node(node_queue);
		node_rbt = jrb_find_str(Graph.Edges,u);
		if(node_rbt != NULL)
		{
			tree = (JRB)jval_v(node_rbt->val);
			jrb_traverse(ele,tree)
			{
				v = jval_s(ele->key);
				Table = Search_On_Table(Graph,v);
				if(Table->colour == 'w')
				{
					printf("%s ",v);
					Table->colour = 'g';
					if(Table->previous == NULL)
					{
						Table->previous = malloc(MAX_LENGTH_STRING);
					}
					strcpy(Table->previous,u);
					dll_append(queue, new_jval_s(v));
				}
			}
		}
예제 #18
0
int BFStraverse(Graph graph, Jval start,
	Jval (*cloneFunc)(Jval), int (*compare)(Jval, Jval), void (*reportFunc)(Jval)) {
	
	Dllist node, queue;
	JRB visited;
	Jval *output;
	Jval temp, tmp;

	int i, n, counter = 0;

	visited = make_jrb();
	queue = new_dllist();
	dll_append(queue, start);

	if((output = myMalloc(sizeof(Jval), 100)) == NULL) {
		return counter;
	}

	while(!dll_empty(queue)) {
		node = dll_first(queue);
		temp = cloneFunc(node->val);
		dll_delete_node(node);

		if(jrb_find_gen(visited, temp, compare) == NULL) {
			counter++;
			reportFunc(temp);
			jrb_insert_gen(visited, temp, temp, compare);
			
			n = getAdjacentVertices(graph, temp, output, compare);
			for(i = 0; i < n; i++) {
				if(jrb_find_gen(visited, output[i], compare) == NULL) {
					dll_append(queue, output[i]);
				}
			}
		}
	}

	return counter;
}
예제 #19
0
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;
}
예제 #20
0
void PfEvict(MMUSim* sim){
  Dllist freeFrames;
  Dllist usedFrames;
  freeFrames = sim->freePhysicalFrames;
  usedFrames = sim->usedPhysicalFrames;
  Dllist uNil;
  uNil = dll_nil(usedFrames);
  Dllist uFrame;
  uFrame = dll_first(usedFrames);

  int rep = sim->rep;

  PhysicalFrame* evictFrame;

  if(rep == 1){ // FIFO///////////////////////////////
    // nothing is needed, FIFO happens automatically
    evictFrame = uFrame->val.v;                     
  }//////////////////////////END FIFO/////////////////

  else if(rep == 2){ // LRU///////////////////////////
    
    PhysicalFrame* oldFrame;
    unsigned int oldTime = UINT_MAX;

    PhysicalFrame* frameArray;
    frameArray = sim->physicalFrames;
    PhysicalFrame* currentFrame;

    int i;
    for (i = 0; i < sim->numFrames; i++){
      currentFrame = &frameArray[i];

      if(currentFrame->lastUsed < oldTime){
        oldFrame = currentFrame;
        oldTime = currentFrame->lastUsed;
      }
    }

    evictFrame = oldFrame;

    Dllist* ref;
    ref = evictFrame->listRef;

    uFrame = *ref;

  } ////////////////////END LRU//////////////////////

  else if(rep == 3){ // LFU////////////////////////

    PhysicalFrame* oldFrame;
    int oldUse = INT_MAX;

    PhysicalFrame* frameArray;
    frameArray = sim->physicalFrames;
    PhysicalFrame* currentFrame;

    int i;
    for (i = 0; i < sim->numFrames; i++){
      currentFrame = &frameArray[i];

      if(currentFrame->useCount < oldUse){
        oldFrame = currentFrame;
        oldUse = currentFrame->useCount;
      }
    }

    evictFrame = oldFrame;

    Dllist* ref;
    ref = evictFrame->listRef;

    uFrame = *ref;

  } /////////////////////END LFU//////////////////////

  else if(rep == 4){ // MFU/////////////////////////

    evictFrame = sim->mfuFrame;
    Dllist* ref;
    ref = evictFrame->listRef;

    uFrame = *ref;



  } ////////////////////END MFU//////////////////////

  else{ // RANDOM///////////////////////////////////
    int max = sim->numFrames - 1;
    int randomIndex = ((double) rand() / (((double)RAND_MAX)+1)) * (max+1);

    PhysicalFrame* frameArray;
    frameArray = sim->physicalFrames;
    PhysicalFrame* randomFrame;
    randomFrame = &frameArray[randomIndex];

    evictFrame = randomFrame;

    Dllist* randomRef;
    randomRef = evictFrame->listRef;

    uFrame = *randomRef;
    
  }///////////////// END RANDOM////////////////////

  dll_delete_node(uFrame);
  dll_append(freeFrames, new_jval_v(evictFrame));
  Dllist listItem = dll_last(sim->freePhysicalFrames);
  evictFrame->listRef = listItem;

}
예제 #21
0
void *elevator(void *arg){
    Elevator *e = (Elevator *) arg; 
    Dllist item, next, pickup;
    Person *p;
    int direction = 1;
    pickup = new_dllist();

    while(1){

        if(e -> onfloor >= top) direction = -1;
        else if(e -> onfloor <= 1) direction = 1;
        //printf("\tElevator[%i] on floor %i going %s:\n",
        //        e -> id, e -> onfloor, direction == 1 ? "up": "down"); 

        /* pick people up */
        pthread_mutex_lock(lock);

        item = dll_first(people);
        while(!dll_empty(people) && item != dll_nil(people)){
            next = dll_next(item);
            p = (Person *) item -> val.v;

            //printf("\t\tShould I get %s %s going from %i to %i? ",
            //        p -> fname, p -> lname, p -> from, p -> to);

            if(e -> onfloor == p -> from){
                if(p -> to > e -> onfloor && direction == 1 || 
                   p -> to < e -> onfloor && direction == -1){
                    dll_append(pickup, item -> val);
                    dll_delete_node(item);
                    //printf("yes!\n");

                }
                //else printf("no!\n");
            }
            //else printf("no!\n");

            item = next;
        }

        pthread_mutex_unlock(lock);

        item = dll_first(pickup);
        while(!dll_empty(pickup) && item != dll_nil(pickup)){
            next = dll_next(item);
            p = (Person *) item -> val.v;

            if(!e -> door_open) open_door(e);
            pthread_mutex_lock(p -> lock);

            p -> e = e;

            pthread_cond_signal(p -> cond);
            pthread_mutex_lock(e -> lock);
            pthread_mutex_unlock(p -> lock);

            pthread_cond_wait(e -> cond, e -> lock);
            pthread_mutex_unlock(e -> lock);

            dll_delete_node(item);
            item = next;
        }
        if(e -> door_open) close_door(e);

        move_to_floor(e, e -> onfloor + direction);

        /* drop people off */
        item = dll_first(e -> people);
        while(!dll_empty(e -> people) && item != dll_nil(e -> people)){
            next = dll_next(item);
            p = (Person *) item -> val.v;

            if(p -> to == e -> onfloor){
               if(!e -> door_open) open_door(e);
                
               pthread_mutex_lock(p -> lock);
               pthread_cond_signal(p -> cond);
               pthread_mutex_lock(e -> lock);
               pthread_mutex_unlock(p -> lock);

               pthread_cond_wait(e -> cond, e -> lock);
               pthread_mutex_unlock(e -> lock);
            }

            item = next;
        }
        //if(e -> door_open) close_door(e);

    }

    return NULL;
}
예제 #22
0
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);
}
예제 #23
0
void do_read(PCB *pcb){
	int fd = pcb->registers[5],
		buf = pcb->registers[6],
		count = pcb->registers[7];

	//printf("COUNT COUNT COUNT::::%d",count);


	if(valid_fd(pcb, fd, FD_READ)){ //todo: or valid fd
		if(buf < 0){
			syscall_return(pcb,-1*EFAULT);
		}

	}else{
		syscall_return(pcb,-1*EBADF); //Bad file number
	}

	struct File_Descriptor *fd_obj = pcb->fd_table[fd];

	//if(!fd_obj->console_flag){
		//printf("do_read: %d %d %d\n", fd, buf, count);
	//}

	if(check_buffer_address(pcb, buf) == FALSE){
		syscall_return(pcb, -1*EFAULT);
	}

	if(count < 0){
		syscall_return(pcb, -1*EINVAL);
	}

	int i = 0;
	int val;
	//printf("\ngot here to 1\n");
	for(; i < count; i++){
		//printf("obj id:%d, console flag:%d\n", fd_obj->id, fd_obj->console_flag);
		if(fd_obj->console_flag){
			//printf("\ngot here to 0000\n");
			P_kt_sem(nelem);

			Dllist first = dll_first(console_read_buf);
			val = jval_i(dll_val(first));
			dll_delete_node(first);
			
			console_read_buf_size -= 1;

		}else{
			//HMM, do we need a lock for buffer access?
			//printf("\ngot here to 2\n");
			struct Pipe *pipe = fd_obj->pipe;

			//printf("read from pipe: %p\n", pipe);
			//printf("r:b\n");
        	P_kt_sem(pipe->empty_sem);

			val = pipe->buff[pipe->buff_start];
			//printf("r:(%d) %c\n",val, val);
			pipe->buff_start++;
			if(pipe->buff_start == PIPE_BUFF_SIZE){
				pipe->buff_start = 0;
			}
			//printf("\ngot here to 2.5\n");
			V_kt_sem(pipe->full_sem);
			//printf("\ngot here to 3\n")
			//printf("r:a\n");;

			if(pipe->buff_start == pipe->buff_end){
				break;
			}

		}


		if(val == -1 || val == 0){
			break;
		}

		main_memory[pcb->User_Base+buf+i] = val;
	}
	if(!fd_obj->console_flag){
		//printf("read done\n");
	}
	//printf("syscall return\n");
	syscall_return(pcb, i);

}