source: rtems/cpukit/posix/src/ualarm.c @ 1dc6662

4.115
Last change on this file since 1dc6662 was 1dc6662, checked in by Sebastian Huber <sebastian.huber@…>, on 04/13/15 at 11:57:57

score: Rename _Watchdog_Reset()

Update #2307.

  • Property mode set to 100644
File size: 2.6 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/posix/pthreadimpl.h>
25#include <rtems/posix/psignalimpl.h>
26#include <rtems/posix/time.h>
27#include <rtems/score/threaddispatch.h>
28#include <rtems/score/todimpl.h>
29#include <rtems/score/watchdogimpl.h>
30
31static void _POSIX_signals_Ualarm_TSR( Objects_Id id, void *argument );
32
33static Watchdog_Control _POSIX_signals_Ualarm_timer = WATCHDOG_INITIALIZER(
34  _POSIX_signals_Ualarm_TSR,
35  0,
36  NULL
37);
38
39/*
40 *  _POSIX_signals_Ualarm_TSR
41 */
42
43static void _POSIX_signals_Ualarm_TSR(
44  Objects_Id      id __attribute__((unused)),
45  void           *argument __attribute__((unused))
46)
47{
48  /*
49   * Send a SIGALRM but if there is a problem, ignore it.
50   * It's OK, there isn't a way this should fail.
51   */
52  (void) kill( getpid(), SIGALRM );
53
54  /*
55   * If the reset interval is non-zero, reschedule ourselves.
56   */
57  _Watchdog_Reset_ticks( &_POSIX_signals_Ualarm_timer );
58}
59
60useconds_t ualarm(
61  useconds_t useconds,
62  useconds_t interval
63)
64{
65  useconds_t        remaining = 0;
66  Watchdog_Control *the_timer;
67  Watchdog_Interval ticks;
68  Watchdog_States   state;
69  struct timespec   tp;
70
71  the_timer = &_POSIX_signals_Ualarm_timer;
72
73  _Thread_Disable_dispatch();
74
75  state = _Watchdog_Remove( the_timer );
76  if ( (state == WATCHDOG_ACTIVE) || (state == WATCHDOG_REMOVE_IT) ) {
77    /*
78     *  The stop_time and start_time fields are snapshots of ticks since
79     *  boot.  Since alarm() is dealing in seconds, we must account for
80     *  this.
81     */
82
83    ticks = the_timer->initial;
84    ticks -= (the_timer->stop_time - the_timer->start_time);
85    /* remaining is now in ticks */
86
87    _Timespec_From_ticks( ticks, &tp );
88    remaining  = tp.tv_sec * TOD_MICROSECONDS_PER_SECOND;
89    remaining += tp.tv_nsec / 1000;
90  }
91
92  /*
93   *  If useconds is non-zero, then the caller wants to schedule
94   *  the alarm repeatedly at that interval.  If the interval is
95   *  less than a single clock tick, then fudge it to a clock tick.
96   */
97  if ( useconds ) {
98    Watchdog_Interval ticks;
99
100    tp.tv_sec = useconds / TOD_MICROSECONDS_PER_SECOND;
101    tp.tv_nsec = (useconds % TOD_MICROSECONDS_PER_SECOND) * 1000;
102    ticks = _Timespec_To_ticks( &tp );
103    if ( ticks == 0 )
104      ticks = 1;
105
106    _Watchdog_Insert_ticks( the_timer, _Timespec_To_ticks( &tp ) );
107  }
108
109  _Thread_Enable_dispatch();
110
111  return remaining;
112}
Note: See TracBrowser for help on using the repository browser.