コード例 #1
0
ファイル: tn_tasks.c プロジェクト: KWinter291/TNKernel-PIC32
//----------------------------------------------------------------------------
int task_wait_complete(TN_TCB * task) //-- v. 2.6
{
#ifdef USE_MUTEXES
   int fmutex;
   int curr_priority;
   TN_MUTEX * mutex;
   TN_TCB * mt_holder_task;
   CDLL_QUEUE * t_que;
#endif
   int rc = FALSE;

   if(task == NULL)
      return 0;

#ifdef USE_MUTEXES

   t_que = NULL;
   if(task->task_wait_reason == TSK_WAIT_REASON_MUTEX_I ||
         task->task_wait_reason == TSK_WAIT_REASON_MUTEX_C)
   {
      fmutex = TRUE;
      t_que = task->pwait_queue;
   }
   else
      fmutex = FALSE;

#endif

   task->pwait_queue  = NULL;
   task->task_wait_rc = TERR_NO_ERR;

   if(task->tick_count != TN_WAIT_INFINITE)
      queue_remove_entry(&(task->timer_queue));

   task->tick_count = TN_WAIT_INFINITE;

   if(!(task->task_state & TSK_STATE_SUSPEND))
   {
      task_to_runnable(task);
      rc = TRUE;
   }
   else  //-- remove WAIT state
      task->task_state = TSK_STATE_SUSPEND;


#ifdef USE_MUTEXES

   if(fmutex)
   {
      mutex = get_mutex_by_wait_queque(t_que);

      mt_holder_task = mutex->holder;
      if(mt_holder_task != NULL)
      {
         //-- if task was blocked by another task and its pri was changed
         //--  - recalc current priority

         if(mt_holder_task->priority != mt_holder_task->base_priority &&
             mt_holder_task->priority == task->priority)
         {
            curr_priority = find_max_blocked_priority(mutex,
                                             mt_holder_task->base_priority);

            set_current_priority(mt_holder_task, curr_priority);
            rc = TRUE;
         }
      }
   }
#endif

   task->task_wait_reason = 0; //-- Clear wait reason

   return rc;
}
コード例 #2
0
ファイル: mx_rtn_dulm.c プロジェクト: Sav0966/qmlab-pic24
/**
 *
 * @param mutex
 *
 * @return TN_BOOL
 */
TN_BOOL do_unlock_mutex (TN_MUTEX_S *mutex)
{
    CDLL_QUEUE_S *curr_que;
    TN_MUTEX_S   *tmp_mutex;
    TN_TCB_S     *task;
    TN_TCB_S     *hi_pri_task = TN_NULL;
    TN_TCB_S     *blk_task;
    TN_TCB_S     *tmp_task;
    TN_UWORD     priority;
    TN_UWORD     pr;
    TN_BOOL      need_switch_context = TN_FALSE;

    queue_remove_entry(&(mutex->mutex_queue));
    queue_remove_entry(&(mutex->lock_mutex_queue));

    if (is_queue_empty(&(tn_curr_run_task->mutex_queue)))
    {
        need_switch_context = set_current_priority(tn_curr_run_task, tn_curr_run_task->base_priority);
    }
    else
    {
        if (mutex->attr == TN_MUTEX_ATTR_INHERIT  ||
            mutex->attr == TN_MUTEX_ATTR_CEILING
           )
        {
            pr       = tn_curr_run_task->base_priority;
            curr_que = tn_curr_run_task->mutex_queue.next;

            for (;;)
            {
                tmp_mutex = get_mutex_by_mutex_queue(curr_que);
                pr        = find_max_blocked_priority(tmp_mutex,pr);

                if (curr_que->next == &(tn_curr_run_task->mutex_queue))
                    break;
                else
                {
                    curr_que = curr_que->next;
                }
            }

            if (pr != tn_curr_run_task->priority)
            {
                need_switch_context = set_current_priority(tn_curr_run_task,pr);
            }
        }
    }

    if (is_queue_empty(&(mutex->wait_queue)))
    {
        mutex->holder = TN_NULL;
        hi_pri_task   = tn_curr_run_task;
    }
    else
    {
        if (mutex->attr == TN_MUTEX_ATTR_CEILING)
        {
            priority = TN_NUM_PRIORITY - 1;
            curr_que = mutex->wait_queue.next;

            for (;;)
            {
                task = get_task_by_tsk_queue(curr_que);

                if (task->priority < priority)
                {
                    hi_pri_task = task;
                    priority    = task->priority;
                }
                if (curr_que->next == &(mutex->wait_queue))
                    break;
                else
                    curr_que = curr_que->next;
            }

            if (enable_lock_mutex(hi_pri_task,&blk_task))
            {
                queue_remove_entry(&(hi_pri_task->task_queue));
                remove_task_from_blocked_list(hi_pri_task);

                if (task_wait_complete(hi_pri_task, TN_FALSE))
                    need_switch_context = TN_TRUE;

                mutex->holder         = hi_pri_task;
                hi_pri_task->blk_task = TN_NULL;

                queue_add_tail(&(hi_pri_task->mutex_queue),&(mutex->mutex_queue));
                queue_add_tail(&tn_locked_mutexes_list,&(mutex->lock_mutex_queue));
            }
            else
            {
                if (!queue_contains_entry(&tn_blocked_tasks_list, &(hi_pri_task->block_queue)))
                {
                    queue_add_tail(&tn_blocked_tasks_list,&(hi_pri_task->block_queue));
                    hi_pri_task->task_wait_reason = TSK_WAIT_REASON_MUTEX_C_BLK;
                    hi_pri_task->blk_task         = blk_task;
                }
            }
        }
        else if (mutex->attr == TN_MUTEX_ATTR_INHERIT)
        {
            curr_que = queue_remove_head(&(mutex->wait_queue));
            task     = get_task_by_tsk_queue(curr_que);

            if (task_wait_complete(task, TN_FALSE))
                need_switch_context = TN_TRUE;

            mutex->holder = task;

            queue_add_tail(&(task->mutex_queue),&(mutex->mutex_queue));
/*--- v.2.3 */
            queue_add_tail(&tn_locked_mutexes_list,&(mutex->lock_mutex_queue));
/*---       */
        }
    }

    if (mutex->holder == TN_NULL && mutex->attr == TN_MUTEX_ATTR_CEILING)
    {
        if (!is_queue_empty(&tn_blocked_tasks_list))
        {
            curr_que = tn_blocked_tasks_list.next;
            for (;;)
            {
                tmp_task = get_task_by_block_queue(curr_que);
    
                if (tmp_task != hi_pri_task)
                {
                    if (try_lock_mutex(tmp_task))
                    {
                        need_switch_context = TN_TRUE;
                    }
                }
                if (curr_que->next == &tn_blocked_tasks_list)
                    break;
                else
                    curr_que = curr_que->next;
            }
        }
    }

    return need_switch_context;
}