OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [posix/] [src/] [ptimer1.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1026 ivang
/*
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
 
64
extern 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
 
82
int 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
 
106
int 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
 
133
void 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
 
151
void 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
 
191
rtems_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
 
263
int 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
 
370
int 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
 
421
int 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
 
655
int 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
 
756
int 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.