/*
 *	Atomically release the specified test-and-set lock and
 *	block the calling thread. This is a convenience function that
 *  does not add much (if any) power, but makes for more readable
 *  code and simplifies the possible system states, making it
 *  easier to reason about application correctness.
 */
int minithread_unlock_and_stop(tas_lock_t *lock) {
	interrupt_level_t old_int = set_interrupt_level(DISABLED);
	atomic_clear(lock);
	minithread_stop();
	set_interrupt_level(old_int);
	return 0;
}
Ejemplo n.º 2
0
/*
 * sleep with timeout in milliseconds. Need to disable interrupts during method call as we
  are not using semaphore for sleeping minithreads.
 */
void minithread_sleep_with_timeout(int delay) {
  interrupt_level_t old_level = set_interrupt_level(DISABLED);
  minithread_t* current_thread = schedule_data->running_thread; 
  register_alarm(delay, wakeup_thread, (void *) current_thread); //registers alarm
  minithread_stop(); //moves to next thread
  set_interrupt_level(old_level);
}
Ejemplo n.º 3
0
/*
 * sleep with timeout in milliseconds
 */
void 
minithread_sleep_with_timeout(int delay)
{
  interrupt_level_t l = set_interrupt_level(DISABLED);
  register_alarm(delay, get_new_alarm_handler(), minithread_self());
  set_interrupt_level(l);
  minithread_stop();
}
Ejemplo n.º 4
0
/*
 * semaphore_P(semaphore_t sem)
 *	Wait on the semaphore.
 */
void semaphore_P(semaphore_t sem) {
	while(atomic_test_and_set(&(sem->mutex)));
	if (--sem->limit < 0) {
		queue_append(sem->waiting, minithread_self());
		sem->mutex = 0;
		minithread_stop();
	} else {
		sem->mutex = 0;
	}
}
Ejemplo n.º 5
0
/*
 * semaphore_P(semaphore_t sem)
 *    P on the sempahore.
 */
void
semaphore_P(semaphore_t sem) {
    /* while (1 == atomic_test_and_set(&(sem->lock)))
        ; */
    if (0 > --(sem->count)) {
        queue_append(sem->wait, minithread_self());
        /* atomic_clear(&(sem->lock)); */
        minithread_stop();

    } /* else {
        atomic_clear(&(sem->lock));
    } */
}
Ejemplo n.º 6
0
/* Final proc of all newly created minithreads. Will never terminate and threads add
 * themselves to the cleanup_queue and then context switch to the reaper thread to perform
 * all the necesary cleanup steps to dispose of the thread properly and safely. */
int minithread_cleanup(int* id) {
  minithread_t* mini = minithread_self();
  mini->status = ZOMBIE;

  interrupt_level_t old_level = set_interrupt_level(DISABLED); 
  queue_append(schedule_data->cleanup_queue, mini);
  set_interrupt_level(old_level);

  // notify reaper thread and let it run
  semaphore_V(reaper_sema);
  minithread_stop();
  return 0;
}
Ejemplo n.º 7
0
/*
 * minithread_unlock_and_stop(tas_lock_t* lock)
 *	Atomically release the specified test-and-set lock and
 *	block the calling thread.
 */
void minithread_unlock_and_stop(tas_lock_t* lock)
{
	// Make it atomic
	set_interrupt_level(DISABLED);

	// Atomically clear the lock
	atomic_clear(lock);

	// Stop the thread
	minithread_stop();

	// Don't need to re-enable interrupts because mt_stop() performs a context 
	// switch and mt_switch() reenables interrupts
}
/*
 * semaphore_P(semaphore_t sem)
 *	P on the sempahore.
 */
void semaphore_P(semaphore_t sem) {
	//Loop until we succeed
	semaphore_spinlock(&(sem->lock));
	while (sem->count == 0) {
		queue_append(sem->thread_queue, minithread_self());
		atomic_clear(&(sem->lock));
		minithread_stop();
		semaphore_spinlock(&(sem->lock));
	}

	//Got the semaphore. Decrement and break
	sem->count--;
	atomic_clear(&(sem->lock));
}
Ejemplo n.º 9
0
void semaphore_P(semaphore_t *sem) {
	//Validate input arguments, abort if invalid argument is seen
	AbortOnCondition(sem == NULL, "Null argument sem in semaphore_P()");

	assert(sem->semaWaitQ != NULL); //sanity check

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

	//critical section
	if (sem->count > 0) sem->count--;
	else
	{
		minithread_t* currThread = minithread_self(); //get the calling thread
		AbortOnCondition(currThread == NULL, "Failed in minithread_self() method in semaphore_P()");
		queue_append(sem->semaWaitQ, currThread); //put thread onto semaphore's wait queue

		minithread_stop(); //block calling thread, yield processor
	}
	set_interrupt_level(old_level); //restore interrupt level
}