source: rtems/cpukit/posix/src/ualarm.c @ 9480815a

5
Last change on this file since 9480815a was 9480815a, checked in by Sebastian Huber <sebastian.huber@…>, on 12/21/17 at 13:36:52

score: Introduce new monotonic clock

Rename PER_CPU_WATCHDOG_MONOTONIC to PER_CPU_WATCHDOG_TICKS. Add new
PER_CPU_WATCHDOG_MONOTONIC which is based on the system uptime (measured
by timecounter).

Close #3264.

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief Schedule Alarm
5 * @ingroup POSIXAPI
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <signal.h>
22#include <unistd.h>
23
24#include <rtems/score/todimpl.h>
25#include <rtems/score/watchdogimpl.h>
26#include <rtems/config.h>
27
28ISR_LOCK_DEFINE( static, _POSIX_signals_Ualarm_lock, "POSIX Ualarm" )
29
30static uint32_t _POSIX_signals_Ualarm_interval;
31
32static void _POSIX_signals_Ualarm_TSR( Watchdog_Control *the_watchdog )
33{
34  int              status;
35  ISR_lock_Context lock_context;
36
37  status = kill( getpid(), SIGALRM );
38
39  #if defined(RTEMS_DEBUG)
40    /*
41     *  There is no reason to think this might fail but we should be
42     *  cautious.
43     */
44    _Assert(status == 0);
45  #else
46    (void) status;
47  #endif
48
49  _ISR_lock_ISR_disable_and_acquire(
50    &_POSIX_signals_Ualarm_lock,
51    &lock_context
52  );
53
54  /*
55   * If the reset interval is non-zero, reschedule ourselves.
56   */
57  if ( _POSIX_signals_Ualarm_interval != 0 ) {
58    _Watchdog_Per_CPU_insert_ticks(
59      the_watchdog,
60      _Per_CPU_Get(),
61      _POSIX_signals_Ualarm_interval
62    );
63  }
64
65  _ISR_lock_Release_and_ISR_enable(
66    &_POSIX_signals_Ualarm_lock,
67    &lock_context
68  );
69}
70
71static Watchdog_Control _POSIX_signals_Ualarm_watchdog = WATCHDOG_INITIALIZER(
72  _POSIX_signals_Ualarm_TSR
73);
74
75static uint32_t _POSIX_signals_Ualarm_us_to_ticks( useconds_t us )
76{
77  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
78
79  return ( us + us_per_tick - 1 ) / us_per_tick;
80}
81
82useconds_t ualarm(
83  useconds_t useconds,
84  useconds_t interval
85)
86{
87  useconds_t        remaining;
88  Watchdog_Control *the_watchdog;
89  ISR_lock_Context  lock_context;
90  ISR_lock_Context  lock_context2;
91  Per_CPU_Control  *cpu;
92  uint64_t          now;
93  uint32_t          ticks_initial;
94  uint32_t          ticks_interval;
95
96  the_watchdog = &_POSIX_signals_Ualarm_watchdog;
97  ticks_initial = _POSIX_signals_Ualarm_us_to_ticks( useconds );
98  ticks_interval = _POSIX_signals_Ualarm_us_to_ticks( interval );
99
100  _ISR_lock_ISR_disable_and_acquire(
101    &_POSIX_signals_Ualarm_lock,
102    &lock_context
103  );
104
105  cpu = _Watchdog_Get_CPU( the_watchdog );
106  _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context2 );
107  now = cpu->Watchdog.ticks;
108
109  remaining = (useconds_t) _Watchdog_Cancel(
110    &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
111    the_watchdog,
112    now
113  );
114
115  if ( ticks_initial != 0 ) {
116    _POSIX_signals_Ualarm_interval = ticks_interval;
117
118    cpu = _Per_CPU_Get();
119    _Watchdog_Set_CPU( the_watchdog, cpu );
120    _Watchdog_Insert(
121      &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
122      the_watchdog,
123      now + ticks_initial
124    );
125  }
126
127  _Watchdog_Per_CPU_release_critical( cpu, &lock_context2 );
128  _ISR_lock_Release_and_ISR_enable(
129    &_POSIX_signals_Ualarm_lock,
130    &lock_context
131  );
132
133  remaining *= rtems_configuration_get_microseconds_per_tick();
134
135  return remaining;
136}
Note: See TracBrowser for help on using the repository browser.