Ejemplo n.º 1
0
int mythread_mutex_lock(mythread_mutex_t *mutex)
{
	int lockstatus;

	mythread_enter_kernel();
	mutex->noofwaitingthreads=mutex->noofwaitingthreads+1;
	mythread_leave_kernel();

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

	lockstatus=testandtestandset(&(mutex->lockvariable)); // a lockstatus of 0 denotes a successful acquiring of lock 
	
	while(lockstatus==1) // if the lock acquiring fails after 100 tries , then the thread is blocked and put in a queue until lock becomes available
	{
		mythread_enter_kernel();
		mutex->noofblockedthreads=mutex->noofblockedthreads+1;
		mythread_block((mutex->blocked_threads),0);// actual 0
		lockstatus=testandtestandset(&(mutex->lockvariable)); // thread that returns from the block state tries to acquire the lock again
	}

	mythread_enter_kernel();
	mutex->owner_thread=mythread_self();
	mythread_leave_kernel();
	return lockstatus;
}
Ejemplo n.º 2
0
int mythread_scheduler(){
	mythread_t self = mythread_self();
	/*Limiting number of priority queues to 10 */

	if(self->preemptions < 10){
		self->preemptions += 1;
	}
	self->attr.attr = pow(2,self->preemptions); /*Since preemptions = invocation -1  */
	mythread_block(mythread_readyq(),1);
	return 0;	
}
Ejemplo n.º 3
0
/*
 *	Will block the thread if needed, otherwise will just decrement
 *	   the semaphore's value
 *
 *	@Param  - Pointer to the semaphore that will impose waiting
 */
void mysem_wait(Semaphore* sem){
	DISABLE_INTERRUPTS();
	sem->value--;
	tcb* currentThread = get_mythread();
	if(sem->value < 0){
		mythread_block(currentThread);
		block_thread(sem, currentThread);
		mysem_printQueue(sem);
	}
	ENABLE_INTERRUPTS();
	// Stall the thread until the thread becomes READY
	while(currentThread->state==BLOCKED){
		asm("nop");
	}
}
Ejemplo n.º 4
0
int mythread_mutex_lock (mythread_mutex_t *mutex)
{
  // if mutex is not poinitng to anything valid then return EINVAL
  if (!mutex)
    return EINVAL;

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


  int retry = 0;
  while (1)
  {
    mythread_enter_kernel();
    // check if lock is available for atmost 50 times
    while ((mutex->value == 1) && (retry < RETRY_MAX))
    {
       retry++;
    }

    // if we waited for 50 times and lock still not avaialable then break from he loop and block the current thread.
    if (retry == RETRY_MAX)
    {
      break;
    }
    
    // if lock is avaialable, grab it atomically using compare and swap function  
    if (compare_and_swap (&mutex->value, 1, 0)==0)
    {
      // update the current owner to mutex to current thread
      mutex->thread = mythread_self();
      mythread_leave_kernel();

      return 0; // success
    }    
  } // end of while loop
  
 // if lock is not available after 50 tries, block the current thread.
  mythread_block (&mutex->queue, BLOCKED);
  
  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
}