summaryrefslogtreecommitdiffstats
path: root/cpukit/rtems
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-18 12:11:04 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-06-20 08:24:46 +0200
commitf6b7b7ba0ae31a7e0f4aace3ebec03e0623d2e40 (patch)
treea9770794691dfb7ea6128005675d6f5c49872160 /cpukit/rtems
parentsmptests/smpwakeafter01: New test (diff)
downloadrtems-f6b7b7ba0ae31a7e0f4aace3ebec03e0623d2e40.tar.bz2
score: Fix _Thread_Delay_ended() on SMP
Suppose we have two tasks A and B and two processors. Task A is about to delete task B. Now task B calls rtems_task_wake_after(1) on the other processor. Task B will block on the Giant lock. Task A progresses with the task B deletion until it has to wait for termination. Now task B obtains the Giant lock, sets its state to STATES_DELAYING, initializes its watchdog timer and waits. Eventually _Thread_Delay_ended() is called, but now _Thread_Get() returned NULL since the thread is already marked as deleted. Thus task B remained forever in the STATES_DELAYING state. Instead of passing the thread identifier use the thread control block directly via the watchdog user argument. This makes _Thread_Delay_ended() also a bit more efficient.
Diffstat (limited to 'cpukit/rtems')
-rw-r--r--cpukit/rtems/src/taskwakeafter.c4
-rw-r--r--cpukit/rtems/src/taskwakewhen.c12
-rw-r--r--cpukit/rtems/src/timerserver.c8
3 files changed, 13 insertions, 11 deletions
diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c
index 88de6e51a8..6f0322723a 100644
--- a/cpukit/rtems/src/taskwakeafter.c
+++ b/cpukit/rtems/src/taskwakeafter.c
@@ -42,8 +42,8 @@ rtems_status_code rtems_task_wake_after(
_Watchdog_Initialize(
&executing->Timer,
_Thread_Delay_ended,
- executing->Object.id,
- NULL
+ 0,
+ executing
);
_Watchdog_Insert_ticks( &executing->Timer, ticks );
}
diff --git a/cpukit/rtems/src/taskwakewhen.c b/cpukit/rtems/src/taskwakewhen.c
index 01e855a125..a1fc15f047 100644
--- a/cpukit/rtems/src/taskwakewhen.c
+++ b/cpukit/rtems/src/taskwakewhen.c
@@ -29,6 +29,7 @@ rtems_status_code rtems_task_wake_when(
)
{
Watchdog_Interval seconds;
+ Thread_Control *executing;
if ( !_TOD_Is_set() )
return RTEMS_NOT_DEFINED;
@@ -47,15 +48,16 @@ rtems_status_code rtems_task_wake_when(
return RTEMS_INVALID_CLOCK;
_Thread_Disable_dispatch();
- _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
+ executing = _Thread_Executing;
+ _Thread_Set_state( executing, STATES_WAITING_FOR_TIME );
_Watchdog_Initialize(
- &_Thread_Executing->Timer,
+ &executing->Timer,
_Thread_Delay_ended,
- _Thread_Executing->Object.id,
- NULL
+ 0,
+ executing
);
_Watchdog_Insert_seconds(
- &_Thread_Executing->Timer,
+ &executing->Timer,
seconds - _TOD_Seconds_since_epoch()
);
_Thread_Enable_dispatch();
diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c
index 76c7a3fe79..7523ebcdf4 100644
--- a/cpukit/rtems/src/timerserver.c
+++ b/cpukit/rtems/src/timerserver.c
@@ -551,14 +551,14 @@ rtems_status_code rtems_timer_initiate_server(
_Watchdog_Initialize(
&ts->Interval_watchdogs.System_watchdog,
_Thread_Delay_ended,
- id,
- NULL
+ 0,
+ ts->thread
);
_Watchdog_Initialize(
&ts->TOD_watchdogs.System_watchdog,
_Thread_Delay_ended,
- id,
- NULL
+ 0,
+ ts->thread
);
/*