Exemplo n.º 1
0
void mksfs(int fresh){
	int i;
	if (fresh){
		init_fresh_disk(disk_name, BLOCK_SIZE, NUM_BLOCKS);
		
		free_blocks = list_create(NULL);
		
		for (i=2; i<NUM_BLOCKS-1; i++){
			list_append_int(free_blocks, i);
		}
		for (i=0; i<NUM_BLOCKS; i++){
			fat[i][block_index] = unused;
			fat[i][next] = eof;
		}
		for (i=0; i<MAX_NUM_FILES; i++){
			files[i].created = false;
			files[i].fatIndex = eof;
		}
	}
	
	else{
		init_disk(disk_name, BLOCK_SIZE, NUM_BLOCKS);
		read_blocks(0,1, &files);
		read_blocks(1,1, &fat);
		read_blocks(NUM_BLOCKS-1, 1, &free_blocks);
	}
	for(i=0; i<MAX_NUM_FILES; i++){
		fdt[i][open] = false;
		fdt[i][read_ptr] = false;
		fdt[i][write_ptr] = files[i].size;
	}
}
Exemplo n.º 2
0
/*
  The scheduler is called each time an ALRM signal is fired. It is responsible
  for preempting the currently running thread and giving a chance to another
  thread that is eligible to run in the runqueue.
*/
void scheduler(){
  noSwitches++;
  if (!list_empty(runqueue) ) {
    //Get the next thread to run and save the current one in a temp variable.
    int threadToPreempt = runningThreadId;
    runningThreadId = list_shift_int(runqueue);
    
    //Update the times to print the total time run on the CPU at the end of 
    //the program.
    clock_gettime(CLOCK_REALTIME, &tcbTable[threadToPreempt].end);
    tcbTable[threadToPreempt].run_time += tcbTable[threadToPreempt].end.tv_nsec - tcbTable[threadToPreempt].start.tv_nsec;
    clock_gettime(CLOCK_REALTIME, &tcbTable[runningThreadId].start);
    
    if (tcbTable[threadToPreempt].state == RUNNABLE || tcbTable[threadToPreempt].state == RUNNING) {
        //If the thread we are about to preempt is still RUNNABLE or RUNNING, we 
        //add it to the runqueue so that it can be scheduler at a later time.
        runqueue = list_append_int(runqueue, threadToPreempt);
    }
    
    //Perform the context switch.
    if (swapcontext(&tcbTable[threadToPreempt].context, &tcbTable[runningThreadId].context) == -1) {
        printf("swapcontext error\n");
        fflush(stdout);
    }
  }
}
Exemplo n.º 3
0
/**
 * Decrements the value of the given semaphore.
 * If the value goes below 0, the thread is put into a WAIT state.
 */
void semaphore_wait(int semaphore) {

	// disable alarm while working with semaphore
	sighold(SIGALRM);

#if DEBUG == 1
	char print[100];
	sprintf(print, "wait called on semaphore %d with value %d\n", semaphore,
			semaphores[semaphore]->value);
	perror(print);
#endif

	semaphores[semaphore]->value -= 1;
	if (semaphores[semaphore]->value < 0) {

#if DEBUG == 1
		sprintf(print, "thread %d put on waitqueue\n", current_thread);
		perror(print);
#endif

		// block thread
		threads[current_thread]->state = WAIT;
		// put it on the wait queue
		list_append_int(semaphores[semaphore]->thread_queue, current_thread);

		//unblock alarm and wait for scheduler to take over
		sigrelse(SIGALRM);
		while (threads[current_thread]->state == WAIT)
			; // when semaphore is signaled thread will be RUNNABLE again and return from this function
	} else {
		//don't block thread, unblock alarm and go back to the thread
		sigrelse(SIGALRM);
	}
}
Exemplo n.º 4
0
/**
 * Increments the value of the given semaphore.
 * If the value was  0, then the thread at the top of the wait queue is put on the runqueue.
 */
void semaphore_signal(int semaphore) {
	int next_thread;
	// disable alarm while working with semaphore
	sighold(SIGALRM);

#if DEBUG == 1
	char print[100];
	sprintf(print, "signaling semaphore %d with value %d\n", semaphore,
			semaphores[semaphore]->value);
	perror(print);
#endif

	if (semaphores[semaphore]->value < 0) {

		// make first thread on the wait queue RUNNABLE
		next_thread = list_shift_int(semaphores[semaphore]->thread_queue);
		if (next_thread == 0) {
			perror("no threads on waitqueue\n");
			exit(-1);
		}

#if DEBUG == 1
		sprintf(print, "signaling thread %d\n", next_thread);
		perror(print);
#endif

		threads[next_thread]->state = RUNNABLE;
		list_append_int(runqueue, next_thread);
	}
	semaphores[semaphore]->value += 1;
	sigrelse(SIGALRM);
}
Exemplo n.º 5
0
/**
 * Switches control from the main thread to one of the threads in the runqueue.
 * Activates the thread switcher.
 */
void runthreads() {
	int i;

	current_thread = 1;

	setup_signals();

	//queue all the threads
	for (i = 2; i < next_thread_index; i++) {
		list_append_int(runqueue, i);
	}

	/* setup our timer */
	it.it_interval.tv_sec = 0;
	it.it_interval.tv_usec = quantum;
	it.it_value = it.it_interval;
	if (setitimer(ITIMER_REAL, &it, NULL))
		perror("setitiimer");

	/* force a swap to the first context */
#if DEBUG == 1
	printf("starting the first thread\n");
#endif

	swapcontext(&main_context, threads[current_thread]->context);

#if DEBUG == 1
	printf("returned to main context; destorying runqueue\n");
#endif

	list_destroy(&runqueue);
}
Exemplo n.º 6
0
int mythread_create(char *threadname, void (*threadfunc)(), int stacksize)
{
	int pointer = threadCounter;

	if(threadCounter >= THREAD_MAX_SIZE)
	{
		return -1;
	}

	getcontext(&thread_table[pointer].context);

	thread_table[pointer].context.uc_link = &uctx_main;
	thread_table[pointer].context.uc_stack.ss_sp = malloc(stacksize);
	thread_table[pointer].context.uc_stack.ss_size = stacksize;
	thread_table[pointer].context.uc_stack.ss_flags = 0;
	sigemptyset(&thread_table[pointer].context.uc_sigmask);



	thread_table[pointer].thread_name = threadname;
	thread_table[pointer].thread_id = pointer;
	thread_table[pointer].state = RUNNABLE;
	//Time only count when thread is running
	thread_table[pointer].start_time = 0;

	makecontext(&thread_table[pointer].context, threadfunc, 0);


	//Finally add the thread to the running queue
	runQueue = list_append_int(runQueue, pointer);


	threadCounter ++;
	return pointer ;
}
Exemplo n.º 7
0
void semaphore_signal(int semaphore)
{

	//Init signal
	sigset_t x;
	sigemptyset(&x);
	sigaddset(&x, SIGALRM);

	//Block signal
	sigprocmask(SIG_BLOCK, &x, NULL);

	semaphore_table[semaphore].value++;

	if(semaphore_table[semaphore].value <= 0)
	{
		int thread;
		thread = list_shift_int(semaphore_table[semaphore].queue);
		thread_table[thread].state = RUNNABLE;

		//Put back the thread in the running queue
		runQueue = list_append_int(runQueue, thread);
	} 

	sigprocmask(SIG_UNBLOCK, &x, NULL);
	switch_thread();
}
Exemplo n.º 8
0
Arquivo: main.c Projeto: oswjk/euler-c
list_t *digits(int i)
{
    list_t *lst = NULL;

    while (i > 0)
    {
        int digit = i % 10;
        i = i / 10;
        lst = list_append_int(lst, digit);
    }

    return lst;
}
Exemplo n.º 9
0
void switch_thread()
{
	switch_ctr++;
	//If the running queue is empty and current thread is exit
	if(list_empty(runQueue) && thread_table[current_thread].state == EXIT)
	{
		//Calculate the running time
		long end_time = getCurrentNanoTime();
		thread_table[current_thread].running_time += end_time - thread_table[current_thread].start_time;
		end = 1;
		setcontext(&uctx_main);
	}
	//If we have a another thread in the running queue we switch
	if(!list_empty(runQueue))
	{
		//Switch thread with the first in the queue
		int old_thread = current_thread;
		current_thread = list_shift_int(runQueue);

		//Update the running time of the old thread
		long end_time = getCurrentNanoTime();
		thread_table[old_thread].running_time += end_time - thread_table[old_thread].start_time;

		//Reset the start time of the current_thread
		thread_table[current_thread].start_time = getCurrentNanoTime();

		//If we still need to run the old thread we put it back in the running quue 
		if(thread_table[old_thread].state == RUNNABLE || thread_table[old_thread].state == RUNNING)
		{
			runQueue = list_append_int(runQueue, old_thread);
		}

		//Update the context
		if(swapcontext(&thread_table[old_thread].context, &thread_table[current_thread].context) == -1)
		{
			return;
		}
	}
	else //No other thread in the queue
	{
		if(swapcontext(&thread_table[current_thread].context, &uctx_main) == -1)
		{
			return;
		}
	}
}
Exemplo n.º 10
0
/*
  When a thread calls this function, the value of the sempahore is decremented. If the 
  value goes below 0, the thread is put into a BLOCKED state. The calling thread
  is no longer in the runqueue and will be inserted into the waitqueue for the 
  given sempahore.
*/
void semaphore_wait(int semaphore){
  sigset_t blockSet;
  sigemptyset(&blockSet);
  sigaddset(&blockSet, SIGALRM);
  sigprocmask(SIG_BLOCK, &blockSet, NULL);

  int tmpNoSwitches = noSwitches; 
  //Decrement the semaphore value.
  (semTable[semaphore]).value--;

  if((semTable[semaphore]).value<0) {
      //This thread has to wait so we set it's state to block and put it in the 
      //wait queue for the given semaphore.
      (tcbTable[runningThreadId]).state = BLOCKED;
      (semTable[semaphore]).thread_queue = list_append_int((semTable[semaphore]).thread_queue,runningThreadId);
  }

  sigprocmask(SIG_UNBLOCK,&blockSet,NULL);
  while(tmpNoSwitches==noSwitches);
}
Exemplo n.º 11
0
void semaphore_wait(int semaphore)
{
	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set,SIGALRM);
	sigprocmask(SIG_BLOCK,&set,NULL);

	long long int old_switch_ctr = switch_ctr; 

	semaphore_table[semaphore].value --;

	if(semaphore_table[semaphore].value < 0)
	{
		thread_table[current_thread].state = BLOCKED;
		list_append_int(semaphore_table[semaphore].queue, current_thread);
	}
	sigprocmask(SIG_UNBLOCK,&set,NULL);

	while(old_switch_ctr==switch_ctr);
}
Exemplo n.º 12
0
/*
This function creates a new thread and returns an integer that points to the thread
control block that is allocated to the newly created thread in the thread control
block table. It returns -1 if it is unable to create a new thread. Further, 
the function creates and initializes the user context for the thread being created.
*/
int mythread_create(char *threadName, void(*threadfunc)(), int stacksize){
  //Set basic information about the thread.
  strcpy(tcbTable[threadId].thread_name, threadName);
  tcbTable[threadId].thread_id = threadId;
  tcbTable[threadId].state = RUNNABLE;
 
  //Set the context information about the thread.
  getcontext(&tcbTable[threadId].context); //Save the current context.
  tcbTable[threadId].context.uc_link = &uctx_main; //The context that will be resumed when the current context exits.
  tcbTable[threadId].context.uc_stack.ss_sp = malloc(stacksize); //Allocate the stack and make it point to the beginning of the stack.
  tcbTable[threadId].context.uc_stack.ss_size = stacksize; //Set the signal stack size.
  makecontext(&tcbTable[threadId].context,threadfunc,0); //Creates the context with the information set above.
  
  //Add thread to the runqueue.
  runqueue = list_append_int(runqueue,threadId);
  totalThreadsCreated++;
  
  //If an error occured, return -1. Otherwise, return the  thread id.
  if(!tcbTable[threadId].context.uc_stack.ss_sp){
    //We failed to allocate memory for the stack
    #if DEBUG == 1
      printf("Failed to allocate memory for the stack\n");
      fflush(stdout);
    #endif
    
    return -1;
  }else{
    #if DEBUG == 1
      printf("state of thread %s is %d\n",tcbTable[threadId].thread_name,tcbTable[threadId].state);
    #endif
    
    int tmp = threadId;
    threadId++;
    return tmp;
  }
}
Exemplo n.º 13
0
/*
  When a thread calls this function, the value of the semaphore is incremented. If the 
  value is less than one, then we should have at least one thread waiting on it. If
  this is the case then we take the thread waiting on the current semaphore out
  of the semaphore wait queue and insert it into the runqueue.
*/
void semaphore_signal(int semaphore){
  // Block Signals
  sigset_t blockSet;
  sigemptyset (&blockSet);
  sigaddset(&blockSet, SIGALRM);
  sigprocmask(SIG_BLOCK, &blockSet, NULL);
  
  /* Increase Semaphore value */
  semTable[semaphore].value = semTable[semaphore].value + 1;
  
  if (semTable[semaphore].value < 1) {
      int waitingThread;
      //Get the thread that has been granted the semphore.
      waitingThread = list_shift_int(semTable[semaphore].thread_queue);
      //Set the state of the thread granted the semaphore to runnable.
      tcbTable[waitingThread].state = RUNNABLE;
      //Add this thread to the back of the runqueue.
      runqueue = list_append_int(runqueue, waitingThread);
  } 

  // Unblock Signals
  sigprocmask(SIG_UNBLOCK, &blockSet, NULL);
  scheduler();
}
Exemplo n.º 14
0
void list_append_range_with_step(list *l, int start, int end, int step){
	register int i;
	for (i=start; i<end; i+=step){
		list_append_int(l, i);
	}
}
Exemplo n.º 15
0
void list_append_range(list *l, int start, int end){
	register int i;
	for (i=start; i<end; i++){
		list_append_int(l, i);
	}
}
Exemplo n.º 16
0
/**
 * Modified version of the swap.c example provided on http://cgi.cs.mcgill.ca/~xcai9/2012_comp_310.html
 *
 * The scheduling algorithm; selects the next context to run, then starts it.
 */
void scheduler() {
	sighold(SIGALRM);

#if DEBUG == 1
	char print[100];
#endif

	// increment current thread run time
	threads[current_thread]->total_time += quantum;

	// check if thread has completed
	if (threads[current_thread]->state == EXIT) {
#if DEBUG == 1
		sprintf(print, "thread %d completed, run time: %d\n", current_thread,
				threads[current_thread]->total_time);
		perror(print);
#endif

	} else if (threads[current_thread]->state == WAIT) {

#if DEBUG == 1
		sprintf(print, "thread %d blocked\n", current_thread);
		perror(print);
#endif

	} else {
		// else append it to the end of the runqueue
		threads[current_thread]->state = RUNNABLE;
		list_append_int(runqueue, current_thread);

#if DEBUG == 1
		sprintf(print, "thread %d put on runqueue, run time: %d\n",
				current_thread, threads[current_thread]->total_time);
		perror(print);
#endif

	}

	// get the next thread waiting to run from the run queue
	current_thread = list_shift_int(runqueue);

	// check if there is a next item
	// current_thread is 0 if there is not
	if (current_thread == 0) {
		// return to main context
#if DEBUG == 1
		perror("all threads completed\n");
#endif

		//turn off timer
		sighold(SIGALRM);
		it.it_interval.tv_usec = 0;
		it.it_value.tv_usec = 0;

		//returns to main context
		return;
	} else {
		// else run next thread on queue
		threads[current_thread]->state = RUNNING;
#if DEBUG == 1
		sprintf(print, "scheduling thread %d\n", current_thread);
		perror(print);
#endif
		sigrelse(SIGALRM);
		setcontext(threads[current_thread]->context);
	}
}