mdot_rtos
Fork of mbed-rtos by
Diff: rtx/TARGET_CORTEX_A/rt_Task.c
- Revision:
- 92:bc9729798a19
- Parent:
- 68:d3d0e710b443
--- a/rtx/TARGET_CORTEX_A/rt_Task.c Wed Sep 16 11:15:38 2015 +0100
+++ b/rtx/TARGET_CORTEX_A/rt_Task.c Fri Sep 25 13:30:34 2015 +0100
@@ -3,10 +3,10 @@
*----------------------------------------------------------------------------
* Name: RT_TASK.C
* Purpose: Task functions and system start up.
- * Rev.: V4.60
+ * Rev.: V4.73
*----------------------------------------------------------------------------
*
- * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
+ * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -79,10 +79,12 @@
p_TCB->cb_type = TCB;
p_TCB->state = READY;
p_TCB->prio = priority;
+ p_TCB->prio_base = priority;
p_TCB->p_lnk = NULL;
p_TCB->p_rlnk = NULL;
p_TCB->p_dlnk = NULL;
p_TCB->p_blnk = NULL;
+ p_TCB->p_mlnk = NULL;
p_TCB->delta_time = 0;
p_TCB->interval_time = 0;
p_TCB->events = 0;
@@ -101,7 +103,7 @@
void rt_switch_req (P_TCB p_new) {
/* Switch to next task (identified by "p_new"). */
- os_tsk.new = p_new;
+ os_tsk.new_tsk = p_new;
p_new->state = RUNNING;
DBG_TASK_SWITCH(p_new->task_id);
}
@@ -188,6 +190,7 @@
if (task_id == 0) {
/* Change execution priority of calling task. */
os_tsk.run->prio = new_prio;
+ os_tsk.run->prio_base = new_prio;
run:if (rt_rdy_prio() > new_prio) {
rt_put_prio (&os_rdy, os_tsk.run);
os_tsk.run->state = READY;
@@ -203,6 +206,7 @@
}
p_task = os_active_TCB[task_id-1];
p_task->prio = new_prio;
+ p_task->prio_base = new_prio;
if (p_task == os_tsk.run) {
goto run;
}
@@ -254,12 +258,40 @@
OS_RESULT rt_tsk_delete (OS_TID task_id) {
/* Terminate the task identified with "task_id". */
P_TCB task_context;
+ P_TCB p_TCB;
+ P_MUCB p_MCB, p_MCB0;
if (task_id == 0 || task_id == os_tsk.run->task_id) {
/* Terminate itself. */
os_tsk.run->state = INACTIVE;
os_tsk.run->tsk_stack = rt_get_PSP ();
rt_stk_check ();
+ p_MCB = os_tsk.run->p_mlnk;
+ while (p_MCB) {
+ /* Release mutexes owned by this task */
+ if (p_MCB->p_lnk) {
+ /* A task is waiting for mutex. */
+ p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+ rt_ret_val(p_TCB, 0/*osOK*/);
+#else
+ rt_ret_val(p_TCB, OS_R_MUT);
+#endif
+ rt_rmv_dly (p_TCB);
+ p_TCB->state = READY;
+ rt_put_prio (&os_rdy, p_TCB);
+ /* A waiting task becomes the owner of this mutex. */
+ p_MCB0 = p_MCB;
+ p_MCB->level = 1;
+ p_MCB->owner = p_TCB;
+ p_MCB->p_mlnk = p_TCB->p_mlnk;
+ p_TCB->p_mlnk = p_MCB;
+ p_MCB = p_MCB0->p_mlnk;
+ }
+ else {
+ p_MCB = p_MCB->p_mlnk;
+ }
+ }
os_active_TCB[os_tsk.run->task_id-1] = NULL;
rt_free_box (mp_stk, os_tsk.run->stack);
os_tsk.run->stack = NULL;
@@ -278,11 +310,43 @@
task_context = os_active_TCB[task_id-1];
rt_rmv_list (task_context);
rt_rmv_dly (task_context);
+ p_MCB = task_context->p_mlnk;
+ while (p_MCB) {
+ /* Release mutexes owned by this task */
+ if (p_MCB->p_lnk) {
+ /* A task is waiting for mutex. */
+ p_TCB = rt_get_first ((P_XCB)p_MCB);
+#ifdef __CMSIS_RTOS
+ rt_ret_val(p_TCB, 0/*osOK*/);
+#else
+ rt_ret_val(p_TCB, OS_R_MUT);
+#endif
+ rt_rmv_dly (p_TCB);
+ p_TCB->state = READY;
+ rt_put_prio (&os_rdy, p_TCB);
+ /* A waiting task becomes the owner of this mutex. */
+ p_MCB0 = p_MCB;
+ p_MCB->level = 1;
+ p_MCB->owner = p_TCB;
+ p_MCB->p_mlnk = p_TCB->p_mlnk;
+ p_TCB->p_mlnk = p_MCB;
+ p_MCB = p_MCB0->p_mlnk;
+ }
+ else {
+ p_MCB = p_MCB->p_mlnk;
+ }
+ }
os_active_TCB[task_id-1] = NULL;
rt_free_box (mp_stk, task_context->stack);
task_context->stack = NULL;
DBG_TASK_NOTIFY(task_context, __FALSE);
rt_free_box (mp_tcb, task_context);
+ if (rt_rdy_prio() > os_tsk.run->prio) {
+ /* Ready task has higher priority than running task. */
+ os_tsk.run->state = READY;
+ rt_put_prio (&os_rdy, os_tsk.run);
+ rt_dispatch (NULL);
+ }
}
return (OS_R_OK);
}
