Ejemplo n.º 1
0
OS_RESULT os_mut_wait (OS_ID mutex, U16 timeout) {
  /* Wait for a mutex, continue when mutex is free. */
  P_MUCB p_MCB = mutex;

  tsk_lock();
  if (p_MCB->level == 0) {
    p_MCB->owner = os_runtask;
    p_MCB->prio  = os_runtask->prio;
    goto inc;
  }
  if (p_MCB->owner == os_runtask) {
    /* OK, running task is the owner of this mutex. */
inc:p_MCB->level++;
    tsk_unlock();
    return (OS_R_OK);
  }
  /* Mutex owned by another task, wait until released. */
  if (timeout == 0) {
    goto rto;
  }
  /* Raise the owner task priority if lower than current priority. */
  /* This priority inversion is called priority inheritance.       */
  if (p_MCB->prio < os_runtask->prio) {
    p_MCB->owner->prio = os_runtask->prio;
    os_resort_prio (p_MCB->owner);
  }
  if (p_MCB->p_lnk != NULL) {
    os_put_prio ((P_XCB)p_MCB, os_runtask);
  }
  else {
    p_MCB->p_lnk = os_runtask;
    os_runtask->p_lnk  = NULL;
    os_runtask->p_rlnk = (P_TCB)p_MCB;
  }
  if (os_block(timeout, WAIT_MUT) == OS_R_TMO) {
rto:tsk_unlock();
    return (OS_R_TMO);
  }
  /* A mutex has been released. */
  tsk_unlock();
  return (OS_R_MUT);
}
Ejemplo n.º 2
0
OS_RESULT os_tsk_prio (OS_TID task_id, U8 new_prio) {
  /* Change execution priority of a task to "new_prio". */
  P_TCB p_task;

  tsk_lock();
  if (task_id == 0) {
    /* Change execution priority of calling task. */
    os_runtask->prio      = new_prio;
    os_runtask->prio_base = new_prio;
run:if (os_rdy_prio() > new_prio) {
      os_put_prio (&os_rdy, os_runtask);
      os_runtask->state = READY;
      os_dispatch (NULL);
    }
    tsk_unlock();
    return (OS_R_OK);
  }

  /* Find the task in the "os_active_TCB" array. */
  if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
    /* Task with "task_id" not found or not started. */
    tsk_unlock ();
    return (OS_R_NOK);
  }
  p_task = os_active_TCB[task_id-1];
  p_task->prio      = new_prio;
  p_task->prio_base = new_prio;
  if (p_task == os_runtask) {
    goto run;
  }
  os_resort_prio (p_task);
  if (p_task->state == READY) {
    /* Task enqueued in a ready list. */
    p_task = os_get_first (&os_rdy);
    os_dispatch (p_task);
  }
  tsk_unlock ();
  return (OS_R_OK);
}