summaryrefslogtreecommitdiffstats
path: root/cpukit/posix/src/alarm.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-02-18 08:36:26 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-03-04 13:36:10 +0100
commit03b900d3ed120ea919ea3eded7edbece3488cff3 (patch)
tree182781fc14fe15fd67caeb80e46f1c58495839c2 /cpukit/posix/src/alarm.c
parentscore: Distribute clock tick to all online CPUs (diff)
downloadrtems-03b900d3ed120ea919ea3eded7edbece3488cff3.tar.bz2
score: Replace watchdog handler implementation
Use a red-black tree instead of delta chains. Close #2344. Update #2554. Update #2555. Close #2606.
Diffstat (limited to 'cpukit/posix/src/alarm.c')
-rw-r--r--cpukit/posix/src/alarm.c96
1 files changed, 52 insertions, 44 deletions
diff --git a/cpukit/posix/src/alarm.c b/cpukit/posix/src/alarm.c
index e85622fdf1..10443e4760 100644
--- a/cpukit/posix/src/alarm.c
+++ b/cpukit/posix/src/alarm.c
@@ -22,29 +22,18 @@
#endif
#include <unistd.h>
+#include <signal.h>
-#include <rtems/posix/pthreadimpl.h>
-#include <rtems/posix/psignalimpl.h>
-#include <rtems/score/threaddispatch.h>
#include <rtems/score/todimpl.h>
#include <rtems/score/watchdogimpl.h>
-/*
- * _POSIX_signals_Alarm_TSR
- */
-static void _POSIX_signals_Alarm_TSR(
- Objects_Id id RTEMS_UNUSED,
- void *argument RTEMS_UNUSED
-)
+ISR_LOCK_DEFINE( static, _POSIX_signals_Alarm_lock, "POSIX Alarm" )
+
+static void _POSIX_signals_Alarm_TSR( Watchdog_Control *the_watchdog )
{
- #if defined(RTEMS_DEBUG)
- int status;
- #define KILL_STATUS status =
- #else
- #define KILL_STATUS (void)
- #endif
+ int status;
- KILL_STATUS kill( getpid(), SIGALRM );
+ status = kill( getpid(), SIGALRM );
#if defined(RTEMS_DEBUG)
/*
@@ -52,43 +41,62 @@ static void _POSIX_signals_Alarm_TSR(
* cautious.
*/
_Assert(status == 0);
+ #else
+ (void) status;
#endif
}
-static Watchdog_Control _POSIX_signals_Alarm_timer = WATCHDOG_INITIALIZER(
- _POSIX_signals_Alarm_TSR,
- 0,
- NULL
+static Watchdog_Control _POSIX_signals_Alarm_watchdog = WATCHDOG_INITIALIZER(
+ _POSIX_signals_Alarm_TSR
);
unsigned int alarm(
unsigned int seconds
)
{
- unsigned int remaining = 0;
- Watchdog_Control *the_timer;
- Watchdog_States state;
-
- the_timer = &_POSIX_signals_Alarm_timer;
-
- _Thread_Disable_dispatch();
-
- state = _Watchdog_Remove_seconds( the_timer );
- if ( state == WATCHDOG_ACTIVE ) {
- /*
- * The stop_time and start_time fields are snapshots of ticks since
- * boot. Since alarm() is dealing in seconds, we must account for
- * this.
- */
-
- remaining = the_timer->initial -
- ((the_timer->stop_time - the_timer->start_time) / TOD_TICKS_PER_SECOND);
+ unsigned int remaining;
+ Watchdog_Control *the_watchdog;
+ ISR_lock_Context lock_context;
+ ISR_lock_Context lock_context2;
+ Per_CPU_Control *cpu;
+ uint64_t now;
+ uint32_t ticks_per_second;
+ uint32_t ticks;
+
+ the_watchdog = &_POSIX_signals_Alarm_watchdog;
+ ticks_per_second = TOD_TICKS_PER_SECOND;
+ ticks = seconds * ticks_per_second;
+
+ _ISR_lock_ISR_disable_and_acquire(
+ &_POSIX_signals_Alarm_lock,
+ &lock_context
+ );
+
+ cpu = _Watchdog_Get_CPU( the_watchdog );
+ _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context2 );
+ now = cpu->Watchdog.ticks;
+
+ remaining = (unsigned long) _Watchdog_Cancel(
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
+ the_watchdog,
+ now
+ );
+
+ if ( ticks != 0 ) {
+ cpu = _Per_CPU_Get();
+ _Watchdog_Set_CPU( the_watchdog, cpu );
+ _Watchdog_Insert(
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_RELATIVE ],
+ the_watchdog,
+ now + ticks
+ );
}
- if ( seconds )
- _Watchdog_Insert_seconds( the_timer, seconds );
-
- _Thread_Enable_dispatch();
+ _Watchdog_Per_CPU_release_critical( cpu, &lock_context2 );
+ _ISR_lock_Release_and_ISR_enable(
+ &_POSIX_signals_Alarm_lock,
+ &lock_context
+ );
- return remaining;
+ return ( remaining + ticks_per_second - 1 ) / ticks_per_second;
}