source: rtems/c/src/exec/posix/src/ptimer1.c @ e180a77e

4.104.114.84.95
Last change on this file since e180a77e was e180a77e, checked in by Joel Sherrill <joel.sherrill@…>, on 01/04/02 at 18:28:24

2002-01-04 Ralf Corsepius <corsepiu@…>

  • src/clockgetres.c: Apply rtems_set_errno_and_return_minus_one.
  • src/clockgettime.c: Apply rtems_set_errno_and_return_minus_one.
  • src/clocksettime.c: Apply rtems_set_errno_and_return_minus_one.
  • src/killinfo.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueueclose.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueuecreatesupp.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueuegetattr.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueuenotify.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueueopen.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueuerecvsupp.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueuesendsupp.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueuesetattr.c: Apply rtems_set_errno_and_return_minus_one.
  • src/mqueueunlink.c: Apply rtems_set_errno_and_return_minus_one.
  • src/nanosleep.c: Apply rtems_set_errno_and_return_minus_one.
  • src/pthreadkill.c: Apply rtems_set_errno_and_return_minus_one.
  • src/pthreadsigmask.c: Apply rtems_set_errno_and_return_minus_one.
  • src/ptimer1.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sched.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semaphorecreatesupp.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semaphorewaitsupp.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semclose.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semdestroy.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semgetvalue.c: Apply rtems_set_errno_and_return_minus_one.
  • src/seminit.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semopen.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sempost.c: Apply rtems_set_errno_and_return_minus_one.
  • src/semunlink.c: Apply rtems_set_errno_and_return_minus_one.
  • src/setpgid.c: Apply rtems_set_errno_and_return_minus_one.
  • src/setsid.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigaction.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigaddset.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigdelset.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigemptyset.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigfillset.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigismember.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigpending.c: Apply rtems_set_errno_and_return_minus_one.
  • src/sigtimedwait.c: Apply rtems_set_errno_and_return_minus_one.
  • src/utsname.c: Apply rtems_set_errno_and_return_minus_one.
  • Property mode set to 100644
File size: 21.5 KB
Line 
1/*
2 *  ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp
3 */
4
5#if HAVE_CONFIG_H
6#include "config.h"
7#endif
8 
9#include <assert.h>
10#include <time.h>
11#include <errno.h>
12
13#include <rtems/system.h>
14#include <rtems/score/isr.h>
15#include <rtems/score/thread.h>
16#include <rtems/score/tod.h>
17
18#include <rtems/posix/time.h>
19
20/************************************/
21/* These includes are now necessary */
22/************************************/
23
24#include <sys/features.h>
25#include <rtems/rtems/status.h>
26#include <rtems/rtems/types.h>
27#include <rtems/rtems/timer.h>
28#include <rtems/rtems/clock.h>
29#include <rtems/posix/psignal.h>
30#include <rtems/score/wkspace.h>
31#include <pthread.h>
32#include <stdio.h>
33#include <signal.h>
34
35#include <rtems/seterr.h>
36#include <rtems/posix/timer.h>
37
38/*****************************/
39/* End of necessary includes */
40/*****************************/
41
42/* ************
43 * Constants
44 * ************/
45
46/*
47#define DEBUG_MESSAGES
48 */
49
50/*
51 * Data for the signals
52 */
53
54/***********************************
55 * Definition of Internal Functions
56 ***********************************/
57
58/* ***************************************************************************
59 * TIMER_INITIALIZE_S
60 *
61 *  Description: Initialize the data of a timer
62 * ***************************************************************************/
63
64extern void TIMER_INITIALIZE_S ( int timer_pos );
65
66/* ***************************************************************************
67 * _POSIX_Timer_Manager_initialization
68 *
69 *  Description: Initialize the internal structure in which the data of all
70 *               the timers are stored
71 * ***************************************************************************/
72
73/* split to reduce minimum size */
74
75/* ***************************************************************************
76 * FIRST_FREE_POSITION_F
77 *
78 *  Description: Returns the first free position in the table of timers.
79 *               If there is not a free position, it returns NO_MORE_TIMERS_C
80 * ***************************************************************************/
81
82int FIRST_FREE_POSITION_F ()
83{
84   int index;
85
86   for (index=0; index<timer_max; index++) {
87      if ( timer_struct[index].state == STATE_FREE_C ) {
88         return index;
89      }
90   }
91   
92   /* The function reaches this point only if all the position are occupied */
93
94   return NO_MORE_TIMERS_C;
95}
96
97/* ***************************************************************************
98 * TIMER_POSITION_F
99 *
100 *  Description: Returns the position in the table of timers in which the
101 *               data of the timer are stored.
102 *               If the timer identifier does not exist, it returns
103 *               BAD_TIMER_C
104 * ***************************************************************************/
105
106int TIMER_POSITION_F ( timer_t timer_id )
107{
108  int index;
109
110  for (index=0; index<timer_max; index++ ) {
111
112     /* Looks for the position of the timer. The timer must exist and the
113      * position can not be free */
114     if ( ( timer_struct[index].timer_id == timer_id ) &&
115          ( timer_struct[index].state != STATE_FREE_C ) ) {
116        return index;
117     }
118  }
119
120  /* If the function reaches this point is because the timer identifier
121   * is not correct */
122
123   return BAD_TIMER_C;
124
125}
126
127/* ***************************************************************************
128 * COPY_ITIMERSPEC_S
129 *
130 *  Description: Does a copy of a variable of type struct itimerspec 
131 * ***************************************************************************/
132
133void COPY_ITIMERSPEC_S ( const struct itimerspec *source,
134                         struct itimerspec *target )
135{
136
137   target->it_value.tv_sec     = source->it_value.tv_sec;
138   target->it_value.tv_nsec    = source->it_value.tv_nsec;
139   target->it_interval.tv_sec  = source->it_interval.tv_sec;
140   target->it_interval.tv_nsec = source->it_interval.tv_nsec;
141
142}
143
144/* ***************************************************************************
145 * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
146 *
147 *  Description: This function converts the data of a structure itimerspec
148 *               into structure rtems_time_of_day
149 * ***************************************************************************/
150
151void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
152   ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time )
153{
154   unsigned long int seconds;
155
156   /* The leap years and the months with 28, 29 or 31 days have not been
157    * considerated. It will be made in the future */
158
159   seconds            = itimer->it_value.tv_sec;
160
161   rtems_time->year   = seconds / SECONDS_PER_YEAR_C;
162   seconds            = seconds % SECONDS_PER_YEAR_C;
163
164   rtems_time->month  = seconds / SECONDS_PER_MONTH_C;
165   seconds            = seconds % SECONDS_PER_MONTH_C;
166
167   rtems_time->day    = seconds / SECONDS_PER_DAY_C;
168   seconds            = seconds % SECONDS_PER_DAY_C;
169
170   rtems_time->hour   = seconds / SECONDS_PER_HOUR_C;
171   seconds            = seconds % SECONDS_PER_HOUR_C;
172
173   rtems_time->minute = seconds / SECONDS_PER_MINUTE_C;
174   seconds            = seconds % SECONDS_PER_MINUTE_C;
175
176   rtems_time->second = seconds;
177
178   rtems_time->ticks  = ( itimer->it_value.tv_nsec * SEC_TO_TICKS_C ) /
179                        NSEC_PER_SEC_C;
180
181}
182
183
184/* ***************************************************************************
185 * FIRE_TIMER_S
186 *
187 *  Description: This is the operation that is ran when a timer expires
188 * ***************************************************************************/
189
190
191rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data)
192{
193  int               timer_pos;  /* Position in the table of the timer that   
194                                 *  has expirated                            */
195  rtems_status_code return_v;   /* Return value of rtems_timer_fire_after    */
196  int               sig_number; /* Number of the signal to send              */
197
198 
199  /* The position of the table of timers that contains the data of the
200   * expired timer will be stored in "timer_pos". In theory a timer can not
201   * expire if it has not been created or has been deleted */
202
203  timer_pos = TIMER_POSITION_F(timer);
204
205  /* Increases the number of expiration of the timer in one unit. */
206  timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1;
207
208
209  if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec  != 0 ) ||
210       ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) {
211
212     /* The timer must be reprogrammed */
213
214     return_v = rtems_timer_fire_after ( timer,
215                                        timer_struct[timer_pos].ticks,
216                                        FIRE_TIMER_S,
217                                        NULL );
218
219     /* Stores the time when the timer was started again */
220
221     timer_struct[timer_pos].time = _TOD_Current;
222     
223     /* The state has not to be actualized, because nothing modifies it */
224
225     timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
226
227  } else {
228     /* Indicates that the timer is stopped */
229 
230     timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
231
232  }
233
234  /*
235   * The sending of the signal to the process running the handling function
236   * specified for that signal is simulated
237   */
238
239  sig_number = timer_struct[timer_pos].inf.sigev_signo;
240
241  if( pthread_kill ( timer_struct[timer_pos].thread_id ,
242                     timer_struct[timer_pos].inf.sigev_signo ) ) {
243     /* XXX error handling */
244  }
245
246  /*
247   * After the signal handler returns, the count of expirations of the
248   * timer must be set to 0.
249   */
250
251  timer_struct[timer_pos].overrun = 0;
252
253}
254
255/* *********************************************************************
256 *  14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
257 * ********************************************************************/
258
259/* **************
260 * timer_create
261 * **************/
262
263int timer_create(
264  clockid_t        clock_id,
265  struct sigevent *evp,
266  timer_t         *timerid
267)
268{
269
270  rtems_status_code return_v;  /* return value of the operation    */
271  rtems_id          timer_id;  /* created timer identifier         */
272  int               timer_pos; /* Position in the table of timers  */
273
274 /*
275  *  The data of the structure evp are checked in order to verify if they
276  *  are coherent.
277  */
278
279  if (evp != NULL) {
280    /* The structure has data */
281    if ( ( evp->sigev_notify != SIGEV_NONE ) &&
282         ( evp->sigev_notify != SIGEV_SIGNAL ) ) {
283       /* The value of the field sigev_notify is not valid */
284       rtems_set_errno_and_return_minus_one( EINVAL );
285     }
286  }
287 
288 /*
289  *  A timer is created using the primitive rtems_timer_create
290  */
291
292  return_v = rtems_timer_create ( clock_id, &timer_id );
293
294  switch (return_v) {
295     case RTEMS_SUCCESSFUL :
296
297       /*
298        * The timer has been created properly
299        */
300 
301        /* Obtains the first free position in the table of timers */
302
303        timer_pos = FIRST_FREE_POSITION_F();
304
305        if ( timer_pos == NO_MORE_TIMERS_C ) {
306           /* There is not position for another timers in spite of RTEMS
307            * supports it. It will necessaty to increase the structure used */
308
309           rtems_set_errno_and_return_minus_one( EAGAIN );
310        }
311
312        /* Exit parameter */
313
314        *timerid  = timer_id;
315
316        /* The data of the created timer are stored to use them later */
317
318        timer_struct[timer_pos].state     = STATE_CREATE_NEW_C;
319
320        /* NEW VERSION*/
321        timer_struct[timer_pos].thread_id = pthread_self ();
322       
323        if ( evp != NULL ) {
324           timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify;
325           timer_struct[timer_pos].inf.sigev_signo  = evp->sigev_signo;
326           timer_struct[timer_pos].inf.sigev_value  = evp->sigev_value;
327        }
328
329        timer_struct[timer_pos].timer_id = timer_id;
330        timer_struct[timer_pos].overrun  = 0;
331
332        timer_struct[timer_pos].timer_data.it_value.tv_sec     = 0;
333        timer_struct[timer_pos].timer_data.it_value.tv_nsec    = 0;
334        timer_struct[timer_pos].timer_data.it_interval.tv_sec  = 0;
335        timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
336
337        return 0;
338
339     case RTEMS_INVALID_NAME : /* The assigned name is not valid */
340
341       rtems_set_errno_and_return_minus_one( EINVAL );
342
343     case RTEMS_TOO_MANY :
344
345       /* There has been created too much timers for the same process */
346       rtems_set_errno_and_return_minus_one( EAGAIN );
347     
348     default :
349
350       /*
351        * Does nothing. It only returns the error without assigning a value
352        * to errno. In theory, it can not happen because the call to
353        * rtems_timer_create can not return other different value.
354        */
355
356       rtems_set_errno_and_return_minus_one( EINVAL );
357  }
358
359  /*
360   * The next sentence is used to avoid singular situations
361   */
362
363  rtems_set_errno_and_return_minus_one( EINVAL );
364}
365
366/*
367 *  14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
368 */
369
370int timer_delete(
371  timer_t timerid
372)
373{
374 
375 /*
376  * IDEA: This function must probably stop the timer first and then delete it
377  *
378  *       It will have to do a call to rtems_timer_cancel and then another
379  *       call to rtems_timer_delete.
380  *       The call to rtems_timer_delete will be probably unnecessary,
381  *       because rtems_timer_delete stops the timer before deleting it.
382  */
383
384  int               timer_pos;
385  rtems_status_code status;
386
387
388   /* First the position in the table of timers is obtained */
389
390   timer_pos = TIMER_POSITION_F ( timerid );
391
392   if ( timer_pos == BAD_TIMER_C ) {
393      /* The timer identifier is erroneus */
394      rtems_set_errno_and_return_minus_one( EINVAL );
395   }
396
397   /* The timer is deleted */
398
399   status = rtems_timer_delete ( timerid );
400
401   if ( status == RTEMS_INVALID_ID ) {
402     /* The timer identifier is erroneus */
403     rtems_set_errno_and_return_minus_one( EINVAL );
404   }
405
406   /* Initializes the data of the timer */
407
408   TIMER_INITIALIZE_S ( timer_pos );
409   return 0;
410}
411
412/*
413 *  14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
414 */
415
416/* **************
417 * timer_settime
418 * **************/
419
420
421int timer_settime(
422  timer_t                  timerid,
423  int                      flags,
424  const struct itimerspec *value,
425  struct itimerspec       *ovalue
426)
427{
428
429   rtems_status_code return_v;   /* Return of the calls to RTEMS        */
430   int               timer_pos;  /* Position of the timer in the table  */
431   rtems_time_of_day rtems_time; /* Time in RTEMS                       */
432   
433
434   /* First the position in the table of timers is obtained */
435
436   timer_pos = TIMER_POSITION_F ( timerid );
437
438   if ( timer_pos == BAD_TIMER_C ) {
439     /* The timer identifier is erroneus */
440     rtems_set_errno_and_return_minus_one( EINVAL );
441   }
442
443   if ( value == NULL ) {
444     /* The stucture of times of the timer is free, and then returns an
445        error but the variable errno is not actualized */
446
447     rtems_set_errno_and_return_minus_one( EINVAL );
448   }
449
450   /* If the function reaches this point, then it will be necessary to do
451    * something with the structure of times of the timer: to stop, start
452    * or start it again */
453
454   /* First, it verifies if the timer must be stopped */
455
456   if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
457      /* The timer is stopped */
458
459      return_v = rtems_timer_cancel ( timerid );
460
461      /* The old data of the timer are returned */
462
463      if ( ovalue )
464        *ovalue = timer_struct[timer_pos].timer_data;
465
466      /* The new data are set */
467
468      timer_struct[timer_pos].timer_data = *value;
469
470      /* Indicates that the timer is created and stopped */
471 
472      timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
473
474      /* Returns with success */
475
476      return 0;
477   }
478
479   /*
480    * If the function reaches this point, then the timer will have to be
481    * initialized with new values: to start it or start it again
482    */
483 
484   /* First, it verifies if the structure "value" is correct */
485
486    if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) ||
487         ( value->it_value.tv_nsec < MIN_NSEC_C ) ) {
488       /* The number of nanoseconds is not correct */
489
490       rtems_set_errno_and_return_minus_one( EINVAL );
491    }
492
493   /* Then, "value" must be converted from seconds and nanoseconds to clock
494    * ticks, to use it in the calls to RTEMS */
495
496   /* It is also necessary to take in account if the time is absolute
497    * or relative */
498
499   switch (flags) {
500      case TIMER_ABSTIME:
501
502        /* The fire time is absolute:
503         * It has to use "rtems_time_fire_when" */
504
505        /* First, it converts from struct itimerspec to rtems_time_of_day */
506
507        ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time );
508
509        return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL);
510
511        switch ( return_v ) {
512           case RTEMS_SUCCESSFUL:
513
514              /* The timer has been started and is running */
515
516              /* Actualizes the data of the structure and
517               * returns the old ones in "ovalue" */
518
519              if ( ovalue )
520                *ovalue = timer_struct[timer_pos].timer_data;
521
522              timer_struct[timer_pos].timer_data = *value;
523 
524              /* It indicates that the time is running */
525
526              timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
527
528              /* Stores the time in which the timer was started again */
529
530              timer_struct[timer_pos].time = _TOD_Current;
531              return 0;
532
533              break;
534
535           case RTEMS_INVALID_ID:
536
537              /* XXX error handling */
538              break;
539
540           case RTEMS_NOT_DEFINED:
541
542              /* XXX error handling */
543              break;
544
545           case RTEMS_INVALID_CLOCK:
546
547              /* XXX error handling */
548              break;
549
550           default: break;
551
552       
553        }
554     
555        break;
556
557      case TIMER_RELATIVE_C:
558
559        /* The fire time is relative:
560         * It has to use "rtems_time_fire_after" */
561
562        /* First, it converts from seconds and nanoseconds to ticks */
563
564        /* The form in which this operation is done can produce a lost
565         * of precision of 1 second */
566 
567/*      This is the process to convert from nanoseconds to ticks
568 *
569 *      There is a tick every 10 miliseconds, then the nanoseconds are
570 *      divided between 10**7. The result of this operation will be the
571 *      number of ticks
572 */
573
574        timer_struct[timer_pos].ticks =
575             ( SEC_TO_TICKS_C * value->it_value.tv_sec ) +
576             ( value->it_value.tv_nsec / ( 1000 * 1000 * 10 ) );
577
578        return_v = rtems_timer_fire_after ( timerid,
579                                           timer_struct[timer_pos].ticks,
580                                           FIRE_TIMER_S,
581                                           NULL );
582
583        switch (return_v) {
584           case RTEMS_SUCCESSFUL:
585
586              /* The timer has been started and is running */
587
588              /* Actualizes the data of the structure and
589               * returns the old ones in "ovalue" */
590
591              if ( ovalue )
592                *ovalue = timer_struct[timer_pos].timer_data;
593
594              timer_struct[timer_pos].timer_data = *value;
595 
596              /* It indicates that the time is running */
597
598              timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
599
600              /* Stores the time in which the timer was started again */
601
602              timer_struct[timer_pos].time = _TOD_Current;
603 
604              return 0;
605
606              break;
607
608           case RTEMS_INVALID_ID:
609
610              /* The timer identifier is not correct. In theory, this
611               * situation can not occur, but the solution is easy */
612
613              rtems_set_errno_and_return_minus_one( EINVAL );
614
615              break;
616
617           case RTEMS_INVALID_NUMBER:
618
619              /* In this case, RTEMS fails because the values of timing
620               * are incorrect */
621
622              /*
623               * I do not know if errno must be actualized
624               *
625               * errno = EINVAL;
626               */
627
628              rtems_set_errno_and_return_minus_one( EINVAL );
629              break;
630           
631           default: break;
632        }
633
634        break;
635
636      default: break;
637
638        /* It does nothing, although it will be probably necessary to
639         * return an error */
640   }
641
642   /* To avoid problems */
643   return 0;
644}
645
646
647/*
648 *  14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
649 */
650
651/* **************
652 * timer_gettime
653 * **************/
654
655int timer_gettime(
656  timer_t            timerid,
657  struct itimerspec *value
658)
659{
660
661 /*
662  * IDEA:  This function does not use functions of RTEMS to the handle
663  *        of timers. It uses some functions for managing the time.
664  *
665  *        A possible form to do this is the following:
666  *
667  *          - When a timer is initialized, the value of the time in
668  *            that moment is stored.
669  *          - When this function is called, it returns the difference
670  *            between the current time and the initialization time.
671  */
672 
673  rtems_time_of_day current_time;
674  int               timer_pos;
675  unsigned32        hours;
676  unsigned32        minutes;
677  unsigned32        seconds;
678  unsigned32        ticks;
679  unsigned32        nanosec;
680 
681
682  /* Reads the current time */
683
684  current_time = _TOD_Current;
685
686  timer_pos = TIMER_POSITION_F ( timerid );
687
688  if ( timer_pos == BAD_TIMER_C ) {
689    /* The timer identifier is erroneus */ 
690    rtems_set_errno_and_return_minus_one( EINVAL );
691  }
692
693  /* Calculates the difference between the start time of the timer and
694   * the current one */
695
696  hours    = current_time.hour - timer_struct[timer_pos].time.hour;
697
698  if ( current_time.minute < timer_struct[timer_pos].time.minute ) {
699     minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute;
700     hours--;
701  } else {
702     minutes = current_time.minute - timer_struct[timer_pos].time.minute;
703  }
704   
705  if ( current_time.second < timer_struct[timer_pos].time.second ) {
706     seconds = 60 - timer_struct[timer_pos].time.second + current_time.second;
707     minutes--;
708  } else {
709     seconds = current_time.second - timer_struct[timer_pos].time.second;
710  }
711
712  if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) {
713     ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks;
714     seconds--;
715  } else {
716     ticks = current_time.ticks - timer_struct[timer_pos].time.ticks;
717  }
718
719  /* The time that the timer is running is calculated */
720  seconds = hours   * 60 * 60 +
721            minutes * 60      +
722            seconds;
723
724  nanosec  = ticks * 10 *  /* msec     */
725             1000  *       /* microsec */
726             1000;         /* nanosec  */
727
728 
729  /* Calculates the time left before the timer finishes */
730 
731  value->it_value.tv_sec =
732    timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds;
733 
734  value->it_value.tv_nsec =
735    timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec;
736
737
738  value->it_interval.tv_sec  =
739    timer_struct[timer_pos].timer_data.it_interval.tv_sec;
740  value->it_interval.tv_nsec =
741    timer_struct[timer_pos].timer_data.it_interval.tv_nsec;
742 
743
744  return 0;
745
746}
747
748/*
749 *  14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
750 */
751
752/* *****************
753 * timer_getoverrun
754 * *****************/
755
756int timer_getoverrun(
757  timer_t   timerid
758)
759{
760
761 /*
762  * IDEA: This function must count the times the timer expires.
763  *   
764  *       The expiration of a timer must increase by one a counter.
765  *       After the signal handler associated to the timer finishs
766  *       its execution, FIRE_TIMER_S will have to set this counter to 0.
767  */
768
769  int timer_pos; /* Position of the timer in the structure     */
770  int overrun;   /* Overflow count                             */
771
772
773  timer_pos = TIMER_POSITION_F ( timerid );
774
775  if ( timer_pos == BAD_TIMER_C ) {
776    /* The timer identifier is erroneus */
777    rtems_set_errno_and_return_minus_one( EINVAL );
778  }
779
780  /* The overflow count of the timer is stored in "overrun" */
781
782  overrun = timer_struct[timer_pos].overrun;
783
784  /* It is set to 0 */
785
786  timer_struct[timer_pos].overrun = 0;
787
788  return overrun;
789
790}
Note: See TracBrowser for help on using the repository browser.