/* * 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; }
/* * 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); }
//Create a new thread and call minithread_start on it minithread_t minithread_fork(proc_t proc, arg_t arg) { minithread_t new_thread = minithread_create(proc, arg); if (new_thread == NULL) return NULL; minithread_start(new_thread); return new_thread; }
minithread_t* minithread_fork(proc_t proc, arg_t arg) { minithread_t *mthread = minithread_create(proc, arg); if (!mthread) { return NULL; } minithread_start(mthread); return mthread; }
minithread_t minithread_fork(proc_t proc, arg_t arg) { // Create the thread minithread_t thread = minithread_create(proc, arg); // Start the thread (add it to the ready queue) //minithread_start(thread); minithread_add_to_ready_queue(thread, 1); return thread; }
minithread_t minithread_fork(proc_t proc, arg_t arg) { minithread_t new_thread = minithread_create(proc,arg); semaphore_P(runnable_q_lock); if(multilevel_queue_enqueue(runnable_q, new_thread->priority,new_thread) == 0) { runnable_count++; //add to queue } semaphore_V(runnable_q_lock); return new_thread; }
minithread_t minithread_fork(proc_t proc, arg_t arg) { interrupt_level_t l; minithread_t new_thread = minithread_create(proc,arg); l = set_interrupt_level(DISABLED); if(multilevel_queue_enqueue(runnable_q, new_thread->priority,new_thread) == 0) { runnable_count++; //add to queue } set_interrupt_level(l); return new_thread; }
/* * 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); } }
/* * 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; }
/* Creates and then starts a minithread, making it RUNNABLE by placing it on the run_queue */ minithread_t* minithread_fork(proc_t proc, arg_t arg) { minithread_t* mini = minithread_create(proc, arg); minithread_start(mini); return mini; }