Changeset 0747e2d in rtems
- Timestamp:
- 02/03/99 16:22:18 (25 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- cd792a86
- Parents:
- c30d04d7
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/posix/include/rtems/posix/Makefile.in
rc30d04d7 r0747e2d 14 14 15 15 H_PIECES= cond config key mutex posixapi \ 16 priority psignal pthread seterr threadsup time16 priority psignal pthread ptimer seterr threadsup time 17 17 #H_PIECES= cancel cond intr key mqueue mqueuemp mutex \ 18 18 # mutexmp pthread pthreadmp priority semaphore semaphoremp threadsup \ -
c/src/exec/posix/include/rtems/posix/config.h
rc30d04d7 r0747e2d 47 47 int maximum_condition_variables; 48 48 int maximum_keys; 49 int maximum_timers; 49 50 int maximum_queued_signals; 50 51 int number_of_initialization_threads; -
c/src/exec/posix/src/Makefile.in
rc30d04d7 r0747e2d 10 10 11 11 # following are semi-implemented and untested 12 # C_PIECES=aio cancel devctl intr mqueue ptimersemaphore time utsname12 # C_PIECES=aio cancel devctl intr mqueue semaphore time utsname 13 13 14 14 ENOSYS_C_PIECES=\ … … 37 37 38 38 C_PIECES= adasupp cond getpid key mutex $(PTHREAD_PIECES) \ 39 $(PSIGNAL_PIECES) sched time \39 $(PSIGNAL_PIECES) ptimer sched time \ 40 40 types unistd $(ENOSYS_C_PIECES) 41 41 -
c/src/exec/posix/src/ptimer.c
rc30d04d7 r0747e2d 1 1 /* 2 * $Id$2 * ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp 3 3 */ 4 4 5 5 #include <assert.h> 6 6 #include <time.h> … … 14 14 #include <rtems/posix/time.h> 15 15 16 /************************************/ 17 /* These includes are now necessary */ 18 /************************************/ 19 20 #include <sys/features.h> 21 #include <rtems/rtems/status.h> 22 #include <rtems/rtems/types.h> 23 #include <rtems/rtems/timer.h> 24 #include <rtems/rtems/clock.h> 25 #include <rtems/posix/psignal.h> 26 #include <rtems/score/wkspace.h> 27 #include <pthread.h> 28 #include <stdio.h> 29 #include <signal.h> 30 31 /*****************************/ 32 /* End of necessary includes */ 33 /*****************************/ 34 35 /* ************ 36 * Constants 37 * ************/ 38 39 #define STATE_FREE_C 0x01 /* Free position of the table of timers */ 40 #define STATE_CREATE_NEW_C 0x02 /* Created timer but not running */ 41 #define STATE_CREATE_RUN_C 0x03 /* Created timer and running */ 42 #define STATE_CREATE_STOP_C 0x04 /* Created, ran and stopped timer */ 43 #define MAX_NSEC_C 1000000000 /* Maximum number of nsec allowed */ 44 #define MIN_NSEC_C 0 /* Minimum number of nsec allowew */ 45 #define TIMER_RELATIVE_C 0 /* Indicates that the fire time is 46 * relative to the current one */ 47 #define SEC_TO_TICKS_C _TOD_Ticks_per_second /* Number of ticks in a second*/ 48 #define NSEC_PER_SEC_C 1000000000 /* Nanoseconds in a second */ 49 50 #define NO_MORE_TIMERS_C 11 /* There is not available timers */ 51 #define BAD_TIMER_C 11 /* The timer does not exist in the table */ 52 53 #define SECONDS_PER_YEAR_C ( 360 * 24 * 60 * 60 ) 54 #define SECONDS_PER_MONTH_C ( 30 * 24 * 60 * 60 ) 55 #define SECONDS_PER_DAY_C ( 24 * 60 * 60 ) 56 #define SECONDS_PER_HOUR_C ( 60 * 60 ) 57 #define SECONDS_PER_MINUTE_C ( 60 ) 58 16 59 /* 60 #define DEBUG_MESSAGES 61 */ 62 63 /* ********************************************************* 64 * Types that will store the created timers and their data 65 * *********************************************************/ 66 67 /* 68 * Data for a timer 69 */ 70 71 typedef struct { 72 pthread_t thread_id; /* Thread identifier */ 73 char state; /* State of the timer */ 74 struct sigevent inf; /* Information associated to the timer */ 75 timer_t timer_id; /* Created timer identifier */ 76 struct itimerspec timer_data; /* Timing data of the timer */ 77 unsigned32 ticks; /* Number of ticks of the initialization */ 78 unsigned32 overrun; /* Number of expirations of the timer */ 79 rtems_time_of_day time; /* Time in which the timer was started */ 80 } timer_alive_t; 81 82 /* 83 * Array of Timers 84 */ 85 86 int timer_max; 87 timer_alive_t *timer_struct; 88 89 /* 90 * Data for the signals 91 */ 92 93 struct sigaction signal_inf[SIGRTMAX]; 94 95 /*********************************** 96 * Definition of Internal Functions 97 ***********************************/ 98 99 /* *************************************************************************** 100 * PRINT_MSG_S 101 * 102 * Description: This function write a message in the display. 103 * It is used for debugging and all the calls must be deleted 104 * when the tests finish 105 * ***************************************************************************/ 106 107 static void PRINT_MSG_S ( char *msg ) 108 { 109 110 #ifdef DEBUG_MESSAGES 111 printf("%s\n", msg); 112 #endif 113 114 } 115 116 /* *************************************************************************** 117 * PRINT_ERRNO_S 118 * 119 * Description: Print the value of the global variable errno in the display 120 * ***************************************************************************/ 121 122 static void PRINT_ERRNO_S () 123 { 124 #ifdef DEBUG_MESSAGES 125 switch (errno) 126 { 127 case EINVAL: 128 PRINT_MSG_S ( "errno EINVAL"); break; 129 case EPERM: 130 PRINT_MSG_S ( "errno EPERM"); break; 131 case ESRCH: 132 PRINT_MSG_S ( "errno ESRCH"); break; 133 case EAGAIN: 134 PRINT_MSG_S ( "errno EAGAIN"); break; 135 default : 136 printf ("errno: %d\n", errno); 137 break; 138 } 139 #endif 140 } 141 142 /* *************************************************************************** 143 * TIMER_INITIALIZE_S 144 * 145 * Description: Initialize the data of a timer 146 * ***************************************************************************/ 147 148 void TIMER_INITIALIZE_S ( int timer_pos ) 149 { 150 151 /* 152 * Indicates that the position in the table is free 153 */ 154 155 timer_struct[timer_pos].state = STATE_FREE_C; 156 157 /* 158 * The initial data of timing are set with null value 159 */ 160 161 timer_struct[timer_pos].timer_data.it_value.tv_sec = 0; 162 timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0; 163 timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0; 164 timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0; 165 166 /* 167 * The count of expirations is 0 168 */ 169 170 timer_struct[timer_pos].overrun = 0; 171 172 } 173 174 /* *************************************************************************** 175 * _POSIX_Timer_Manager_initialization 176 * 177 * Description: Initialize the internal structure in which the data of all 178 * the timers are stored 179 * ***************************************************************************/ 180 181 void _POSIX_Timer_Manager_initialization ( int max_timers ) 182 { 183 int index; 184 185 timer_struct = _Workspace_Allocate_or_fatal_error( 186 max_timers * sizeof(timer_alive_t) ); 187 188 /* 189 * Initialize all the timers 190 */ 191 192 for (index=0; index<max_timers; index++) 193 TIMER_INITIALIZE_S( index ); 194 } 195 196 /* *************************************************************************** 197 * FIRST_FREE_POSITION_F 198 * 199 * Description: Returns the first free position in the table of timers. 200 * If there is not a free position, it returns NO_MORE_TIMERS_C 201 * ***************************************************************************/ 202 203 int FIRST_FREE_POSITION_F () 204 { 205 int index; 206 207 for (index=0; index<timer_max; index++) { 208 if ( timer_struct[index].state == STATE_FREE_C ) { 209 return index; 210 } 211 } 212 213 /* The function reaches this point only if all the position are occupied */ 214 215 return NO_MORE_TIMERS_C; 216 } 217 218 /* *************************************************************************** 219 * TIMER_POSITION_F 220 * 221 * Description: Returns the position in the table of timers in which the 222 * data of the timer are stored. 223 * If the timer identifier does not exist, it returns 224 * BAD_TIMER_C 225 * ***************************************************************************/ 226 227 int TIMER_POSITION_F ( timer_t timer_id ) 228 { 229 int index; 230 231 for (index=0; index<timer_max; index++ ) { 232 233 /* Looks for the position of the timer. The timer must exist and the 234 * position can not be free */ 235 if ( ( timer_struct[index].timer_id == timer_id ) && 236 ( timer_struct[index].state != STATE_FREE_C ) ) { 237 return index; 238 } 239 } 240 241 /* If the function reaches this point is because the timer identifier 242 * is not correct */ 243 244 return BAD_TIMER_C; 245 246 } 247 248 /* *************************************************************************** 249 * COPY_ITIMERSPEC_S 250 * 251 * Description: Does a copy of a variable of type struct itimerspec 252 * ***************************************************************************/ 253 254 void COPY_ITIMERSPEC_S ( const struct itimerspec *source, 255 struct itimerspec *target ) 256 { 257 258 target->it_value.tv_sec = source->it_value.tv_sec; 259 target->it_value.tv_nsec = source->it_value.tv_nsec; 260 target->it_interval.tv_sec = source->it_interval.tv_sec; 261 target->it_interval.tv_nsec = source->it_interval.tv_nsec; 262 263 } 264 265 /* *************************************************************************** 266 * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S 267 * 268 * Description: This function converts the data of a structure itimerspec 269 * into structure rtems_time_of_day 270 * ***************************************************************************/ 271 272 void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S 273 ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time ) 274 { 275 unsigned long int seconds; 276 277 /* The leap years and the months with 28, 29 or 31 days have not been 278 * considerated. It will be made in the future */ 279 280 seconds = itimer->it_value.tv_sec; 281 282 rtems_time->year = seconds / SECONDS_PER_YEAR_C; 283 seconds = seconds % SECONDS_PER_YEAR_C; 284 285 rtems_time->month = seconds / SECONDS_PER_MONTH_C; 286 seconds = seconds % SECONDS_PER_MONTH_C; 287 288 rtems_time->day = seconds / SECONDS_PER_DAY_C; 289 seconds = seconds % SECONDS_PER_DAY_C; 290 291 rtems_time->hour = seconds / SECONDS_PER_HOUR_C; 292 seconds = seconds % SECONDS_PER_HOUR_C; 293 294 rtems_time->minute = seconds / SECONDS_PER_MINUTE_C; 295 seconds = seconds % SECONDS_PER_MINUTE_C; 296 297 rtems_time->second = seconds; 298 299 rtems_time->ticks = ( itimer->it_value.tv_nsec * SEC_TO_TICKS_C ) / 300 NSEC_PER_SEC_C; 301 302 } 303 304 305 /* *************************************************************************** 306 * FIRE_TIMER_S 307 * 308 * Description: This is the operation that is ran when a timer expires 309 * ***************************************************************************/ 310 311 312 rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data) 313 { 314 int timer_pos; /* Position in the table of the timer that 315 * has expirated */ 316 rtems_status_code return_v; /* Return value of rtems_timer_fire_after */ 317 int sig_number; /* Number of the signal to send */ 318 319 320 /* The position of the table of timers that contains the data of the 321 * expired timer will be stored in "timer_pos". In theory a timer can not 322 * expire if it has not been created or has been deleted */ 323 324 PRINT_MSG_S ("FIRE_TIMER_S"); 325 326 timer_pos = TIMER_POSITION_F(timer); 327 328 /* Increases the number of expiration of the timer in one unit. */ 329 timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1; 330 331 332 if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec != 0 ) || 333 ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) { 334 335 /* The timer must be reprogrammed */ 336 337 return_v = rtems_timer_fire_after ( timer, 338 timer_struct[timer_pos].ticks, 339 FIRE_TIMER_S, 340 NULL ); 341 342 /* Stores the time when the timer was started again */ 343 344 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, 345 &timer_struct[timer_pos].time ); 346 347 /* The state has not to be actualized, because nothing modifies it */ 348 349 timer_struct[timer_pos].state = STATE_CREATE_RUN_C; 350 351 } else { 352 /* Indicates that the timer is stopped */ 353 354 timer_struct[timer_pos].state = STATE_CREATE_STOP_C; 355 356 } 357 358 /* 359 * The sending of the signal to the process running the handling function 360 * specified for that signal is simulated 361 */ 362 363 sig_number = timer_struct[timer_pos].inf.sigev_signo; 364 365 if( pthread_kill ( timer_struct[timer_pos].thread_id , 366 timer_struct[timer_pos].inf.sigev_signo ) ) { 367 PRINT_MSG_S ("ERROR_PTHREAD_KILL"); 368 } else { 369 PRINT_MSG_S ("SUCCESS_PTHREAD_KILL"); 370 } 371 372 /* 373 * After the signal handler returns, the count of expirations of the 374 * timer must be set to 0. 375 */ 376 377 timer_struct[timer_pos].overrun = 0; 378 379 } 380 381 /* ********************************************************************* 17 382 * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264 18 */ 383 * ********************************************************************/ 384 385 /* ************** 386 * timer_create 387 * **************/ 19 388 20 389 int timer_create( … … 24 393 ) 25 394 { 26 return POSIX_NOT_IMPLEMENTED(); 395 396 rtems_status_code return_v; /* return value of the operation */ 397 rtems_id timer_id; /* created timer identifier */ 398 int timer_pos; /* Position in the table of timers */ 399 400 /* 401 * The data of the structure evp are checked in order to verify if they 402 * are coherent. 403 */ 404 405 if (evp != NULL) { 406 /* The structure has data */ 407 408 if ( ( evp->sigev_notify != SIGEV_NONE ) && 409 ( evp->sigev_notify != SIGEV_SIGNAL ) ) { 410 /* The value of the field sigev_notify is not valid */ 411 412 return (-1); 413 414 } 415 } 416 417 /* 418 * A timer is created using the primitive rtems_timer_create 419 */ 420 421 return_v = rtems_timer_create ( clock_id, &timer_id ); 422 423 switch (return_v) { 424 case RTEMS_SUCCESSFUL : 425 426 PRINT_MSG_S("SUCCESS: rtems create timer RTEMS_SUCCESSFUL"); 427 428 /* 429 * The timer has been created properly 430 */ 431 432 /* Obtains the first free position in the table of timers */ 433 434 timer_pos = FIRST_FREE_POSITION_F(); 435 436 if ( timer_pos == NO_MORE_TIMERS_C ) { 437 /* There is not position for another timers in spite of RTEMS 438 * supports it. It will necessaty to increase the structure used */ 439 440 errno = EAGAIN; 441 442 return -1; 443 } 444 445 /* Exit parameter */ 446 447 *timerid = timer_id; 448 449 /* The data of the created timer are stored to use them later */ 450 451 timer_struct[timer_pos].state = STATE_CREATE_NEW_C; 452 453 /* NEW VERSION*/ 454 timer_struct[timer_pos].thread_id = pthread_self (); 455 456 457 if ( evp != NULL ) { 458 459 timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify; 460 timer_struct[timer_pos].inf.sigev_signo = evp->sigev_signo; 461 timer_struct[timer_pos].inf.sigev_value = evp->sigev_value; 462 463 } 464 465 466 timer_struct[timer_pos].timer_id = timer_id; 467 468 timer_struct[timer_pos].overrun = 0; 469 470 timer_struct[timer_pos].timer_data.it_value.tv_sec = 0; 471 timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0; 472 timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0; 473 timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0; 474 475 return 0; 476 477 478 case RTEMS_INVALID_NAME : /* The assigned name is not valid*/ 479 480 PRINT_MSG_S ("ERROR: rtems create timer RTEMS_INVALID_NAME"); 481 482 errno = EINVAL; 483 484 return (-1); 485 486 487 case RTEMS_TOO_MANY : 488 489 PRINT_MSG_S ("ERROR: rtems create timer RTEMS_TOO_MANY "); 490 491 /* There has been created too much timers for the same process */ 492 493 errno = EAGAIN; 494 495 return (-1); 496 497 default : 498 499 /* 500 * Does nothing. It only returns the error without assigning a value 501 * to errno. In theory, it can not happen because the call to 502 * rtems_timer_create can not return other different value. 503 */ 504 505 return (-1); 506 507 } 508 509 /* 510 * The next sentence is used to avoid singular situations 511 */ 512 513 return (-1); 514 27 515 } 28 516 … … 35 523 ) 36 524 { 37 return POSIX_NOT_IMPLEMENTED(); 525 526 /* 527 * IDEA: This function must probably stop the timer first and then delete it 528 * 529 * It will have to do a call to rtems_timer_cancel and then another 530 * call to rtems_timer_delete. 531 * The call to rtems_timer_delete will be probably unnecessary, 532 * because rtems_timer_delete stops the timer before deleting it. 533 */ 534 535 int timer_pos; 536 rtems_status_code status; 537 538 539 /* First the position in the table of timers is obtained */ 540 541 timer_pos = TIMER_POSITION_F ( timerid ); 542 543 if ( timer_pos == BAD_TIMER_C ) { 544 /* The timer identifier is erroneus */ 545 546 errno = EINVAL; 547 return -1; 548 } 549 550 /* The timer is deleted */ 551 552 status = rtems_timer_delete ( timerid ); 553 554 if ( status == RTEMS_INVALID_ID ) { 555 /* The timer identifier is erroneus */ 556 557 errno = EINVAL; 558 return -1; 559 } 560 561 /* Initializes the data of the timer */ 562 563 TIMER_INITIALIZE_S ( timer_pos ); 564 565 return 0; 38 566 } 39 567 … … 41 569 * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 42 570 */ 571 572 /* ************** 573 * timer_settime 574 * **************/ 575 43 576 44 577 int timer_settime( … … 49 582 ) 50 583 { 51 return POSIX_NOT_IMPLEMENTED(); 52 } 584 585 rtems_status_code return_v; /* Return of the calls to RTEMS */ 586 int timer_pos; /* Position of the timer in the table */ 587 rtems_time_of_day rtems_time; /* Time in RTEMS */ 588 589 /* First the position in the table of timers is obtained */ 590 591 timer_pos = TIMER_POSITION_F ( timerid ); 592 593 if ( timer_pos == BAD_TIMER_C ) { 594 /* The timer identifier is erroneus */ 595 596 errno = EINVAL; 597 return -1; 598 } 599 600 if ( value == NULL ) { 601 /* The stucture of times of the timer is free, and then returns an 602 error but the variable errno is not actualized */ 603 604 /* errno = ?????? */ 605 606 return -1; 607 } 608 609 /* If the function reaches this point, then it will be necessary to do 610 * something with the structure of times of the timer: to stop, start 611 * or start it again */ 612 613 /* First, it verifies if the timer must be stopped */ 614 615 if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) { 616 /* The timer is stopped */ 617 618 return_v = rtems_timer_cancel ( timerid ); 619 620 /* The old data of the timer are returned */ 621 622 COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue ); 623 624 /* The new data are set */ 625 626 COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data ); 627 628 /* Indicates that the timer is created and stopped */ 629 630 timer_struct[timer_pos].state = STATE_CREATE_STOP_C; 631 632 /* Returns with success */ 633 634 return 0; 635 } 636 637 /* 638 * If the function reaches this point, then the timer will have to be 639 * initialized with new values: to start it or start it again 640 */ 641 642 /* First, it verifies if the structure "value" is correct */ 643 644 if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) || 645 ( value->it_value.tv_nsec < MIN_NSEC_C ) ) { 646 /* The number of nanoseconds is not correct */ 647 648 errno = EINVAL; 649 650 return -1; 651 } 652 653 /* Then, "value" must be converted from seconds and nanoseconds to clock 654 * ticks, to use it in the calls to RTEMS */ 655 656 /* It is also necessary to take in account if the time is absolute 657 * or relative */ 658 659 switch (flags) { 660 case TIMER_ABSTIME: 661 662 /* The fire time is absolute: 663 * It has to use "rtems_time_fire_when" */ 664 665 /* First, it converts from struct itimerspec to rtems_time_of_day */ 666 667 ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time ); 668 669 return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL); 670 671 switch ( return_v ) { 672 case RTEMS_SUCCESSFUL: 673 674 PRINT_MSG_S ("SUCCESS: timer_settime RTEMS_SUCCESSFUL"); 675 676 /* The timer has been started and is running */ 677 678 /* Actualizes the data of the structure and 679 * returns the old ones in "ovalue" */ 680 681 COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue ); 682 683 COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data ); 684 685 /* It indicates that the time is running */ 686 687 timer_struct[timer_pos].state = STATE_CREATE_RUN_C; 688 689 /* Stores the time in which the timer was started again */ 690 691 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, 692 &timer_struct[timer_pos].time ); 693 694 return 0; 695 696 break; 697 698 case RTEMS_INVALID_ID: 699 700 PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_ID"); 701 break; 702 703 case RTEMS_NOT_DEFINED: 704 705 PRINT_MSG_S ("ERROR: timer_settime RTEMS_NOT_DEFINED"); 706 break; 707 708 case RTEMS_INVALID_CLOCK: 709 710 PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_CLOCK"); 711 break; 712 713 default: 714 715 716 } 717 718 break; 719 720 case TIMER_RELATIVE_C: 721 722 /* The fire time is relative: 723 * It has to use "rtems_time_fire_after" */ 724 725 /* First, it converts from seconds and nanoseconds to ticks */ 726 727 /* The form in which this operation is done can produce a lost 728 * of precision of 1 second */ 729 730 /* This is the process to convert from nanoseconds to ticks 731 * 732 * There is a tick every 10 miliseconds, then the nanoseconds are 733 * divided between 10**7. The result of this operation will be the 734 * number of ticks 735 */ 736 737 timer_struct[timer_pos].ticks = 738 ( SEC_TO_TICKS_C * value->it_value.tv_sec ) + 739 ( value->it_value.tv_nsec / ( 1000 * 1000 * 10 ) ); 740 741 return_v = rtems_timer_fire_after ( timerid, 742 timer_struct[timer_pos].ticks, 743 FIRE_TIMER_S, 744 NULL ); 745 746 switch (return_v) { 747 case RTEMS_SUCCESSFUL: 748 749 PRINT_MSG_S ( "SUCCESS: timer_settime RTEMS_SUCCESSFUL"); 750 751 /* The timer has been started and is running */ 752 753 /* Actualizes the data of the structure and 754 * returns the old ones in "ovalue" */ 755 756 COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue ); 757 758 COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data ); 759 760 /* It indicates that the time is running */ 761 762 timer_struct[timer_pos].state = STATE_CREATE_RUN_C; 763 764 /* Stores the time in which the timer was started again */ 765 766 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, 767 &timer_struct[timer_pos].time ); 768 769 return 0; 770 771 break; 772 773 case RTEMS_INVALID_ID: 774 775 PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_ID"); 776 777 /* The timer identifier is not correct. In theory, this 778 * situation can not occur, but the solution is easy */ 779 780 errno = EINVAL; 781 782 return -1; 783 784 break; 785 786 case RTEMS_INVALID_NUMBER: 787 788 PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_NUMBER"); 789 790 /* In this case, RTEMS fails because the values of timing 791 * are incorrect */ 792 793 /* 794 * I do not know if errno must be actualized 795 * 796 * errno = EINVAL; 797 */ 798 799 return -1; 800 801 break; 802 803 default: 804 } 805 806 break; 807 808 default: 809 810 /* It does nothing, although it will be probably necessary to 811 * return an error */ 812 813 } 814 815 /* To avoid problems */ 816 817 return 0; 818 819 } 820 53 821 54 822 /* 55 823 * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 56 824 */ 825 826 /* ************** 827 * timer_gettime 828 * **************/ 57 829 58 830 int timer_gettime( … … 61 833 ) 62 834 { 63 return POSIX_NOT_IMPLEMENTED(); 835 836 /* 837 * IDEA: This function does not use functions of RTEMS to the handle 838 * of timers. It uses some functions for managing the time. 839 * 840 * A possible form to do this is the following: 841 * 842 * - When a timer is initialized, the value of the time in 843 * that moment is stored. 844 * - When this function is called, it returns the difference 845 * between the current time and the initialization time. 846 */ 847 848 rtems_time_of_day current_time; 849 rtems_status_code return_v; 850 int timer_pos; 851 unsigned32 hours; 852 unsigned32 minutes; 853 unsigned32 seconds; 854 unsigned32 ticks; 855 unsigned32 nanosec; 856 857 858 /* Reads the current time */ 859 860 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, ¤t_time ); 861 862 timer_pos = TIMER_POSITION_F ( timerid ); 863 864 if ( timer_pos == BAD_TIMER_C ) { 865 866 /* The timer identifier is erroneus */ 867 868 errno = EINVAL; 869 870 return (-1); 871 872 } 873 874 /* Calculates the difference between the start time of the timer and 875 * the current one */ 876 877 hours = current_time.hour - timer_struct[timer_pos].time.hour; 878 879 if ( current_time.minute < timer_struct[timer_pos].time.minute ) { 880 minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute; 881 hours--; 882 } else { 883 minutes = current_time.minute - timer_struct[timer_pos].time.minute; 884 } 885 886 if ( current_time.second < timer_struct[timer_pos].time.second ) { 887 seconds = 60 - timer_struct[timer_pos].time.second + current_time.second; 888 minutes--; 889 } else { 890 seconds = current_time.second - timer_struct[timer_pos].time.second; 891 } 892 893 if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) { 894 ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks; 895 seconds--; 896 } else { 897 ticks = current_time.ticks - timer_struct[timer_pos].time.ticks; 898 } 899 900 /* The time that the timer is running is calculated */ 901 seconds = hours * 60 * 60 + 902 minutes * 60 + 903 seconds; 904 905 nanosec = ticks * 10 * /* msec */ 906 1000 * /* microsec */ 907 1000; /* nanosec */ 908 909 910 /* Calculates the time left before the timer finishes */ 911 912 value->it_value.tv_sec = 913 timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds; 914 915 value->it_value.tv_nsec = 916 timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec; 917 918 919 value->it_interval.tv_sec = 920 timer_struct[timer_pos].timer_data.it_interval.tv_sec; 921 value->it_interval.tv_nsec = 922 timer_struct[timer_pos].timer_data.it_interval.tv_nsec; 923 924 925 return 0; 926 64 927 } 65 928 … … 68 931 */ 69 932 933 /* ***************** 934 * timer_getoverrun 935 * *****************/ 936 70 937 int timer_getoverrun( 71 938 timer_t timerid 72 939 ) 73 940 { 74 return POSIX_NOT_IMPLEMENTED(); 75 } 941 942 /* 943 * IDEA: This function must count the times the timer expires. 944 * 945 * The expiration of a timer must increase by one a counter. 946 * After the signal handler associated to the timer finishs 947 * its execution, FIRE_TIMER_S will have to set this counter to 0. 948 */ 949 950 int timer_pos; /* Position of the timer in the structure */ 951 int overrun; /* Overflow count */ 952 953 954 timer_pos = TIMER_POSITION_F ( timerid ); 955 956 if ( timer_pos == BAD_TIMER_C ) { 957 /* The timer identifier is erroneus */ 958 959 errno = EINVAL; 960 961 return -1; 962 } 963 964 /* The overflow count of the timer is stored in "overrun" */ 965 966 overrun = timer_struct[timer_pos].overrun; 967 968 /* It is set to 0 */ 969 970 timer_struct[timer_pos].overrun = 0; 971 972 return overrun; 973 974 } -
c/src/exec/sapi/include/confdefs.h
rc30d04d7 r0747e2d 354 354 #endif 355 355 356 #ifndef CONFIGURE_MAXIMUM_POSIX_TIMERS 357 #define CONFIGURE_MAXIMUM_POSIX_TIMERS 0 358 #endif 359 356 360 #ifndef CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 357 361 #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 0 … … 412 416 ((_keys) * \ 413 417 ( sizeof(POSIX_Keys_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) ) 418 419 #define CONFIGURE_MEMORY_FOR_POSIX_TIMERS(_timers) \ 420 ((_timers) * \ 421 ( 0 ) ) 414 422 415 423 #define CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(_queued_signals) \ … … 618 626 CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS, 619 627 CONFIGURE_MAXIMUM_POSIX_KEYS + CONFIGURE_GNAT_KEYS, 628 CONFIGURE_MAXIMUM_POSIX_TIMERS, 620 629 CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS, 621 630 CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE, -
c/src/exec/sapi/src/posixapi.c
rc30d04d7 r0747e2d 37 37 #include <rtems/posix/psignal.h> 38 38 #include <rtems/posix/pthread.h> 39 #include <rtems/posix/ptimer.h> 39 40 #include <rtems/posix/time.h> 40 41 … … 51 52 0, /* maximum_condition_variables */ 52 53 0, /* maximum_keys */ 54 0, /* maximum_timers */ 53 55 0, /* maximum_queued_signals */ 54 56 0, /* number_of_initialization_threads */ … … 91 93 ); 92 94 95 _POSIX_Timer_Manager_initialization ( api_configuration->maximum_timers ); 93 96 } 94 97 -
cpukit/posix/include/rtems/posix/config.h
rc30d04d7 r0747e2d 47 47 int maximum_condition_variables; 48 48 int maximum_keys; 49 int maximum_timers; 49 50 int maximum_queued_signals; 50 51 int number_of_initialization_threads; -
cpukit/posix/src/ptimer.c
rc30d04d7 r0747e2d 1 1 /* 2 * $Id$2 * ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp 3 3 */ 4 4 5 5 #include <assert.h> 6 6 #include <time.h> … … 14 14 #include <rtems/posix/time.h> 15 15 16 /************************************/ 17 /* These includes are now necessary */ 18 /************************************/ 19 20 #include <sys/features.h> 21 #include <rtems/rtems/status.h> 22 #include <rtems/rtems/types.h> 23 #include <rtems/rtems/timer.h> 24 #include <rtems/rtems/clock.h> 25 #include <rtems/posix/psignal.h> 26 #include <rtems/score/wkspace.h> 27 #include <pthread.h> 28 #include <stdio.h> 29 #include <signal.h> 30 31 /*****************************/ 32 /* End of necessary includes */ 33 /*****************************/ 34 35 /* ************ 36 * Constants 37 * ************/ 38 39 #define STATE_FREE_C 0x01 /* Free position of the table of timers */ 40 #define STATE_CREATE_NEW_C 0x02 /* Created timer but not running */ 41 #define STATE_CREATE_RUN_C 0x03 /* Created timer and running */ 42 #define STATE_CREATE_STOP_C 0x04 /* Created, ran and stopped timer */ 43 #define MAX_NSEC_C 1000000000 /* Maximum number of nsec allowed */ 44 #define MIN_NSEC_C 0 /* Minimum number of nsec allowew */ 45 #define TIMER_RELATIVE_C 0 /* Indicates that the fire time is 46 * relative to the current one */ 47 #define SEC_TO_TICKS_C _TOD_Ticks_per_second /* Number of ticks in a second*/ 48 #define NSEC_PER_SEC_C 1000000000 /* Nanoseconds in a second */ 49 50 #define NO_MORE_TIMERS_C 11 /* There is not available timers */ 51 #define BAD_TIMER_C 11 /* The timer does not exist in the table */ 52 53 #define SECONDS_PER_YEAR_C ( 360 * 24 * 60 * 60 ) 54 #define SECONDS_PER_MONTH_C ( 30 * 24 * 60 * 60 ) 55 #define SECONDS_PER_DAY_C ( 24 * 60 * 60 ) 56 #define SECONDS_PER_HOUR_C ( 60 * 60 ) 57 #define SECONDS_PER_MINUTE_C ( 60 ) 58 16 59 /* 60 #define DEBUG_MESSAGES 61 */ 62 63 /* ********************************************************* 64 * Types that will store the created timers and their data 65 * *********************************************************/ 66 67 /* 68 * Data for a timer 69 */ 70 71 typedef struct { 72 pthread_t thread_id; /* Thread identifier */ 73 char state; /* State of the timer */ 74 struct sigevent inf; /* Information associated to the timer */ 75 timer_t timer_id; /* Created timer identifier */ 76 struct itimerspec timer_data; /* Timing data of the timer */ 77 unsigned32 ticks; /* Number of ticks of the initialization */ 78 unsigned32 overrun; /* Number of expirations of the timer */ 79 rtems_time_of_day time; /* Time in which the timer was started */ 80 } timer_alive_t; 81 82 /* 83 * Array of Timers 84 */ 85 86 int timer_max; 87 timer_alive_t *timer_struct; 88 89 /* 90 * Data for the signals 91 */ 92 93 struct sigaction signal_inf[SIGRTMAX]; 94 95 /*********************************** 96 * Definition of Internal Functions 97 ***********************************/ 98 99 /* *************************************************************************** 100 * PRINT_MSG_S 101 * 102 * Description: This function write a message in the display. 103 * It is used for debugging and all the calls must be deleted 104 * when the tests finish 105 * ***************************************************************************/ 106 107 static void PRINT_MSG_S ( char *msg ) 108 { 109 110 #ifdef DEBUG_MESSAGES 111 printf("%s\n", msg); 112 #endif 113 114 } 115 116 /* *************************************************************************** 117 * PRINT_ERRNO_S 118 * 119 * Description: Print the value of the global variable errno in the display 120 * ***************************************************************************/ 121 122 static void PRINT_ERRNO_S () 123 { 124 #ifdef DEBUG_MESSAGES 125 switch (errno) 126 { 127 case EINVAL: 128 PRINT_MSG_S ( "errno EINVAL"); break; 129 case EPERM: 130 PRINT_MSG_S ( "errno EPERM"); break; 131 case ESRCH: 132 PRINT_MSG_S ( "errno ESRCH"); break; 133 case EAGAIN: 134 PRINT_MSG_S ( "errno EAGAIN"); break; 135 default : 136 printf ("errno: %d\n", errno); 137 break; 138 } 139 #endif 140 } 141 142 /* *************************************************************************** 143 * TIMER_INITIALIZE_S 144 * 145 * Description: Initialize the data of a timer 146 * ***************************************************************************/ 147 148 void TIMER_INITIALIZE_S ( int timer_pos ) 149 { 150 151 /* 152 * Indicates that the position in the table is free 153 */ 154 155 timer_struct[timer_pos].state = STATE_FREE_C; 156 157 /* 158 * The initial data of timing are set with null value 159 */ 160 161 timer_struct[timer_pos].timer_data.it_value.tv_sec = 0; 162 timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0; 163 timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0; 164 timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0; 165 166 /* 167 * The count of expirations is 0 168 */ 169 170 timer_struct[timer_pos].overrun = 0; 171 172 } 173 174 /* *************************************************************************** 175 * _POSIX_Timer_Manager_initialization 176 * 177 * Description: Initialize the internal structure in which the data of all 178 * the timers are stored 179 * ***************************************************************************/ 180 181 void _POSIX_Timer_Manager_initialization ( int max_timers ) 182 { 183 int index; 184 185 timer_struct = _Workspace_Allocate_or_fatal_error( 186 max_timers * sizeof(timer_alive_t) ); 187 188 /* 189 * Initialize all the timers 190 */ 191 192 for (index=0; index<max_timers; index++) 193 TIMER_INITIALIZE_S( index ); 194 } 195 196 /* *************************************************************************** 197 * FIRST_FREE_POSITION_F 198 * 199 * Description: Returns the first free position in the table of timers. 200 * If there is not a free position, it returns NO_MORE_TIMERS_C 201 * ***************************************************************************/ 202 203 int FIRST_FREE_POSITION_F () 204 { 205 int index; 206 207 for (index=0; index<timer_max; index++) { 208 if ( timer_struct[index].state == STATE_FREE_C ) { 209 return index; 210 } 211 } 212 213 /* The function reaches this point only if all the position are occupied */ 214 215 return NO_MORE_TIMERS_C; 216 } 217 218 /* *************************************************************************** 219 * TIMER_POSITION_F 220 * 221 * Description: Returns the position in the table of timers in which the 222 * data of the timer are stored. 223 * If the timer identifier does not exist, it returns 224 * BAD_TIMER_C 225 * ***************************************************************************/ 226 227 int TIMER_POSITION_F ( timer_t timer_id ) 228 { 229 int index; 230 231 for (index=0; index<timer_max; index++ ) { 232 233 /* Looks for the position of the timer. The timer must exist and the 234 * position can not be free */ 235 if ( ( timer_struct[index].timer_id == timer_id ) && 236 ( timer_struct[index].state != STATE_FREE_C ) ) { 237 return index; 238 } 239 } 240 241 /* If the function reaches this point is because the timer identifier 242 * is not correct */ 243 244 return BAD_TIMER_C; 245 246 } 247 248 /* *************************************************************************** 249 * COPY_ITIMERSPEC_S 250 * 251 * Description: Does a copy of a variable of type struct itimerspec 252 * ***************************************************************************/ 253 254 void COPY_ITIMERSPEC_S ( const struct itimerspec *source, 255 struct itimerspec *target ) 256 { 257 258 target->it_value.tv_sec = source->it_value.tv_sec; 259 target->it_value.tv_nsec = source->it_value.tv_nsec; 260 target->it_interval.tv_sec = source->it_interval.tv_sec; 261 target->it_interval.tv_nsec = source->it_interval.tv_nsec; 262 263 } 264 265 /* *************************************************************************** 266 * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S 267 * 268 * Description: This function converts the data of a structure itimerspec 269 * into structure rtems_time_of_day 270 * ***************************************************************************/ 271 272 void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S 273 ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time ) 274 { 275 unsigned long int seconds; 276 277 /* The leap years and the months with 28, 29 or 31 days have not been 278 * considerated. It will be made in the future */ 279 280 seconds = itimer->it_value.tv_sec; 281 282 rtems_time->year = seconds / SECONDS_PER_YEAR_C; 283 seconds = seconds % SECONDS_PER_YEAR_C; 284 285 rtems_time->month = seconds / SECONDS_PER_MONTH_C; 286 seconds = seconds % SECONDS_PER_MONTH_C; 287 288 rtems_time->day = seconds / SECONDS_PER_DAY_C; 289 seconds = seconds % SECONDS_PER_DAY_C; 290 291 rtems_time->hour = seconds / SECONDS_PER_HOUR_C; 292 seconds = seconds % SECONDS_PER_HOUR_C; 293 294 rtems_time->minute = seconds / SECONDS_PER_MINUTE_C; 295 seconds = seconds % SECONDS_PER_MINUTE_C; 296 297 rtems_time->second = seconds; 298 299 rtems_time->ticks = ( itimer->it_value.tv_nsec * SEC_TO_TICKS_C ) / 300 NSEC_PER_SEC_C; 301 302 } 303 304 305 /* *************************************************************************** 306 * FIRE_TIMER_S 307 * 308 * Description: This is the operation that is ran when a timer expires 309 * ***************************************************************************/ 310 311 312 rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data) 313 { 314 int timer_pos; /* Position in the table of the timer that 315 * has expirated */ 316 rtems_status_code return_v; /* Return value of rtems_timer_fire_after */ 317 int sig_number; /* Number of the signal to send */ 318 319 320 /* The position of the table of timers that contains the data of the 321 * expired timer will be stored in "timer_pos". In theory a timer can not 322 * expire if it has not been created or has been deleted */ 323 324 PRINT_MSG_S ("FIRE_TIMER_S"); 325 326 timer_pos = TIMER_POSITION_F(timer); 327 328 /* Increases the number of expiration of the timer in one unit. */ 329 timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1; 330 331 332 if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec != 0 ) || 333 ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) { 334 335 /* The timer must be reprogrammed */ 336 337 return_v = rtems_timer_fire_after ( timer, 338 timer_struct[timer_pos].ticks, 339 FIRE_TIMER_S, 340 NULL ); 341 342 /* Stores the time when the timer was started again */ 343 344 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, 345 &timer_struct[timer_pos].time ); 346 347 /* The state has not to be actualized, because nothing modifies it */ 348 349 timer_struct[timer_pos].state = STATE_CREATE_RUN_C; 350 351 } else { 352 /* Indicates that the timer is stopped */ 353 354 timer_struct[timer_pos].state = STATE_CREATE_STOP_C; 355 356 } 357 358 /* 359 * The sending of the signal to the process running the handling function 360 * specified for that signal is simulated 361 */ 362 363 sig_number = timer_struct[timer_pos].inf.sigev_signo; 364 365 if( pthread_kill ( timer_struct[timer_pos].thread_id , 366 timer_struct[timer_pos].inf.sigev_signo ) ) { 367 PRINT_MSG_S ("ERROR_PTHREAD_KILL"); 368 } else { 369 PRINT_MSG_S ("SUCCESS_PTHREAD_KILL"); 370 } 371 372 /* 373 * After the signal handler returns, the count of expirations of the 374 * timer must be set to 0. 375 */ 376 377 timer_struct[timer_pos].overrun = 0; 378 379 } 380 381 /* ********************************************************************* 17 382 * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264 18 */ 383 * ********************************************************************/ 384 385 /* ************** 386 * timer_create 387 * **************/ 19 388 20 389 int timer_create( … … 24 393 ) 25 394 { 26 return POSIX_NOT_IMPLEMENTED(); 395 396 rtems_status_code return_v; /* return value of the operation */ 397 rtems_id timer_id; /* created timer identifier */ 398 int timer_pos; /* Position in the table of timers */ 399 400 /* 401 * The data of the structure evp are checked in order to verify if they 402 * are coherent. 403 */ 404 405 if (evp != NULL) { 406 /* The structure has data */ 407 408 if ( ( evp->sigev_notify != SIGEV_NONE ) && 409 ( evp->sigev_notify != SIGEV_SIGNAL ) ) { 410 /* The value of the field sigev_notify is not valid */ 411 412 return (-1); 413 414 } 415 } 416 417 /* 418 * A timer is created using the primitive rtems_timer_create 419 */ 420 421 return_v = rtems_timer_create ( clock_id, &timer_id ); 422 423 switch (return_v) { 424 case RTEMS_SUCCESSFUL : 425 426 PRINT_MSG_S("SUCCESS: rtems create timer RTEMS_SUCCESSFUL"); 427 428 /* 429 * The timer has been created properly 430 */ 431 432 /* Obtains the first free position in the table of timers */ 433 434 timer_pos = FIRST_FREE_POSITION_F(); 435 436 if ( timer_pos == NO_MORE_TIMERS_C ) { 437 /* There is not position for another timers in spite of RTEMS 438 * supports it. It will necessaty to increase the structure used */ 439 440 errno = EAGAIN; 441 442 return -1; 443 } 444 445 /* Exit parameter */ 446 447 *timerid = timer_id; 448 449 /* The data of the created timer are stored to use them later */ 450 451 timer_struct[timer_pos].state = STATE_CREATE_NEW_C; 452 453 /* NEW VERSION*/ 454 timer_struct[timer_pos].thread_id = pthread_self (); 455 456 457 if ( evp != NULL ) { 458 459 timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify; 460 timer_struct[timer_pos].inf.sigev_signo = evp->sigev_signo; 461 timer_struct[timer_pos].inf.sigev_value = evp->sigev_value; 462 463 } 464 465 466 timer_struct[timer_pos].timer_id = timer_id; 467 468 timer_struct[timer_pos].overrun = 0; 469 470 timer_struct[timer_pos].timer_data.it_value.tv_sec = 0; 471 timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0; 472 timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0; 473 timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0; 474 475 return 0; 476 477 478 case RTEMS_INVALID_NAME : /* The assigned name is not valid*/ 479 480 PRINT_MSG_S ("ERROR: rtems create timer RTEMS_INVALID_NAME"); 481 482 errno = EINVAL; 483 484 return (-1); 485 486 487 case RTEMS_TOO_MANY : 488 489 PRINT_MSG_S ("ERROR: rtems create timer RTEMS_TOO_MANY "); 490 491 /* There has been created too much timers for the same process */ 492 493 errno = EAGAIN; 494 495 return (-1); 496 497 default : 498 499 /* 500 * Does nothing. It only returns the error without assigning a value 501 * to errno. In theory, it can not happen because the call to 502 * rtems_timer_create can not return other different value. 503 */ 504 505 return (-1); 506 507 } 508 509 /* 510 * The next sentence is used to avoid singular situations 511 */ 512 513 return (-1); 514 27 515 } 28 516 … … 35 523 ) 36 524 { 37 return POSIX_NOT_IMPLEMENTED(); 525 526 /* 527 * IDEA: This function must probably stop the timer first and then delete it 528 * 529 * It will have to do a call to rtems_timer_cancel and then another 530 * call to rtems_timer_delete. 531 * The call to rtems_timer_delete will be probably unnecessary, 532 * because rtems_timer_delete stops the timer before deleting it. 533 */ 534 535 int timer_pos; 536 rtems_status_code status; 537 538 539 /* First the position in the table of timers is obtained */ 540 541 timer_pos = TIMER_POSITION_F ( timerid ); 542 543 if ( timer_pos == BAD_TIMER_C ) { 544 /* The timer identifier is erroneus */ 545 546 errno = EINVAL; 547 return -1; 548 } 549 550 /* The timer is deleted */ 551 552 status = rtems_timer_delete ( timerid ); 553 554 if ( status == RTEMS_INVALID_ID ) { 555 /* The timer identifier is erroneus */ 556 557 errno = EINVAL; 558 return -1; 559 } 560 561 /* Initializes the data of the timer */ 562 563 TIMER_INITIALIZE_S ( timer_pos ); 564 565 return 0; 38 566 } 39 567 … … 41 569 * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 42 570 */ 571 572 /* ************** 573 * timer_settime 574 * **************/ 575 43 576 44 577 int timer_settime( … … 49 582 ) 50 583 { 51 return POSIX_NOT_IMPLEMENTED(); 52 } 584 585 rtems_status_code return_v; /* Return of the calls to RTEMS */ 586 int timer_pos; /* Position of the timer in the table */ 587 rtems_time_of_day rtems_time; /* Time in RTEMS */ 588 589 /* First the position in the table of timers is obtained */ 590 591 timer_pos = TIMER_POSITION_F ( timerid ); 592 593 if ( timer_pos == BAD_TIMER_C ) { 594 /* The timer identifier is erroneus */ 595 596 errno = EINVAL; 597 return -1; 598 } 599 600 if ( value == NULL ) { 601 /* The stucture of times of the timer is free, and then returns an 602 error but the variable errno is not actualized */ 603 604 /* errno = ?????? */ 605 606 return -1; 607 } 608 609 /* If the function reaches this point, then it will be necessary to do 610 * something with the structure of times of the timer: to stop, start 611 * or start it again */ 612 613 /* First, it verifies if the timer must be stopped */ 614 615 if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) { 616 /* The timer is stopped */ 617 618 return_v = rtems_timer_cancel ( timerid ); 619 620 /* The old data of the timer are returned */ 621 622 COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue ); 623 624 /* The new data are set */ 625 626 COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data ); 627 628 /* Indicates that the timer is created and stopped */ 629 630 timer_struct[timer_pos].state = STATE_CREATE_STOP_C; 631 632 /* Returns with success */ 633 634 return 0; 635 } 636 637 /* 638 * If the function reaches this point, then the timer will have to be 639 * initialized with new values: to start it or start it again 640 */ 641 642 /* First, it verifies if the structure "value" is correct */ 643 644 if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) || 645 ( value->it_value.tv_nsec < MIN_NSEC_C ) ) { 646 /* The number of nanoseconds is not correct */ 647 648 errno = EINVAL; 649 650 return -1; 651 } 652 653 /* Then, "value" must be converted from seconds and nanoseconds to clock 654 * ticks, to use it in the calls to RTEMS */ 655 656 /* It is also necessary to take in account if the time is absolute 657 * or relative */ 658 659 switch (flags) { 660 case TIMER_ABSTIME: 661 662 /* The fire time is absolute: 663 * It has to use "rtems_time_fire_when" */ 664 665 /* First, it converts from struct itimerspec to rtems_time_of_day */ 666 667 ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time ); 668 669 return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL); 670 671 switch ( return_v ) { 672 case RTEMS_SUCCESSFUL: 673 674 PRINT_MSG_S ("SUCCESS: timer_settime RTEMS_SUCCESSFUL"); 675 676 /* The timer has been started and is running */ 677 678 /* Actualizes the data of the structure and 679 * returns the old ones in "ovalue" */ 680 681 COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue ); 682 683 COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data ); 684 685 /* It indicates that the time is running */ 686 687 timer_struct[timer_pos].state = STATE_CREATE_RUN_C; 688 689 /* Stores the time in which the timer was started again */ 690 691 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, 692 &timer_struct[timer_pos].time ); 693 694 return 0; 695 696 break; 697 698 case RTEMS_INVALID_ID: 699 700 PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_ID"); 701 break; 702 703 case RTEMS_NOT_DEFINED: 704 705 PRINT_MSG_S ("ERROR: timer_settime RTEMS_NOT_DEFINED"); 706 break; 707 708 case RTEMS_INVALID_CLOCK: 709 710 PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_CLOCK"); 711 break; 712 713 default: 714 715 716 } 717 718 break; 719 720 case TIMER_RELATIVE_C: 721 722 /* The fire time is relative: 723 * It has to use "rtems_time_fire_after" */ 724 725 /* First, it converts from seconds and nanoseconds to ticks */ 726 727 /* The form in which this operation is done can produce a lost 728 * of precision of 1 second */ 729 730 /* This is the process to convert from nanoseconds to ticks 731 * 732 * There is a tick every 10 miliseconds, then the nanoseconds are 733 * divided between 10**7. The result of this operation will be the 734 * number of ticks 735 */ 736 737 timer_struct[timer_pos].ticks = 738 ( SEC_TO_TICKS_C * value->it_value.tv_sec ) + 739 ( value->it_value.tv_nsec / ( 1000 * 1000 * 10 ) ); 740 741 return_v = rtems_timer_fire_after ( timerid, 742 timer_struct[timer_pos].ticks, 743 FIRE_TIMER_S, 744 NULL ); 745 746 switch (return_v) { 747 case RTEMS_SUCCESSFUL: 748 749 PRINT_MSG_S ( "SUCCESS: timer_settime RTEMS_SUCCESSFUL"); 750 751 /* The timer has been started and is running */ 752 753 /* Actualizes the data of the structure and 754 * returns the old ones in "ovalue" */ 755 756 COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue ); 757 758 COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data ); 759 760 /* It indicates that the time is running */ 761 762 timer_struct[timer_pos].state = STATE_CREATE_RUN_C; 763 764 /* Stores the time in which the timer was started again */ 765 766 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, 767 &timer_struct[timer_pos].time ); 768 769 return 0; 770 771 break; 772 773 case RTEMS_INVALID_ID: 774 775 PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_ID"); 776 777 /* The timer identifier is not correct. In theory, this 778 * situation can not occur, but the solution is easy */ 779 780 errno = EINVAL; 781 782 return -1; 783 784 break; 785 786 case RTEMS_INVALID_NUMBER: 787 788 PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_NUMBER"); 789 790 /* In this case, RTEMS fails because the values of timing 791 * are incorrect */ 792 793 /* 794 * I do not know if errno must be actualized 795 * 796 * errno = EINVAL; 797 */ 798 799 return -1; 800 801 break; 802 803 default: 804 } 805 806 break; 807 808 default: 809 810 /* It does nothing, although it will be probably necessary to 811 * return an error */ 812 813 } 814 815 /* To avoid problems */ 816 817 return 0; 818 819 } 820 53 821 54 822 /* 55 823 * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 56 824 */ 825 826 /* ************** 827 * timer_gettime 828 * **************/ 57 829 58 830 int timer_gettime( … … 61 833 ) 62 834 { 63 return POSIX_NOT_IMPLEMENTED(); 835 836 /* 837 * IDEA: This function does not use functions of RTEMS to the handle 838 * of timers. It uses some functions for managing the time. 839 * 840 * A possible form to do this is the following: 841 * 842 * - When a timer is initialized, the value of the time in 843 * that moment is stored. 844 * - When this function is called, it returns the difference 845 * between the current time and the initialization time. 846 */ 847 848 rtems_time_of_day current_time; 849 rtems_status_code return_v; 850 int timer_pos; 851 unsigned32 hours; 852 unsigned32 minutes; 853 unsigned32 seconds; 854 unsigned32 ticks; 855 unsigned32 nanosec; 856 857 858 /* Reads the current time */ 859 860 return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, ¤t_time ); 861 862 timer_pos = TIMER_POSITION_F ( timerid ); 863 864 if ( timer_pos == BAD_TIMER_C ) { 865 866 /* The timer identifier is erroneus */ 867 868 errno = EINVAL; 869 870 return (-1); 871 872 } 873 874 /* Calculates the difference between the start time of the timer and 875 * the current one */ 876 877 hours = current_time.hour - timer_struct[timer_pos].time.hour; 878 879 if ( current_time.minute < timer_struct[timer_pos].time.minute ) { 880 minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute; 881 hours--; 882 } else { 883 minutes = current_time.minute - timer_struct[timer_pos].time.minute; 884 } 885 886 if ( current_time.second < timer_struct[timer_pos].time.second ) { 887 seconds = 60 - timer_struct[timer_pos].time.second + current_time.second; 888 minutes--; 889 } else { 890 seconds = current_time.second - timer_struct[timer_pos].time.second; 891 } 892 893 if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) { 894 ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks; 895 seconds--; 896 } else { 897 ticks = current_time.ticks - timer_struct[timer_pos].time.ticks; 898 } 899 900 /* The time that the timer is running is calculated */ 901 seconds = hours * 60 * 60 + 902 minutes * 60 + 903 seconds; 904 905 nanosec = ticks * 10 * /* msec */ 906 1000 * /* microsec */ 907 1000; /* nanosec */ 908 909 910 /* Calculates the time left before the timer finishes */ 911 912 value->it_value.tv_sec = 913 timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds; 914 915 value->it_value.tv_nsec = 916 timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec; 917 918 919 value->it_interval.tv_sec = 920 timer_struct[timer_pos].timer_data.it_interval.tv_sec; 921 value->it_interval.tv_nsec = 922 timer_struct[timer_pos].timer_data.it_interval.tv_nsec; 923 924 925 return 0; 926 64 927 } 65 928 … … 68 931 */ 69 932 933 /* ***************** 934 * timer_getoverrun 935 * *****************/ 936 70 937 int timer_getoverrun( 71 938 timer_t timerid 72 939 ) 73 940 { 74 return POSIX_NOT_IMPLEMENTED(); 75 } 941 942 /* 943 * IDEA: This function must count the times the timer expires. 944 * 945 * The expiration of a timer must increase by one a counter. 946 * After the signal handler associated to the timer finishs 947 * its execution, FIRE_TIMER_S will have to set this counter to 0. 948 */ 949 950 int timer_pos; /* Position of the timer in the structure */ 951 int overrun; /* Overflow count */ 952 953 954 timer_pos = TIMER_POSITION_F ( timerid ); 955 956 if ( timer_pos == BAD_TIMER_C ) { 957 /* The timer identifier is erroneus */ 958 959 errno = EINVAL; 960 961 return -1; 962 } 963 964 /* The overflow count of the timer is stored in "overrun" */ 965 966 overrun = timer_struct[timer_pos].overrun; 967 968 /* It is set to 0 */ 969 970 timer_struct[timer_pos].overrun = 0; 971 972 return overrun; 973 974 } -
cpukit/sapi/include/confdefs.h
rc30d04d7 r0747e2d 354 354 #endif 355 355 356 #ifndef CONFIGURE_MAXIMUM_POSIX_TIMERS 357 #define CONFIGURE_MAXIMUM_POSIX_TIMERS 0 358 #endif 359 356 360 #ifndef CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 357 361 #define CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS 0 … … 412 416 ((_keys) * \ 413 417 ( sizeof(POSIX_Keys_Control) + CONFIGURE_OBJECT_TABLE_STUFF ) ) 418 419 #define CONFIGURE_MEMORY_FOR_POSIX_TIMERS(_timers) \ 420 ((_timers) * \ 421 ( 0 ) ) 414 422 415 423 #define CONFIGURE_MEMORY_FOR_POSIX_QUEUED_SIGNALS(_queued_signals) \ … … 618 626 CONFIGURE_MAXIMUM_ADA_TASKS + CONFIGURE_MAXIMUM_FAKE_ADA_TASKS, 619 627 CONFIGURE_MAXIMUM_POSIX_KEYS + CONFIGURE_GNAT_KEYS, 628 CONFIGURE_MAXIMUM_POSIX_TIMERS, 620 629 CONFIGURE_MAXIMUM_POSIX_QUEUED_SIGNALS, 621 630 CONFIGURE_POSIX_INIT_THREAD_TABLE_SIZE, -
cpukit/sapi/src/posixapi.c
rc30d04d7 r0747e2d 37 37 #include <rtems/posix/psignal.h> 38 38 #include <rtems/posix/pthread.h> 39 #include <rtems/posix/ptimer.h> 39 40 #include <rtems/posix/time.h> 40 41 … … 51 52 0, /* maximum_condition_variables */ 52 53 0, /* maximum_keys */ 54 0, /* maximum_timers */ 53 55 0, /* maximum_queued_signals */ 54 56 0, /* number_of_initialization_threads */ … … 91 93 ); 92 94 95 _POSIX_Timer_Manager_initialization ( api_configuration->maximum_timers ); 93 96 } 94 97
Note: See TracChangeset
for help on using the changeset viewer.