/*
 * 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;
}
Example #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) {
	// 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);
}