File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include <signal.h>
0042 #include <unistd.h>
0043
0044 #include <rtems/score/todimpl.h>
0045 #include <rtems/score/watchdogimpl.h>
0046 #include <rtems/config.h>
0047
0048 #if ISR_LOCK_NEEDS_OBJECT
0049 static ISR_lock_Control _POSIX_signals_Ualarm_lock =
0050 ISR_LOCK_INITIALIZER( "POSIX Ualarm" );
0051 #endif
0052
0053 static uint32_t _POSIX_signals_Ualarm_interval;
0054
0055 static void _POSIX_signals_Ualarm_TSR( Watchdog_Control *the_watchdog )
0056 {
0057 int status;
0058 ISR_lock_Context lock_context;
0059
0060 status = kill( getpid(), SIGALRM );
0061
0062 #if defined(RTEMS_DEBUG)
0063
0064
0065
0066
0067 _Assert(status == 0);
0068 #else
0069 (void) status;
0070 #endif
0071
0072 _ISR_lock_ISR_disable_and_acquire(
0073 &_POSIX_signals_Ualarm_lock,
0074 &lock_context
0075 );
0076
0077
0078
0079
0080 if ( _POSIX_signals_Ualarm_interval != 0 ) {
0081 _Watchdog_Per_CPU_insert_ticks(
0082 the_watchdog,
0083 _Per_CPU_Get(),
0084 _POSIX_signals_Ualarm_interval
0085 );
0086 }
0087
0088 _ISR_lock_Release_and_ISR_enable(
0089 &_POSIX_signals_Ualarm_lock,
0090 &lock_context
0091 );
0092 }
0093
0094 static Watchdog_Control _POSIX_signals_Ualarm_watchdog = WATCHDOG_INITIALIZER(
0095 _POSIX_signals_Ualarm_TSR
0096 );
0097
0098 static uint32_t _POSIX_signals_Ualarm_us_to_ticks( useconds_t us )
0099 {
0100 uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
0101
0102 return ( us + us_per_tick - 1 ) / us_per_tick;
0103 }
0104
0105 useconds_t ualarm(
0106 useconds_t useconds,
0107 useconds_t interval
0108 )
0109 {
0110 useconds_t remaining;
0111 Watchdog_Control *the_watchdog;
0112 ISR_lock_Context lock_context;
0113 ISR_lock_Context lock_context2;
0114 Per_CPU_Control *cpu;
0115 uint64_t now;
0116 uint32_t ticks_initial;
0117 uint32_t ticks_interval;
0118
0119 the_watchdog = &_POSIX_signals_Ualarm_watchdog;
0120 ticks_initial = _POSIX_signals_Ualarm_us_to_ticks( useconds );
0121 ticks_interval = _POSIX_signals_Ualarm_us_to_ticks( interval );
0122
0123 _ISR_lock_ISR_disable_and_acquire(
0124 &_POSIX_signals_Ualarm_lock,
0125 &lock_context
0126 );
0127
0128 cpu = _Watchdog_Get_CPU( the_watchdog );
0129 _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context2 );
0130 now = cpu->Watchdog.ticks;
0131
0132 remaining = (useconds_t) _Watchdog_Cancel(
0133 &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
0134 the_watchdog,
0135 now
0136 );
0137
0138 if ( ticks_initial != 0 ) {
0139 _POSIX_signals_Ualarm_interval = ticks_interval;
0140
0141 cpu = _Per_CPU_Get();
0142 _Watchdog_Set_CPU( the_watchdog, cpu );
0143 _Watchdog_Insert(
0144 &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
0145 the_watchdog,
0146 now + ticks_initial
0147 );
0148 }
0149
0150 _Watchdog_Per_CPU_release_critical( cpu, &lock_context2 );
0151 _ISR_lock_Release_and_ISR_enable(
0152 &_POSIX_signals_Ualarm_lock,
0153 &lock_context
0154 );
0155
0156 remaining *= rtems_configuration_get_microseconds_per_tick();
0157
0158 return remaining;
0159 }