//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;
}
Ejemplo n.º 2
0
/**
 * This function does need to be protected because it is only called
 * from within a semaphore V, during which interrupts are disabled.
 * */
void
minithread_dequeue_and_run(queue_t q) {
  minithread_t blocked_thread = NULL;
  queue_dequeue(q, (void**)(&blocked_thread) );
  if (blocked_thread->status != BLOCKED) {
    printf("thread %d should have status BLOCKED\n", minithread_id());
  }
  minithread_start(blocked_thread);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
/*
 * semaphore_V(semaphore_t sem)
 *	Signal on the semaphore.
 */
void semaphore_V(semaphore_t sem) {
	minithread_t thread;
	while(atomic_test_and_set(&(sem->mutex)));
	
	if(++sem->limit <= 0) {
		queue_dequeue(sem->waiting,(void**) &thread);
		minithread_start((minithread_t) thread);			 
	}
	sem->mutex = 0;
}
/*
 * semaphore_V(semaphore_t sem)
 *	V on the sempahore.
 * If a thread is waiting to P the semaphore, 
 * wake it up.
 */
void semaphore_V(semaphore_t sem) {
	minithread_t waiting_thread;

	semaphore_spinlock(&(sem->lock));
	sem->count++;
	if ( queue_length(sem->thread_queue) ) {
		queue_dequeue(sem->thread_queue, &waiting_thread);
		minithread_start(waiting_thread);
	}
	atomic_clear(&(sem->lock));
}
Ejemplo n.º 6
0
/*
 * semaphore_V(semaphore_t sem)
 *    V on the sempahore.
 */
void
semaphore_V(semaphore_t sem) {
    minithread_t t;
    /* while (1 == atomic_test_and_set(&(sem->lock)))
        ; */
    if (0 >= ++(sem->count)) {
        queue_dequeue(sem->wait,(void**)&t);
        minithread_start(t);
    }
    /* atomic_clear(&(sem->lock)); */
}
Ejemplo n.º 7
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);
  }
}
Ejemplo n.º 8
0
void semaphore_V(semaphore_t *sem) {
	//Validate input arguments, abort if invalid argument is seen
	AbortOnCondition(sem == NULL, "Null argument sem in semaphore_V()"); //validate argument

	assert(sem->semaWaitQ != NULL);

	interrupt_level_t old_level = set_interrupt_level(DISABLED); //disable interrupts

	//critical section
	if (queue_length(sem->semaWaitQ) == 0) sem->count++;
	else
	{
		//if the semaphore wait queue is not empty, then there are threads waiting and the count must be at 0
		assert(sem->count == 0);

		minithread_t* t = NULL;
		int dequeueSuccess = queue_dequeue(sem->semaWaitQ, (void**) &t);
		assert(t != NULL);
		AbortOnCondition(dequeueSuccess != 0, "Failed in queue_dequeue operation in semaphore_V()");
		
		minithread_start(t);
	}
	set_interrupt_level(old_level); //restore interrupts
}
/*
 * Thread Awaken Callback - for sleep with timeout
 */
void minithread_awaken_callback(arg_t arg) {
	minithread_start( (minithread_t)arg );
}
Ejemplo n.º 10
0
void wakeup_thread(void* wakeup_mini) {
  //need to cast this back to the correct data type of a minithread_t
  //Note that we have decided to put the waking thread in the same priority level
  //as when it was sleeping
  minithread_start((minithread_t *) wakeup_mini);
}
Ejemplo n.º 11
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;
}