Ejemplo n.º 1
0
int mythread_mutex_unlock(mythread_mutex_t *mutex)
{
	int status;

	if(mutex->lockvariable==-1) // if the lock was already destroyed, return an error code 
	{
	
		return 1; // return the error code
	}

	status=compare_and_swap(&mutex->lockvariable,0,1); // changing the state of the lockvariable to unlocked atomically

	while(status==0)
	{
		status=compare_and_swap(&mutex->lockvariable,0,1);
	}
	
	mythread_enter_kernel();
	mutex->noofwaitingthreads-=1; // decrementing the number of threads waiting on the mutex by one
	mutex->owner_thread=NULL;
	
	// Chech if there are any threads that are blocked in the queue due to exceeding the threshold
	if(mutex->noofwaitingthreads==mutex->noofblockedthreads && mutex->noofwaitingthreads > 0)
	{
		mutex->noofblockedthreads-=1;
		mythread_unblock(mutex->blocked_threads,1);
	}
	else
	{
		mythread_leave_kernel();

	}	
	return 0;
}
/*
 * This function unblocks one of the threads blocked on a conditional variable
 * The scheduling policy uses FIFO
 * Pre:A conditional variable on which threads are blocked
 * Post:One thread which was blocked on the conditional variable is unblocked
 * Returns:  1 on failure
 * 	     0 on success
 */
int mythread_cond_signal(mythread_cond_t * cond)
{
    /*
     * Wait if there is any thread is executing conditional wait
     * This is used to ensure no signal is lost 
     * while any thread is executing condtional wait code.  
     */
    if (futex_down(&ccb_table[*cond]->mutex)) {
	perror("failed to do futex_down");
	return 1;
    }

    /*
     * Dequeue and resume the thread from blocked queue
     */  
    mythread_enter_kernel();
    if(ccb_table[*cond]->q != NULL) {
          mythread_unblock(&ccb_table[*cond]->q, 0);
    } else {
          mythread_leave_kernel();
    }
    /*
     * Resume any thread about to execute conditional wait
     */  
    if (futex_up(&ccb_table[*cond]->mutex)) {
	perror("failed to do futex up\n");
	return 1;
    }
    return 0;
}
Ejemplo n.º 3
0
/*
 *	Will release a thread if needed, otherwise will just increment
 *	  the semaphore's value
 *
 *	@Param  - Pointer to the semaphore that is being signaled
 */
void mysem_signal(Semaphore* sem){
	DISABLE_INTERRUPTS();
	sem->value++;
	if(sem->value <= 0){
		mythread_unblock(release_thread(sem));
		mysem_printQueue(sem);
	}
	ENABLE_INTERRUPTS();
}
Ejemplo n.º 4
0
int mythread_mutex_unlock (mythread_mutex_t *mutex)
{
  // if mutex is not pointing to anything valid then return EINVAL
  if (!mutex)
    return EINVAL;

  if (mutex->value == -1)
    return EINVAL;

  mythread_enter_kernel ();

  // set the mutex value to zero to indicate that mutex is available.
  mutex->value = 0;


  // unblock the next thread from the mutex queue waiting for the lock. 
  mythread_unblock (&mutex->queue, RUNNING);
  
  return 0; // success
}
Ejemplo n.º 5
0
int mythread_barrier_wait (mythread_barrier_t *barrier)
{

  // if barrier does not exist or if it was previously destroyed, then return error code.
  if (!barrier)
    return EINVAL;
  if (barrier->init_count == -1)
    return EINVAL;

  int i;
  mythread_enter_kernel();

  // A thread called wait, decrement the counter by 1. 
  if (barrier->count > 0)
    barrier->count--;

  // if this is the last thread calling the wait
  if (barrier->count == 0)
  {
    // reinitialize the barrier count before unblocking rest of threads, so that the barrier can be reused
    barrier->count = barrier->init_count;

    // there should exactly be (init_count - 1) number of threads in the queue at this point. Unblock all of them.  
    for (i = 0; i < barrier->init_count -1; i++)
    {
      mythread_unblock (&barrier->queue, 0);
      mythread_enter_kernel ();
    }

    mythread_leave_kernel();
    
    // only the last thread returns MYTHREAD_BARRIER_SERIAL_THREAD while rest of threads return 0. 
    return MYTHREAD_BARRIER_SERIAL_THREAD; // success
  }

 // if this is not the last thread calling wait, block the current thread. 
  else 
  mythread_block (&barrier->queue, 1);
  
  return 0; // success
}
/*
 * This function unblocks all the threads which are blocked on the conditional variable referenced by cond
 * Pre:A conditional variable on which threads are blocked
 * Post: All threads which are blocked on the conditional variable are unblocked
 * Returns:  1 on failure
 * 	     0 on success
 */
int mythread_cond_broadcast(mythread_cond_t * cond)
{
    if (futex_down(&ccb_table[*cond]->mutex)) {
	perror("failed to do futex_down\n");
	return 1;
    }
    /*
     * Remove each thread from head of the queue and wake up all the blocked threads.
     */    
    mythread_enter_kernel();
    while (ccb_table[*cond]->q != NULL) {
	mythread_unblock(&ccb_table[*cond]->q, 0);
        mythread_enter_kernel();
    }
    mythread_leave_kernel();
    /*
     * Resume any thread that is about to execute conditional wait
     */       
    if (futex_up(&ccb_table[*cond]->mutex)) {
	perror("failed to do futex_up\n");
	return 1;
    }
    return 0;
}