source: rtems/c/src/exec/posix/src/time.c @ 5e7b6272

4.104.114.84.95
Last change on this file since 5e7b6272 was 5e7b6272, checked in by Joel Sherrill <joel.sherrill@…>, on 05/31/96 at 23:27:45

renamed _TOD_Ticks_since_boot as _Watchdog_Ticks_since_boot so the Watchdog
Handler could timestamp the starting and stopping of timers. Since
TOD is built on top of Watchdog, this avoided a circular dependency.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 *  $Id$
3 */
4
5#include <assert.h>
6#include <time.h>
7#include <errno.h>
8
9#include <rtems/system.h>
10#include <rtems/score/isr.h>
11#include <rtems/score/thread.h>
12#include <rtems/score/tod.h>
13
14/*
15 *  Seconds from January 1, 1970 to January 1, 1988.  Used to account for
16 *  differences between POSIX API and RTEMS core.
17 */
18
19#define POSIX_TIME_SECONDS_1970_THROUGH_1988 \
20  (((1987 - 1970 + 1)  * TOD_SECONDS_PER_NON_LEAP_YEAR) + \
21  (4 * TOD_SECONDS_PER_DAY))
22
23/*
24 *  _POSIX_Time_Spec_to_interval
25 */
26
27Watchdog_Interval _POSIX_Time_Spec_to_interval(
28  const struct timespec *time
29)
30{
31  Watchdog_Interval  ticks;
32
33  ticks  = (time->tv_sec * TOD_MICROSECONDS_PER_SECOND) /
34             _TOD_Microseconds_per_tick;
35
36  ticks += (time->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
37             _TOD_Microseconds_per_tick;
38
39  return ticks;
40}
41
42/*
43 *  4.5.1 Get System Time, P1003.1b-1993, p. 91
44 */
45
46time_t time(
47  time_t   *tloc
48)
49{
50  time_t  seconds_since_epoch;
51
52  if ( !_TOD_Is_set() ) {
53    errno = EINVAL;
54    return -1;
55  }
56
57  /*
58   *  Internally the RTEMS epoch is 1988.  This must be taken into account.
59   */
60
61  seconds_since_epoch = _TOD_Seconds_since_epoch;
62     
63  seconds_since_epoch += POSIX_TIME_SECONDS_1970_THROUGH_1988;
64
65  if ( tloc )
66    *tloc = seconds_since_epoch;
67
68  return seconds_since_epoch;
69}
70
71/*
72 *  14.2.1 Clocks, P1003.1b-1993, p. 263
73 */
74
75int clock_settime(
76  clockid_t              clock_id,
77  const struct timespec *tp
78)
79{
80  struct tm         split_time;
81  TOD_Control       tod;
82  Watchdog_Interval seconds;
83
84  assert( tp );
85
86  switch ( clock_id ) {
87 
88    case CLOCK_REALTIME:
89      (void) gmtime_r( &tp->tv_sec, &split_time );
90 
91      /*
92       *  Convert the tm structure format to that used by the TOD Handler
93       *
94       *  NOTE: TOD Handler does not honor leap seconds.
95       */
96
97      tod.year   = split_time.tm_year + 1900;  /* RHS is years since 1900 */
98      tod.month  = split_time.tm_mon + 1;      /* RHS uses 0-11 */
99      tod.day    = split_time.tm_mday;
100      tod.hour   = split_time.tm_hour;
101      tod.minute = split_time.tm_min;
102      tod.second = split_time.tm_sec;  /* RHS allows 0-61 for leap seconds */
103
104      tod.ticks  = (tp->tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND) /
105                      _TOD_Microseconds_per_tick;
106
107      if ( !_TOD_Validate( &tod ) ) {
108        errno = EINVAL;
109        return -1;
110      }
111 
112      /*
113       *  We can't use the tp->tv_sec field because it is based on
114       *  a different EPOCH.
115       */
116
117      seconds = _TOD_To_seconds( &tod );
118      _Thread_Disable_dispatch();
119        _TOD_Set( &tod, seconds );
120      _Thread_Enable_dispatch();
121      break;
122 
123#ifdef _POSIX_CPUTIME
124    case CLOCK_PROCESS_CPUTIME:
125      return POSIX_NOT_IMPLEMENTED();
126      break;
127#endif
128 
129#ifdef _POSIX_THREAD_CPUTIME
130    case CLOCK_THREAD_CPUTIME:
131      return POSIX_NOT_IMPLEMENTED();
132      break;
133#endif
134    default:
135      errno = EINVAL;
136      return -1;
137 
138  }
139  return 0;
140}
141
142/*
143 *  14.2.1 Clocks, P1003.1b-1993, p. 263
144 */
145
146int clock_gettime(
147  clockid_t        clock_id,
148  struct timespec *tp
149)
150{
151  ISR_Level      level;
152  time_t         seconds;
153  long           ticks;
154
155  assert( tp );
156
157  switch ( clock_id ) {
158
159    case CLOCK_REALTIME:
160      if ( !_TOD_Is_set() ) {  /* XXX does posix allow it to not be set? */
161        errno = EINVAL;
162        return -1;
163      }
164 
165      _ISR_Disable( level );
166        seconds = _TOD_Seconds_since_epoch;
167        ticks   = _TOD_Current.ticks;
168      _ISR_Enable( level );
169 
170      tp->tv_sec  = seconds + POSIX_TIME_SECONDS_1970_THROUGH_1988;
171      tp->tv_nsec = ticks * _TOD_Microseconds_per_tick *
172                      TOD_NANOSECONDS_PER_MICROSECOND;
173      break;
174
175#ifdef _POSIX_CPUTIME
176    case CLOCK_PROCESS_CPUTIME:
177      /* could base this on _Watchdog_Ticks_since_boot -- must make set work though*/
178      return POSIX_NOT_IMPLEMENTED();
179      break;
180#endif
181
182#ifdef _POSIX_THREAD_CPUTIME
183    case CLOCK_THREAD_CPUTIME:
184      return POSIX_NOT_IMPLEMENTED();
185      break;
186#endif
187    default:
188      errno = EINVAL;
189      return -1;
190
191  }
192  return 0;
193}
194
195/*
196 *  14.2.1 Clocks, P1003.1b-1993, p. 263
197 */
198
199int clock_getres(
200  clockid_t        clock_id,
201  struct timespec *res
202)
203{
204  switch ( clock_id ) {
205 
206    /*
207     *  All time in rtems is based on the same clock tick.
208     */
209
210    case CLOCK_REALTIME:
211    case CLOCK_PROCESS_CPUTIME:
212    case CLOCK_THREAD_CPUTIME:
213      if ( res ) {
214        res->tv_sec  = _TOD_Microseconds_per_tick / TOD_MICROSECONDS_PER_SECOND;
215        res->tv_nsec =
216          (_TOD_Microseconds_per_tick % TOD_MICROSECONDS_PER_SECOND) *
217            TOD_NANOSECONDS_PER_MICROSECOND;
218      }
219      break;
220 
221    default:
222      errno = EINVAL;
223      return -1;
224 
225  }
226  return 0;
227}
228
229/*
230 *  14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
231 */
232
233int timer_create(
234  clockid_t        clock_id,
235  struct sigevent *evp,
236  timer_t         *timerid
237)
238{
239  return POSIX_NOT_IMPLEMENTED();
240}
241
242/*
243 *  14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
244 */
245
246int timer_delete(
247  timer_t timerid
248)
249{
250  return POSIX_NOT_IMPLEMENTED();
251}
252
253/*
254 *  14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
255 */
256
257int timer_settime(
258  timer_t                  timerid,
259  int                      flags,
260  const struct itimerspec *value,
261  struct itimerspec       *ovalue
262)
263{
264  return POSIX_NOT_IMPLEMENTED();
265}
266
267/*
268 *  14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
269 */
270
271int timer_gettime(
272  timer_t            timerid,
273  struct itimerspec *value
274)
275{
276  return POSIX_NOT_IMPLEMENTED();
277}
278
279/*
280 *  14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
281 */
282
283int timer_getoverrun(
284  timer_t   timerid
285)
286{
287  return POSIX_NOT_IMPLEMENTED();
288}
289
290/*
291 *  14.2.5 High Resolution Sleep, P1003.1b-1993, p. 269
292 */
293
294int nanosleep(
295  const struct timespec  *rqtp,
296  struct timespec        *rmtp
297)
298{
299  Watchdog_Interval ticks;
300
301  if ( rqtp->tv_nsec < 0 || rqtp->tv_nsec >= TOD_NANOSECONDS_PER_SECOND ) {
302    errno = EINVAL;
303    return -1;
304  }
305 
306/* XXX this is interruptible by a posix signal */
307
308/* XXX rmtp is the time remaining on the timer -- we do not support this */
309
310  ticks = _POSIX_Time_Spec_to_interval( rqtp );
311 
312  _Thread_Disable_dispatch();
313    _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_TIME );
314    _Watchdog_Initialize(
315      &_Thread_Executing->Timer,
316      _Thread_Delay_ended,          /* XXX may need to be POSIX specific */
317      _Thread_Executing->Object.id,
318      NULL
319    );
320    _Watchdog_Insert_ticks( &_Thread_Executing->Timer, ticks );
321  _Thread_Enable_dispatch();
322
323  if ( rmtp ) {
324    /* XXX calculate time remaining */
325  }
326
327  return 0;                    /* XXX should account for signal */
328
329}
330
331/*
332 *  20.1.3 Accessing a Process CPU-time CLock, P1003.4b/D8, p. 55
333 */
334
335int clock_getcpuclockid(
336  pid_t      pid,
337  clockid_t *clock_id
338)
339{
340  return POSIX_NOT_IMPLEMENTED();
341}
342
343/*
344 *  20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
345 */
346
347int clock_setenable_attr(
348  clockid_t    clock_id,
349  int          attr
350)
351{
352  return POSIX_NOT_IMPLEMENTED();
353}
354
355/*
356 *  20.1.5 CPU-time Clock Attribute Access, P1003.4b/D8, p. 58
357 */
358
359int clock_getenable_attr(
360  clockid_t    clock_id,
361  int         *attr
362)
363{
364  return POSIX_NOT_IMPLEMENTED();
365}
Note: See TracBrowser for help on using the repository browser.