Exemplo n.º 1
0
void test_length() {
    multilevel_queue_t q1;
    void *p;
    int i1 = 0;
    int i2 = 0;
    // Test null queue
    assert(multilevel_queue_length(NULL) == -1);
    // Test queues
    q1 = multilevel_queue_new(2);
    assert(multilevel_queue_length(q1) == 0);
    assert(multilevel_queue_enqueue(q1, 1, &i1) == 0);
    assert(multilevel_queue_length(q1) == 1);
    assert(multilevel_queue_enqueue(q1, 1, &i2) == 0);
    assert(multilevel_queue_length(q1) == 2);
    assert(multilevel_queue_enqueue(q1, 0, &i1) == 0);
    assert(multilevel_queue_length(q1) == 3);
    assert(multilevel_queue_enqueue(q1, 0, &i2) == 0);
    assert(multilevel_queue_length(q1) == 4);
    assert(multilevel_queue_dequeue(q1, 0, &p) == 0);
    assert(multilevel_queue_length(q1) == 3);
    assert(multilevel_queue_dequeue(q1, 0, &p) == 0);
    assert(multilevel_queue_length(q1) == 2);
    assert(multilevel_queue_dequeue(q1, 1, &p) == 1);
    assert(multilevel_queue_dequeue(q1, 1, &p) == 1);
    assert(multilevel_queue_length(q1) == 0);
    assert(multilevel_queue_free(q1) == 0);
}
Exemplo n.º 2
0
/*
 * Initialization.
 *
 *      minithread_system_initialize:
 *       This procedure should be called from your C main procedure
 *       to turn a single threaded UNIX process into a multithreaded
 *       program.
 *
 *       Initialize any private data structures.
 *       Create the idle thread.
 *       Fork the thread which should call mainproc(mainarg)
 *       Start scheduling.
 *
 */
void
minithread_system_initialize(proc_t mainproc, arg_t mainarg) {
  minithread_t clean_up_thread = NULL;
  int a = 0;
  void* dummy_ptr = NULL;
  minithread_t tmp = NULL;
  tmp = NULL;
  dummy_ptr = (void*)&a;
  current_id = 0; // the next thread id to be assigned
  id_lock = semaphore_create();
  semaphore_initialize(id_lock,1); 
  runnable_q = multilevel_queue_new(4);
  blocked_q = queue_new();
  blocked_q_lock = semaphore_create();
  semaphore_initialize(blocked_q_lock,1);
  dead_q = queue_new();
  dead_q_lock = semaphore_create();
  semaphore_initialize(dead_q_lock,1);
  dead_sem = semaphore_create();
  semaphore_initialize(dead_sem,0);    
  runnable_q_lock = semaphore_create();
  semaphore_initialize(runnable_q_lock,1);
  clean_up_thread = minithread_create(clean_up, NULL);
  multilevel_queue_enqueue(runnable_q,
    clean_up_thread->priority,clean_up_thread);
  runnable_count++;
  minithread_clock_init(TIME_QUANTA, (interrupt_handler_t)clock_handler);
  init_alarm();
  current_thread = minithread_create(mainproc, mainarg);
  minithread_switch(&dummy_ptr, &(current_thread->stacktop));
  return;
}
Exemplo n.º 3
0
void test_dequeue() {
    multilevel_queue_t q;
    void *value;
    int x1 = 5;
    int x2 = 6;
    int x3 = 7;
    // Testing null queue
    assert(multilevel_queue_dequeue(NULL, 0, &value) == -1);
    assert(value == NULL);
    // Testing empty queue
    q = multilevel_queue_new(2);
    assert(multilevel_queue_dequeue(q, 3, &value) == -1);
    assert(value == NULL);
    // Testing queue
    assert(multilevel_queue_enqueue(q, 0, &x2) == 0);
    assert(multilevel_queue_enqueue(q, 1, &x3) == 0);
    assert(multilevel_queue_enqueue(q, 0, &x1) == 0);
    assert(multilevel_queue_dequeue(q, 2, (&value)) == -1);
    assert(multilevel_queue_dequeue(q, 0, (&value)) == 0);
    assert(*((int*) value) == x2);
    assert(multilevel_queue_length(q) == 2);
    assert(multilevel_queue_dequeue(q, 1, (&value)) == 1);
    assert(*((int*) value) == x3);
    assert(multilevel_queue_length(q) == 1);
    assert(multilevel_queue_dequeue(q, 1, &value) == 0);
    assert(*((int*) value) == x1);
    assert(multilevel_queue_length(q) == 0);
    assert(multilevel_queue_dequeue(q, 0, &value) == -1);
    assert(multilevel_queue_free(q) == 0);
}
Exemplo n.º 4
0
/*
 * Initialize the system to run the first minithread at
 * mainproc(mainarg).  This procedure should be called from your
 * main program with the callback procedure and argument specified
 * as arguments.
 */
void
minithread_system_initialize(proc_t mainproc, arg_t mainarg) {
  runnable_queue = multilevel_queue_new(MAX_LEVELS);
  
  stopped_queue = queue_new();
  scheduler_thread = scheduler_thread_create();
  assert(scheduler_thread);
  running_thread = scheduler_thread;
  int res = network_initialize((network_handler_t) network_handler);
  assert(res == 0);
  alarm_system_initialize();  
  minimsg_initialize();
  minisocket_initialize();
  reaper_thread = minithread_create(clean_stopped_threads, NULL);
  minithread_fork(mainproc, mainarg);
  interrupt_level_t prev_level = set_interrupt_level(ENABLED);
  minithread_clock_init(PERIOD * MILLISECOND, clock_handler);
  while (1) {
    if (!multilevel_queue_is_empty(runnable_queue)) {
      minithread_yield();
    }
  }
  set_interrupt_level(prev_level);
  multilevel_queue_free(runnable_queue);
  queue_free(stopped_queue);
}
// Store NUM_TOTAL_ELEMENTS in level 0,
// dequeue and make sure level is always 0
// and proper elements returned.
void test1() {

    printf("Beginning test 1.\n");

    multilevel_queue_t ml_q = multilevel_queue_new(NUM_LEVELS);
    
    int i;

    for (i = 0; i < NUM_TOTAL_ELEMENTS; i++) {
        int *int_ptr = (int *)malloc(sizeof(int));
        *int_ptr = i;
        multilevel_queue_enqueue(ml_q, 0, int_ptr);
    }

    int **int_ptr_ptr = (int **)malloc(sizeof(int *));
    int level_found_on;
    for (i = 0; i < NUM_TOTAL_ELEMENTS; i++) {
        level_found_on = multilevel_queue_dequeue(ml_q, 0, (void **)int_ptr_ptr);
        assert(level_found_on == 0);
        assert(**int_ptr_ptr == i);
        free(*int_ptr_ptr);
    }

    free(int_ptr_ptr);

    multilevel_queue_free(ml_q);

    printf("Test 1 passed.\n");

}
Exemplo n.º 6
0
/*
 * Initialization.
 * Initializes reaper and idle threads, starts and initializes main thread.
 * Also creates the scheduler and other data 
 *
 */
void minithread_system_initialize(proc_t mainproc, arg_t mainarg) {
  //allocate room for schedule data (global)
  schedule_data = (scheduler *) malloc(sizeof(scheduler));
  if (schedule_data == NULL) {
    exit(1); //OOM
  }
  schedule_data->cleanup_queue = queue_new();
  schedule_data->multi_run_queue = multilevel_queue_new(num_levels);

  reaper_sema = semaphore_create();
  semaphore_initialize(reaper_sema, 0);

  // create main thread
  minithread_t* main_thread = minithread_fork(mainproc, mainarg);

  // initialize idle thread
  idle_thread = (minithread_t *) malloc(sizeof(minithread_t));
  idle_thread->stacktop = NULL;
  idle_thread->thread_id = -1;

  //initialize alarm bookeeping data structure (priority queue)
  alarm_init();

  //remove from run queue and run it
  schedule_data->running_thread = main_thread;
  main_thread->status = RUNNING;
  multilevel_queue_dequeue(schedule_data->multi_run_queue, 0, (void *) main_thread);

  //reaper thread init
  reaper_thread = minithread_create(reaper_queue_cleanup, NULL);
  minithread_start(reaper_thread);

  //Start clock
  minithread_clock_init(clock_period, clock_handler);

  //Initialize network
  network_initialize(network_handler);

  //START MAIN PROC
  //minithread_switch also enables clock interrupts
  minithread_switch(&idle_thread->stacktop, &main_thread->stacktop);
  //always comes back here to idle in the kernel level (allows freeing resources)
  while (1) {
    minithread_t* next = next_runnable();

    set_interrupt_level(DISABLED);
    next->status = RUNNING;
    schedule_data->running_thread = next;
    minithread_switch(&idle_thread->stacktop, &next->stacktop);
  }
}
Exemplo n.º 7
0
/*
 * This is tested via valgrind
 */
void test_free() {
    multilevel_queue_t q1, q2, q3;
    int i;
    int i1 = 0;
    int i2 = 0;
    // Test null queue
    assert(multilevel_queue_free(NULL) == -1);
    // Test empty queue
    q1 = multilevel_queue_new(2);
    assert(multilevel_queue_free(q1) == 0);
    // Test queue with elements
    q2 = multilevel_queue_new(2);
    assert(multilevel_queue_enqueue(q2, 0, &i1) == 0);
    assert(multilevel_queue_enqueue(q2, 1, &i2) == 0);
    assert(multilevel_queue_free(q2) == 0);
    // Stress test for leaks
    q3 = multilevel_queue_new(2);
    for (i = 0; i < 10; i++) {
        assert(multilevel_queue_enqueue(q3, 0, &i1) == 0);
        assert(multilevel_queue_enqueue(q3, 1, &i2) == 0);
    }
    assert(multilevel_queue_free(q3) == 0);
}
// Store NUM_TOTAL_ELEMENTS evenly dispersed
// across levels 0-4. Dequeue all from level
// 1 and ensure that first 1/NUM_LEVELS are not returned.
void test3() {

    printf("Beginning test 3.\n");

    multilevel_queue_t ml_q = multilevel_queue_new(NUM_LEVELS);
    
    int i;
    int j;

    int level_fraction = NUM_TOTAL_ELEMENTS / NUM_LEVELS;

    for (i = 1; i <= NUM_LEVELS; i++) {
        for (j = i * level_fraction; j < (i+1) * level_fraction; j++) {
            int *int_ptr = (int *)malloc(sizeof(int));
            *int_ptr = j;
            multilevel_queue_enqueue(ml_q, i, int_ptr);
        }
    }

    int **int_ptr_ptr = (int **)malloc(sizeof(int *));
    int level_found_on;

    for (i = 0; i<= NUM_LEVELS; i++) {
        for (j = i * level_fraction; j < (i-1) * level_fraction; j++) {
            level_found_on = multilevel_queue_dequeue(ml_q, 1, (void **)int_ptr_ptr);
            if (j > level_fraction * (NUM_LEVELS - 1)/NUM_LEVELS) {
                assert(level_found_on == -1);    
            } else {
                assert(level_found_on == i+1);
                assert(**int_ptr_ptr == j + level_fraction);
                free(*int_ptr_ptr);
            }
        }
    }

    free(int_ptr_ptr);

    multilevel_queue_free(ml_q);

    printf("Test 3 passed.\n");
}
/*
 * Initialization.
 *
 * 	minithread_system_initialize:
 *	 This procedure should be called from your C main procedure
 *	 to turn a single threaded UNIX process into a multithreaded
 *	 program.
 *
 *	 Initialize any private data structures.
 * 	 Create the idle thread.
 *       Fork the thread which should call mainproc(mainarg)
 * 	 Start scheduling.
 *
 */
int minithread_system_initialize(proc_t mainproc, arg_t mainarg) {
	dbgprintf("Initializing minithread system...\n");
	ready_queue = multilevel_queue_new(2, 0);
	stop_queue = queue_new();
	dead_queue = queue_new();

	if (!ready_queue || !stop_queue || !dead_queue ) {
		return 0;
	}

	last_id = 0;
	current_quanta_end = 0;

	current = idle = minithread_create(NULL, NULL);
	minithread_fork(mainproc, mainarg);

	// initialize alarm subsystem
	alarm_system_initialize();

	minithread_clock_init(minithread_clock_handler);
	// interrupts currently disabled

	// schedule will call switch, which will enable interrupts
	minithread_schedule();

	// begin idle thread body
	minithread_idle();

	// system is shutting down now
	// stop clock interrupts
//	minithread_clock_stop();

	// cleanup alarm system
	alarm_system_cleanup();

	// cleanup thread system
	minithread_system_cleanup();

	return 0;
}
Exemplo n.º 10
0
/*
 * Initialization.
 *
 * 	minithread_system_initialize:
 *	 This procedure should be called from your C main procedure
 *	 to turn a single threaded UNIX process into a multithreaded
 *	 program.
 *
 *	 Initialize any private data structures.
 * 	 Create the idle thread.
 *       Fork the thread which should call mainproc(mainarg)
 * 	 Start scheduling.
 *
 */
void minithread_system_initialize(proc_t mainproc, arg_t mainarg) {
	// create an initial TCB
	minithread_t tcb = (minithread_t) malloc(sizeof(minithread));

	// Create a dummy pointer that points nowhere for the idle thread's stack
	stack_pointer_t* stack_top = (stack_pointer_t*) malloc(sizeof(stack_pointer_t));

	// Create the ready queue
	ready_queue = multilevel_queue_new(4);

	// There are currently 0 ready threads
	ready_threads = 0;

	// Set the current level we inspect in the ML queue to 0
	current_level = 0;

	// The first level of the queue has quanta of 1 period
	ticks_until_switch = 1;

	// The number of ticks to spend in the first ML queue level
	ticks_until_next_level = 80;

	// Create the waiting queue
	cleanup_queue = queue_new();

	// Create the alarm queue
	alarm_queue = queue_new();

	// Create the cleanup semaphore
	cleanup_sem = semaphore_create();
	semaphore_initialize(cleanup_sem, 0);

	// Initialize the TCB
	tcb->id = 0;
	tcb->priority = 0;
	tcb->proc = (proc_t) minithread_idle;
	tcb->arg = NULL; 
	tcb->dir_block_id = 0; // it'll never be used anyway
	// remember to update the initialize stack call a few lines down too - 
	// the first 2 nulls should also be proc/arg

	// Allocate the stack
	tcb->stack_base = NULL; // don't need this
	// just give it a dummy pointer so it can context switch
	tcb->stack_top = stack_top;

	// Set the global variables
	idle = tcb;
	running = idle;

	// Setup interrupts
	minithread_clock_init(&interrupt_handler);

	// Setup disk interrupts
	install_disk_handler((interrupt_handler_t) &disk_interrupt_handler);

	// Initialize the keyboard
	miniterm_initialize();

	// Initialize the minimsg layer
	minimsg_initialize();

	// Initialize the minisocket layer
	minisocket_initialize();

	// Initialize the miniroute layer
	miniroute_initialize();

	// Before interrupts are enabled, start the network handler
	network_initialize((interrupt_handler_t) &network_handler);

	// Initialize the filesystem
	minifile_initialize();

	// Fork the mainproc(mainarg) thread
	minithread_fork(mainproc, mainarg);

	// Fork a cleanup thread
	cleanup = minithread_fork((proc_t) minithread_cleanup, NULL);

	// Enable the interrupts
	set_interrupt_level(ENABLED);

	// Start the idle procedure
	minithread_idle(NULL);
}
Exemplo n.º 11
0
void test_new() {
    multilevel_queue_t q;
    q = multilevel_queue_new(4);
    assert(multilevel_queue_length(q) == 0);
    assert(multilevel_queue_free(q) == 0);
}