Пример #1
0
/**
 * @brief Puts a task to sleep on the sleep queue until the next
 * event is signalled for the device.
 *
 * @param dev  Device number.
 */
int dev_wait(unsigned int dev __attribute__((unused)))
{
	disable_interrupts();

  	tcb_t* cur_tcb = get_cur_tcb();
    if(cur_tcb->holds_lock !=0){
        return -EHOLDSLOCK;
    }
 	tcb_t* sleep_queue = devices[dev].sleep_q;
  	if(sleep_queue == 0)
	{
		devices[dev].sleep_q = cur_tcb;
		devices[dev].sleep_q -> sleep_queue = 0;
	}
	else{
		while(sleep_queue -> sleep_queue !=0)
			sleep_queue = sleep_queue -> sleep_queue;
		sleep_queue->sleep_queue = cur_tcb;
		sleep_queue = sleep_queue-> sleep_queue;
		sleep_queue -> sleep_queue =0;
	}

  	dispatch_sleep();
	enable_interrupts();
	
	return 0;
}
Пример #2
0
int mutex_lock(int mutex  __attribute__((unused)))
{
    tcb_t* temp;
    
    disable_interrupts();

    // if the provided mutex identifier if invalid
    if(mutex > OS_NUM_MUTEX ||
            gtMutex[mutex].bAvailable == TRUE) {
        
        enable_interrupts();
        return -EINVAL;
    
    } 

    if(gtMutex[mutex].pHolding_Tcb == get_cur_tcb()) {

        // if the current task is already holding the lock
        enable_interrupts();
        return -EDEADLOCK;

    } else {
        if(gtMutex[mutex].bLock == 0) {
            // if the lock is not been locked
            // set lock status and holding tcb
            gtMutex[mutex].bLock = 1;
            gtMutex[mutex].pHolding_Tcb = get_cur_tcb();
            get_cur_tcb()->holds_lock = 1;
            #ifdef HLP
            get_cur_tcb()->cur_prio = 0;
            #endif // HLP
            gtMutex[mutex].pSleep_queue = 0;
            enable_interrupts();
            return 0;

        } else {
            // if the lock is been locked
            // move the current tack to mutex sleeping queue
            temp = gtMutex[mutex].pSleep_queue;

            if (temp == 0)
            {
                gtMutex[mutex].pSleep_queue = get_cur_tcb();
            } else {
                // put current tcb at the end of the mutex sleeping queue
                while((temp->sleep_queue) != 0) {
                    temp = temp->sleep_queue;
                }
                temp->sleep_queue = get_cur_tcb();
            }

            // context switch to another task
            dispatch_sleep();
        }
    }

    // the function cannot get here
    return 1; 
}
Пример #3
0
int mutex_lock(int mutex  __attribute__((unused)))
{
	disable_interrupts();

	/* invalid mutex id, return error code */
	if(mutex < 0 || mutex >= OS_NUM_MUTEX || gtMutex[mutex].bAvailable){
		enable_interrupts();
		return -EINVAL;
	}
	else{
		tcb_t* cur_tcb = get_cur_tcb();
		/* current task is already holding the lock, return error code */
		if(cur_tcb == gtMutex[mutex].pHolding_Tcb){
			enable_interrupts();
			return -EDEADLOCK;
		}
		/* lock is holding by others, put current task to sleep */
		else if(gtMutex[mutex].bLock){
			/* put the task into sleep queue */
			if(gtMutex[mutex].pSleep_queue == NULL){
				gtMutex[mutex].pSleep_queue = cur_tcb;
				cur_tcb->sleep_queue = NULL;
			}
			else{
				tcb_t* tmp = gtMutex[mutex].pSleep_queue;
				while(tmp->sleep_queue != NULL){
					tmp = tmp->sleep_queue;
				}
				tmp->sleep_queue = cur_tcb;
				cur_tcb->sleep_queue = NULL;
			}
			/* sleep & context switch */
			dispatch_sleep();
		}
		/* no one's holding it, get go! */
		gtMutex[mutex].pHolding_Tcb = cur_tcb;
		gtMutex[mutex].bLock = TRUE;

		cur_tcb->holds_lock ++;
		//cur_tcb->native_prio = cur_tcb->cur_prio;
		//cur_tcb->cur_prio = 0;

		enable_interrupts();
		return 0;
	}
}
Пример #4
0
int mutex_lock(int mutex_num)
{
	if(debug_enabled1 == 1) printf("\tmutex::mutex_lock:: lock(%d) by tcb %d\n", mutex_num, get_cur_tcb()->cur_prio);
	
	disable_interrupts();
	
	//check for valid mutex number
	if(mutex_num < 0 || mutex_num > mutexID) return -EINVAL;
	
	//mutex is valid
	mutex_t* mutex = &gtMutex[mutex_num-1]; //mutex we are referencing

	//mutex is available
	if(mutex->bAvailable == TRUE) {
		//acquire  mutex
		mutex->bLock = 		TRUE;
		mutex->bAvailable = 	FALSE;
		mutex->pHolding_Tcb = 	get_cur_tcb();
		get_cur_tcb()->holds_lock++;
		enable_interrupts();
		return 0; //success
	}
	//mutex is not available
	else
	{
		//if current task is already holding it
		if(mutex->pHolding_Tcb == get_cur_tcb()) return -EDEADLOCK;
		
		//if the sleep queue is empty
		if( mutex->pSleep_queue == NULL_TCB ) mutex->pSleep_queue = get_cur_tcb();
		//else sleep queue is not empty
		else
		{
			//add to the end of the queue
			tcb_t* t = mutex->pSleep_queue;
			while(t->sleep_queue != NULL_TCB) t = t->sleep_queue;
			t->sleep_queue = get_cur_tcb();
		}
	}

	//sleep and wait..`
	dispatch_sleep();
	enable_interrupts();
	return 0; //success
}
Пример #5
0
/**
 * @brief Puts a task to sleep on the sleep queue until the next
 * event is signalled for the device.
 *
 * @param dev  Device number.
 */
int dev_wait(unsigned int dev __attribute__((unused)))
{
  tcb_t* cur_tcb;
  tcb_t* sleepQ;

  disable_interrupts();

  // get current tcb and sleep devices on sleep queue
  cur_tcb = get_cur_tcb();
  sleepQ = devices[dev].sleep_queue;
  // if task is holding a lock, return error
  if (cur_tcb->holds_lock != 0)
    return -EHOLDSLOCK;
  // add cur_tcb to head of sleep queue linked list
  devices[dev].sleep_queue = cur_tcb;
  cur_tcb->sleep_queue = sleepQ;
  // dispatch to next task
  dispatch_sleep();
  return 0;
}
/*                                                                              
------------------------------------------------                                
Function: mutex_lock                                                         
Description:                                                                    
Locks the mutex if no process currently holds the 
mutex, else puts the current process in sleep queue.
------------------------------------------------                                
*/     
int mutex_lock(int mutex)
{	
	tcb_t* cur_tcb;

	/*Getting currrently running TCB*/
	cur_tcb = get_cur_tcb();		
	
	if (mutex<1 || mutex>OS_NUM_MUTEX || (gtMutex[mutex-1].bAvailable!=1)) {
		return -EINVAL;
	}
	if (gtMutex[mutex-1].pHolding_Tcb == cur_tcb) {
		return -EDEADLOCK;
	}

	/*Locking the current mutex, if available*/
	if (gtMutex[mutex-1].bLock == 0) {
		gtMutex[mutex-1].pHolding_Tcb = cur_tcb;
		gtMutex[mutex-1].bLock = 1;
		gtMutex[mutex-1].pHolding_Tcb->holds_lock = 1;
		cur_tcb->cur_prio = 0;		
		return 0;
	}
	/* adding process to mutex sleep queue */
	else {		
		/* If initial sleep queue is empty*/		
		if (gtMutex[mutex-1].pSleep_queue == 0){
			cur_tcb->sleep_queue = 0;
			gtMutex[mutex-1].pSleep_queue = cur_tcb;
			rear[mutex-1] = cur_tcb;
		} 
		else {
			/* Attaching current head to new del_tcb and updating head*/
			cur_tcb->sleep_queue = 0;
			rear[mutex-1]->sleep_queue = cur_tcb;
			rear[mutex-1] = cur_tcb;
		}	
		dispatch_sleep();		
		return 0; 
	}
	return 0;
}
Пример #7
0
/**
 * @brief Puts a task to sleep on the sleep queue until the next
 * event is signalled for the device.
 *
 * @param dev  Device number.
 */
int dev_wait(unsigned int dev)
{   
    disable_interrupts();
    // get the current task's tcb, no need to handle fault dev
    tcb_t* current_task_tcb = get_cur_tcb();

    // check if the current task holds any mutex
    if (current_task_tcb->cur_prio == HLP_PRIO) {
        printf("current taks has mutex on hand, cannot sleep!\n");
        return EHOLDSLOCK;
    }

    // insert the task on the head of device sleep queue
    current_task_tcb->sleep_queue = devices[dev].sleep_queue;
    devices[dev].sleep_queue = current_task_tcb;

    // make it sleep
    dispatch_sleep();
    
    return 0;
}
Пример #8
0
int event_wait(unsigned int dev_num) {
    // Sanity checks
    if (dev_num >= NUM_DEVICES) return -EINVAL;
    
    // Prevent curr_tcb from being modified by device_update.
    INT_ATOMIC_START;
    
    // Prevent tasks from waiting if they have a mutex.
    if (curr_tcb->locks_held != 0) return -EHOLDSLOCK;
    
    // Restore device priority to its native priority.
    curr_tcb->curr_prio = curr_tcb->native_prio;
    
    // Put calling task on the device queue.
    dev_enqueue(curr_tcb, dev_num);
    
    // Sleep current task.
    dispatch_sleep();
    
    INT_ATOMIC_END;
    
    return 0;
}
Пример #9
0
int mutex_lock(int mutex  __attribute__((unused)))
{ 
  // Get the current task
  tcb_t* cur_tcb = get_cur_tcb();
  mutex_t* cur_mutex = &(gtMutex[mutex]);
 
  // Check if mutex is in range
  if((mutex <0) || (mutex >= OS_NUM_MUTEX)) return EINVAL;

  // Check if deadlock error
  if(cur_tcb == gtMutex[mutex].pHolding_Tcb) return EDEADLOCK;

  // Disable interrupts
  disable_interrupts();

  // If mutex is locked (blocked), wait until freed up by sleeping
  while(cur_mutex->bLock == 1){
    // Enable interrupts
    enable_interrupts();
    
    dispatch_sleep();
    
    //Disable interrupts
    disable_interrupts();
  }
  
  // Set holding Tcb to current task, set bLock = TRUE, give curr\ent task highest priority, set cur tasks's "holds_lock" val to 1
  cur_mutex->bLock = 1;
    cur_mutex->pHolding_Tcb = cur_tcb;
    cur_tcb->cur_prio = highest_prio();
    cur_tcb->holds_lock = 1;

    // Enable Interrupts
    enable_interrupts();

    return 0;
}
Пример #10
0
int mutex_lock(int mutex  __attribute__((unused)))
{
    disable_interrupts();
    tcb_t* cur_tcb = get_cur_tcb();
    uint8_t cur_prio = get_cur_prio();
    tcb_t* sleep_queue, *temp;
    mutex_t *cur_mutex = &(gtMutex[mutex]);


    /* check if provided mutex identifier is valid */
    if(mutex > num_mutices)
    {
        enable_interrupts();
        return EINVAL;
    }

    /* check if current task is holding the mutex */
    if(cur_mutex->pHolding_Tcb == cur_tcb)
    {
        enable_interrupts();
        return EDEADLOCK;
    }


    /* check if sleep queue is empty */
    if(cur_mutex->pSleep_queue == 0)
    {
        cur_mutex->pSleep_queue = cur_tcb;
        cur_tcb->sleep_queue = 0;
    }

    /* insert task at appropriate location in sleep queue */
    else
    {
        sleep_queue = cur_mutex->pSleep_queue;
        temp = sleep_queue;

        /* insert at front of the list */
        if(cur_prio < (sleep_queue->cur_prio))
        {
            cur_tcb->sleep_queue = cur_mutex->pSleep_queue;
            cur_mutex->pSleep_queue = cur_tcb;
        }
        else
        {
            sleep_queue = sleep_queue->sleep_queue;
            while(sleep_queue != 0)
            {
                if(cur_prio < (sleep_queue->cur_prio))
                {
                    cur_tcb->sleep_queue = sleep_queue;
                    temp->sleep_queue = cur_tcb;
                    break;
                }
                temp = sleep_queue;
                sleep_queue = sleep_queue->sleep_queue;
            }
        }
    }

    disable_interrupts();
    dispatch_sleep();
    enable_interrupts();

    return 0;
}