summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-02 19:04:51 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-02 19:04:51 +0000
commit68003979629b255fe855c3fdac97c74e3fb059e7 (patch)
treef584f54908d3f382c943ead222ff2f1b2683a8d8 /c
parentSplit cancel.c into multiple files. (diff)
downloadrtems-68003979629b255fe855c3fdac97c74e3fb059e7.tar.bz2
*** empty log message ***
Diffstat (limited to 'c')
-rw-r--r--c/src/exec/posix/include/rtems/posix/timer.h32
-rw-r--r--c/src/exec/posix/src/Makefile.in8
-rw-r--r--c/src/exec/posix/src/ptimer.c927
-rw-r--r--c/src/exec/posix/src/ptimer1.c941
4 files changed, 985 insertions, 923 deletions
diff --git a/c/src/exec/posix/include/rtems/posix/timer.h b/c/src/exec/posix/include/rtems/posix/timer.h
new file mode 100644
index 0000000000..264a172d23
--- /dev/null
+++ b/c/src/exec/posix/include/rtems/posix/timer.h
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ */
+
+#ifndef __RTEMS_POSIX_TIMERS_h
+#define __RTEMS_POSIX_TIMERS_h
+
+/*
+ * Data for a timer
+ */
+
+typedef struct {
+ pthread_t thread_id; /* Thread identifier */
+ char state; /* State of the timer */
+ struct sigevent inf; /* Information associated to the timer */
+ timer_t timer_id; /* Created timer identifier */
+ struct itimerspec timer_data; /* Timing data of the timer */
+ unsigned32 ticks; /* Number of ticks of the initialization */
+ unsigned32 overrun; /* Number of expirations of the timer */
+ rtems_time_of_day time; /* Time in which the timer was started */
+} timer_alive_t;
+
+/*
+ * Array of Timers
+ */
+
+extern int timer_max;
+extern timer_alive_t *timer_struct;
+
+#endif
+/* end of include file */
+
diff --git a/c/src/exec/posix/src/Makefile.in b/c/src/exec/posix/src/Makefile.in
index 9948dc8e66..50cc10dd05 100644
--- a/c/src/exec/posix/src/Makefile.in
+++ b/c/src/exec/posix/src/Makefile.in
@@ -73,11 +73,15 @@ TIME_C_PIECES= time posixtimespecsubtract posixtimespectointerval \
posixintervaltotimespec clockgetcpuclockid clockgetenableattr \
clockgetres clockgettime clocksetenableattr clocksettime nanosleep
+# the timer manager needs to be split further but only after its
+# dependence on the Classic API Timer Manager is removed.
+TIMER_C_PIECES=ptimer ptimer1
+
C_PIECES = adasupp $(CANCEL_C_PIECES) $(CONDITION_VARIABLE_C_PIECES) \
getpid $(KEY_C_PIECES) $(MESSAGE_QUEUE_C_PIECES) \
$(MUTEX_C_PIECES) $(PTHREAD_C_PIECES) \
- $(PSIGNAL_C_PIECES) ptimer sched $(SEMAPHORE_C_PIECES) \
- $(TIME_C_PIECES) types unistd $(ENOSYS_C_PIECES) \
+ $(PSIGNAL_C_PIECES) sched $(SEMAPHORE_C_PIECES) \
+ $(TIME_C_PIECES) $(TIMER_C_PIECES) types unistd $(ENOSYS_C_PIECES) \
$(BUILD_FOR_NOW_C_PIECES)
C_FILES = $(C_PIECES:%=%.c)
diff --git a/c/src/exec/posix/src/ptimer.c b/c/src/exec/posix/src/ptimer.c
index 81d1d35e1d..72fd7939a2 100644
--- a/c/src/exec/posix/src/ptimer.c
+++ b/c/src/exec/posix/src/ptimer.c
@@ -32,144 +32,7 @@
/* End of necessary includes */
/*****************************/
-/* ************
- * Constants
- * ************/
-
-#define STATE_FREE_C 0x01 /* Free position of the table of timers */
-#define STATE_CREATE_NEW_C 0x02 /* Created timer but not running */
-#define STATE_CREATE_RUN_C 0x03 /* Created timer and running */
-#define STATE_CREATE_STOP_C 0x04 /* Created, ran and stopped timer */
-#define MAX_NSEC_C 1000000000 /* Maximum number of nsec allowed */
-#define MIN_NSEC_C 0 /* Minimum number of nsec allowew */
-#define TIMER_RELATIVE_C 0 /* Indicates that the fire time is
- * relative to the current one */
-#define SEC_TO_TICKS_C _TOD_Ticks_per_second /* Number of ticks in a second*/
-#define NSEC_PER_SEC_C 1000000000 /* Nanoseconds in a second */
-
-#define NO_MORE_TIMERS_C 11 /* There is not available timers */
-#define BAD_TIMER_C 11 /* The timer does not exist in the table */
-
-#define SECONDS_PER_YEAR_C ( 360 * 24 * 60 * 60 )
-#define SECONDS_PER_MONTH_C ( 30 * 24 * 60 * 60 )
-#define SECONDS_PER_DAY_C ( 24 * 60 * 60 )
-#define SECONDS_PER_HOUR_C ( 60 * 60 )
-#define SECONDS_PER_MINUTE_C ( 60 )
-
-/*
-#define DEBUG_MESSAGES
- */
-
-/* *********************************************************
- * Types that will store the created timers and their data
- * *********************************************************/
-
-/*
- * Data for a timer
- */
-
-typedef struct {
- pthread_t thread_id; /* Thread identifier */
- char state; /* State of the timer */
- struct sigevent inf; /* Information associated to the timer */
- timer_t timer_id; /* Created timer identifier */
- struct itimerspec timer_data; /* Timing data of the timer */
- unsigned32 ticks; /* Number of ticks of the initialization */
- unsigned32 overrun; /* Number of expirations of the timer */
- rtems_time_of_day time; /* Time in which the timer was started */
-} timer_alive_t;
-
-/*
- * Array of Timers
- */
-
-int timer_max;
-timer_alive_t *timer_struct;
-
-/*
- * Data for the signals
- */
-
-struct sigaction signal_inf[SIGRTMAX];
-
-/***********************************
- * Definition of Internal Functions
- ***********************************/
-
-/* ***************************************************************************
- * PRINT_MSG_S
- *
- * Description: This function write a message in the display.
- * It is used for debugging and all the calls must be deleted
- * when the tests finish
- * ***************************************************************************/
-
-static void PRINT_MSG_S ( char *msg )
-{
-
-#ifdef DEBUG_MESSAGES
- printf("%s\n", msg);
-#endif
-
-}
-
-/* ***************************************************************************
- * PRINT_ERRNO_S
- *
- * Description: Print the value of the global variable errno in the display
- * ***************************************************************************/
-
-static void PRINT_ERRNO_S ()
-{
-#ifdef DEBUG_MESSAGES
- switch (errno)
- {
- case EINVAL:
- PRINT_MSG_S ( "errno EINVAL"); break;
- case EPERM:
- PRINT_MSG_S ( "errno EPERM"); break;
- case ESRCH:
- PRINT_MSG_S ( "errno ESRCH"); break;
- case EAGAIN:
- PRINT_MSG_S ( "errno EAGAIN"); break;
- default :
- printf ("errno: %d\n", errno);
- break;
- }
-#endif
-}
-
-/* ***************************************************************************
- * TIMER_INITIALIZE_S
- *
- * Description: Initialize the data of a timer
- * ***************************************************************************/
-
-void TIMER_INITIALIZE_S ( int timer_pos )
-{
-
- /*
- * Indicates that the position in the table is free
- */
-
- timer_struct[timer_pos].state = STATE_FREE_C;
-
- /*
- * The initial data of timing are set with null value
- */
-
- timer_struct[timer_pos].timer_data.it_value.tv_sec = 0;
- timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0;
- timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0;
- timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
-
- /*
- * The count of expirations is 0
- */
-
- timer_struct[timer_pos].overrun = 0;
-
-}
+#include <rtems/posix/timer.h>
/* ***************************************************************************
* _POSIX_Timer_Manager_initialization
@@ -178,6 +41,11 @@ void TIMER_INITIALIZE_S ( int timer_pos )
* the timers are stored
* ***************************************************************************/
+extern void TIMER_INITIALIZE_S( int );
+int timer_max;
+timer_alive_t *timer_struct;
+
+
void _POSIX_Timer_Manager_initialization ( int max_timers )
{
int index;
@@ -197,786 +65,3 @@ void _POSIX_Timer_Manager_initialization ( int max_timers )
timer_max = max_timers;
}
-/* ***************************************************************************
- * FIRST_FREE_POSITION_F
- *
- * Description: Returns the first free position in the table of timers.
- * If there is not a free position, it returns NO_MORE_TIMERS_C
- * ***************************************************************************/
-
-int FIRST_FREE_POSITION_F ()
-{
- int index;
-
- for (index=0; index<timer_max; index++) {
- if ( timer_struct[index].state == STATE_FREE_C ) {
- return index;
- }
- }
-
- /* The function reaches this point only if all the position are occupied */
-
- return NO_MORE_TIMERS_C;
-}
-
-/* ***************************************************************************
- * TIMER_POSITION_F
- *
- * Description: Returns the position in the table of timers in which the
- * data of the timer are stored.
- * If the timer identifier does not exist, it returns
- * BAD_TIMER_C
- * ***************************************************************************/
-
-int TIMER_POSITION_F ( timer_t timer_id )
-{
- int index;
-
- for (index=0; index<timer_max; index++ ) {
-
- /* Looks for the position of the timer. The timer must exist and the
- * position can not be free */
- if ( ( timer_struct[index].timer_id == timer_id ) &&
- ( timer_struct[index].state != STATE_FREE_C ) ) {
- return index;
- }
- }
-
- /* If the function reaches this point is because the timer identifier
- * is not correct */
-
- return BAD_TIMER_C;
-
-}
-
-/* ***************************************************************************
- * COPY_ITIMERSPEC_S
- *
- * Description: Does a copy of a variable of type struct itimerspec
- * ***************************************************************************/
-
-void COPY_ITIMERSPEC_S ( const struct itimerspec *source,
- struct itimerspec *target )
-{
-
- target->it_value.tv_sec = source->it_value.tv_sec;
- target->it_value.tv_nsec = source->it_value.tv_nsec;
- target->it_interval.tv_sec = source->it_interval.tv_sec;
- target->it_interval.tv_nsec = source->it_interval.tv_nsec;
-
-}
-
-/* ***************************************************************************
- * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
- *
- * Description: This function converts the data of a structure itimerspec
- * into structure rtems_time_of_day
- * ***************************************************************************/
-
-void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
- ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time )
-{
- unsigned long int seconds;
-
- /* The leap years and the months with 28, 29 or 31 days have not been
- * considerated. It will be made in the future */
-
- seconds = itimer->it_value.tv_sec;
-
- rtems_time->year = seconds / SECONDS_PER_YEAR_C;
- seconds = seconds % SECONDS_PER_YEAR_C;
-
- rtems_time->month = seconds / SECONDS_PER_MONTH_C;
- seconds = seconds % SECONDS_PER_MONTH_C;
-
- rtems_time->day = seconds / SECONDS_PER_DAY_C;
- seconds = seconds % SECONDS_PER_DAY_C;
-
- rtems_time->hour = seconds / SECONDS_PER_HOUR_C;
- seconds = seconds % SECONDS_PER_HOUR_C;
-
- rtems_time->minute = seconds / SECONDS_PER_MINUTE_C;
- seconds = seconds % SECONDS_PER_MINUTE_C;
-
- rtems_time->second = seconds;
-
- rtems_time->ticks = ( itimer->it_value.tv_nsec * SEC_TO_TICKS_C ) /
- NSEC_PER_SEC_C;
-
-}
-
-
-/* ***************************************************************************
- * FIRE_TIMER_S
- *
- * Description: This is the operation that is ran when a timer expires
- * ***************************************************************************/
-
-
-rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data)
-{
- int timer_pos; /* Position in the table of the timer that
- * has expirated */
- rtems_status_code return_v; /* Return value of rtems_timer_fire_after */
- int sig_number; /* Number of the signal to send */
-
-
- /* The position of the table of timers that contains the data of the
- * expired timer will be stored in "timer_pos". In theory a timer can not
- * expire if it has not been created or has been deleted */
-
- PRINT_MSG_S ("FIRE_TIMER_S");
-
- timer_pos = TIMER_POSITION_F(timer);
-
- /* Increases the number of expiration of the timer in one unit. */
- timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1;
-
-
- if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec != 0 ) ||
- ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) {
-
- /* The timer must be reprogrammed */
-
- return_v = rtems_timer_fire_after ( timer,
- timer_struct[timer_pos].ticks,
- FIRE_TIMER_S,
- NULL );
-
- /* Stores the time when the timer was started again */
-
- return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD,
- &timer_struct[timer_pos].time );
-
- /* The state has not to be actualized, because nothing modifies it */
-
- timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
-
- } else {
- /* Indicates that the timer is stopped */
-
- timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
-
- }
-
- /*
- * The sending of the signal to the process running the handling function
- * specified for that signal is simulated
- */
-
- sig_number = timer_struct[timer_pos].inf.sigev_signo;
-
- if( pthread_kill ( timer_struct[timer_pos].thread_id ,
- timer_struct[timer_pos].inf.sigev_signo ) ) {
- PRINT_MSG_S ("ERROR_PTHREAD_KILL");
- } else {
- PRINT_MSG_S ("SUCCESS_PTHREAD_KILL");
- }
-
- /*
- * After the signal handler returns, the count of expirations of the
- * timer must be set to 0.
- */
-
- timer_struct[timer_pos].overrun = 0;
-
-}
-
-/* *********************************************************************
- * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
- * ********************************************************************/
-
-/* **************
- * timer_create
- * **************/
-
-int timer_create(
- clockid_t clock_id,
- struct sigevent *evp,
- timer_t *timerid
-)
-{
-
- rtems_status_code return_v; /* return value of the operation */
- rtems_id timer_id; /* created timer identifier */
- int timer_pos; /* Position in the table of timers */
-
- /*
- * The data of the structure evp are checked in order to verify if they
- * are coherent.
- */
-
- if (evp != NULL) {
- /* The structure has data */
-
- if ( ( evp->sigev_notify != SIGEV_NONE ) &&
- ( evp->sigev_notify != SIGEV_SIGNAL ) ) {
- /* The value of the field sigev_notify is not valid */
-
- return (-1);
-
- }
- }
-
- /*
- * A timer is created using the primitive rtems_timer_create
- */
-
- return_v = rtems_timer_create ( clock_id, &timer_id );
-
- switch (return_v) {
- case RTEMS_SUCCESSFUL :
-
- PRINT_MSG_S("SUCCESS: rtems create timer RTEMS_SUCCESSFUL");
-
- /*
- * The timer has been created properly
- */
-
- /* Obtains the first free position in the table of timers */
-
- timer_pos = FIRST_FREE_POSITION_F();
-
- if ( timer_pos == NO_MORE_TIMERS_C ) {
- /* There is not position for another timers in spite of RTEMS
- * supports it. It will necessaty to increase the structure used */
-
- errno = EAGAIN;
-
- return -1;
- }
-
- /* Exit parameter */
-
- *timerid = timer_id;
-
- /* The data of the created timer are stored to use them later */
-
- timer_struct[timer_pos].state = STATE_CREATE_NEW_C;
-
- /* NEW VERSION*/
- timer_struct[timer_pos].thread_id = pthread_self ();
-
-
- if ( evp != NULL ) {
-
- timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify;
- timer_struct[timer_pos].inf.sigev_signo = evp->sigev_signo;
- timer_struct[timer_pos].inf.sigev_value = evp->sigev_value;
-
- }
-
-
- timer_struct[timer_pos].timer_id = timer_id;
-
- timer_struct[timer_pos].overrun = 0;
-
- timer_struct[timer_pos].timer_data.it_value.tv_sec = 0;
- timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0;
- timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0;
- timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
-
- return 0;
-
-
- case RTEMS_INVALID_NAME : /* The assigned name is not valid*/
-
- PRINT_MSG_S ("ERROR: rtems create timer RTEMS_INVALID_NAME");
-
- errno = EINVAL;
-
- return (-1);
-
-
- case RTEMS_TOO_MANY :
-
- PRINT_MSG_S ("ERROR: rtems create timer RTEMS_TOO_MANY ");
-
- /* There has been created too much timers for the same process */
-
- errno = EAGAIN;
-
- return (-1);
-
- default :
-
- /*
- * Does nothing. It only returns the error without assigning a value
- * to errno. In theory, it can not happen because the call to
- * rtems_timer_create can not return other different value.
- */
-
- return (-1);
-
- }
-
- /*
- * The next sentence is used to avoid singular situations
- */
-
- return (-1);
-
-}
-
-/*
- * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
- */
-
-int timer_delete(
- timer_t timerid
-)
-{
-
- /*
- * IDEA: This function must probably stop the timer first and then delete it
- *
- * It will have to do a call to rtems_timer_cancel and then another
- * call to rtems_timer_delete.
- * The call to rtems_timer_delete will be probably unnecessary,
- * because rtems_timer_delete stops the timer before deleting it.
- */
-
- int timer_pos;
- rtems_status_code status;
-
-
- /* First the position in the table of timers is obtained */
-
- timer_pos = TIMER_POSITION_F ( timerid );
-
- if ( timer_pos == BAD_TIMER_C ) {
- /* The timer identifier is erroneus */
-
- errno = EINVAL;
- return -1;
- }
-
- /* The timer is deleted */
-
- status = rtems_timer_delete ( timerid );
-
- if ( status == RTEMS_INVALID_ID ) {
- /* The timer identifier is erroneus */
-
- errno = EINVAL;
- return -1;
- }
-
- /* Initializes the data of the timer */
-
- TIMER_INITIALIZE_S ( timer_pos );
-
- return 0;
-}
-
-/*
- * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
- */
-
-/* **************
- * timer_settime
- * **************/
-
-
-int timer_settime(
- timer_t timerid,
- int flags,
- const struct itimerspec *value,
- struct itimerspec *ovalue
-)
-{
-
- rtems_status_code return_v; /* Return of the calls to RTEMS */
- int timer_pos; /* Position of the timer in the table */
- rtems_time_of_day rtems_time; /* Time in RTEMS */
-
-
- /* First the position in the table of timers is obtained */
-
- timer_pos = TIMER_POSITION_F ( timerid );
-
- if ( timer_pos == BAD_TIMER_C ) {
- /* The timer identifier is erroneus */
-
- errno = EINVAL;
- return -1;
- }
-
- if ( value == NULL ) {
- /* The stucture of times of the timer is free, and then returns an
- error but the variable errno is not actualized */
-
- /* errno = ?????? */
-
- return -1;
- }
-
- /* If the function reaches this point, then it will be necessary to do
- * something with the structure of times of the timer: to stop, start
- * or start it again */
-
- /* First, it verifies if the timer must be stopped */
-
- if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
- /* The timer is stopped */
-
- return_v = rtems_timer_cancel ( timerid );
-
- /* The old data of the timer are returned */
-
- if ( ovalue )
- COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue );
-
- /* The new data are set */
-
- COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data );
-
- /* Indicates that the timer is created and stopped */
-
- timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
-
- /* Returns with success */
-
- return 0;
- }
-
- /*
- * If the function reaches this point, then the timer will have to be
- * initialized with new values: to start it or start it again
- */
-
- /* First, it verifies if the structure "value" is correct */
-
- if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) ||
- ( value->it_value.tv_nsec < MIN_NSEC_C ) ) {
- /* The number of nanoseconds is not correct */
-
- errno = EINVAL;
-
- return -1;
- }
-
- /* Then, "value" must be converted from seconds and nanoseconds to clock
- * ticks, to use it in the calls to RTEMS */
-
- /* It is also necessary to take in account if the time is absolute
- * or relative */
-
- switch (flags) {
- case TIMER_ABSTIME:
-
- /* The fire time is absolute:
- * It has to use "rtems_time_fire_when" */
-
- /* First, it converts from struct itimerspec to rtems_time_of_day */
-
- ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time );
-
- return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL);
-
- switch ( return_v ) {
- case RTEMS_SUCCESSFUL:
-
- PRINT_MSG_S ("SUCCESS: timer_settime RTEMS_SUCCESSFUL");
-
- /* The timer has been started and is running */
-
- /* Actualizes the data of the structure and
- * returns the old ones in "ovalue" */
-
- if ( ovalue )
- COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue );
-
- COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data );
-
- /* It indicates that the time is running */
-
- timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
-
- /* Stores the time in which the timer was started again */
-
- return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD,
- &timer_struct[timer_pos].time );
-
- return 0;
-
- break;
-
- case RTEMS_INVALID_ID:
-
- PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_ID");
- break;
-
- case RTEMS_NOT_DEFINED:
-
- PRINT_MSG_S ("ERROR: timer_settime RTEMS_NOT_DEFINED");
- break;
-
- case RTEMS_INVALID_CLOCK:
-
- PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_CLOCK");
- break;
-
- default:
-
-
- }
-
- break;
-
- case TIMER_RELATIVE_C:
-
- /* The fire time is relative:
- * It has to use "rtems_time_fire_after" */
-
- /* First, it converts from seconds and nanoseconds to ticks */
-
- /* The form in which this operation is done can produce a lost
- * of precision of 1 second */
-
-/* This is the process to convert from nanoseconds to ticks
- *
- * There is a tick every 10 miliseconds, then the nanoseconds are
- * divided between 10**7. The result of this operation will be the
- * number of ticks
- */
-
- timer_struct[timer_pos].ticks =
- ( SEC_TO_TICKS_C * value->it_value.tv_sec ) +
- ( value->it_value.tv_nsec / ( 1000 * 1000 * 10 ) );
-
- return_v = rtems_timer_fire_after ( timerid,
- timer_struct[timer_pos].ticks,
- FIRE_TIMER_S,
- NULL );
-
- switch (return_v) {
- case RTEMS_SUCCESSFUL:
-
- PRINT_MSG_S ( "SUCCESS: timer_settime RTEMS_SUCCESSFUL");
-
- /* The timer has been started and is running */
-
- /* Actualizes the data of the structure and
- * returns the old ones in "ovalue" */
-
- if ( ovalue )
- COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue );
-
- COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data );
-
- /* It indicates that the time is running */
-
- timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
-
- /* Stores the time in which the timer was started again */
-
- return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD,
- &timer_struct[timer_pos].time );
-
- return 0;
-
- break;
-
- case RTEMS_INVALID_ID:
-
- PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_ID");
-
- /* The timer identifier is not correct. In theory, this
- * situation can not occur, but the solution is easy */
-
- errno = EINVAL;
-
- return -1;
-
- break;
-
- case RTEMS_INVALID_NUMBER:
-
- PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_NUMBER");
-
- /* In this case, RTEMS fails because the values of timing
- * are incorrect */
-
- /*
- * I do not know if errno must be actualized
- *
- * errno = EINVAL;
- */
-
- return -1;
-
- break;
-
- default:
- }
-
- break;
-
- default:
-
- /* It does nothing, although it will be probably necessary to
- * return an error */
-
- }
-
- /* To avoid problems */
-
- return 0;
-
-}
-
-
-/*
- * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
- */
-
-/* **************
- * timer_gettime
- * **************/
-
-int timer_gettime(
- timer_t timerid,
- struct itimerspec *value
-)
-{
-
- /*
- * IDEA: This function does not use functions of RTEMS to the handle
- * of timers. It uses some functions for managing the time.
- *
- * A possible form to do this is the following:
- *
- * - When a timer is initialized, the value of the time in
- * that moment is stored.
- * - When this function is called, it returns the difference
- * between the current time and the initialization time.
- */
-
- rtems_time_of_day current_time;
- rtems_status_code return_v;
- int timer_pos;
- unsigned32 hours;
- unsigned32 minutes;
- unsigned32 seconds;
- unsigned32 ticks;
- unsigned32 nanosec;
-
-
- /* Reads the current time */
-
- return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, &current_time );
-
- timer_pos = TIMER_POSITION_F ( timerid );
-
- if ( timer_pos == BAD_TIMER_C ) {
-
- /* The timer identifier is erroneus */
-
- errno = EINVAL;
-
- return (-1);
-
- }
-
- /* Calculates the difference between the start time of the timer and
- * the current one */
-
- hours = current_time.hour - timer_struct[timer_pos].time.hour;
-
- if ( current_time.minute < timer_struct[timer_pos].time.minute ) {
- minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute;
- hours--;
- } else {
- minutes = current_time.minute - timer_struct[timer_pos].time.minute;
- }
-
- if ( current_time.second < timer_struct[timer_pos].time.second ) {
- seconds = 60 - timer_struct[timer_pos].time.second + current_time.second;
- minutes--;
- } else {
- seconds = current_time.second - timer_struct[timer_pos].time.second;
- }
-
- if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) {
- ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks;
- seconds--;
- } else {
- ticks = current_time.ticks - timer_struct[timer_pos].time.ticks;
- }
-
- /* The time that the timer is running is calculated */
- seconds = hours * 60 * 60 +
- minutes * 60 +
- seconds;
-
- nanosec = ticks * 10 * /* msec */
- 1000 * /* microsec */
- 1000; /* nanosec */
-
-
- /* Calculates the time left before the timer finishes */
-
- value->it_value.tv_sec =
- timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds;
-
- value->it_value.tv_nsec =
- timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec;
-
-
- value->it_interval.tv_sec =
- timer_struct[timer_pos].timer_data.it_interval.tv_sec;
- value->it_interval.tv_nsec =
- timer_struct[timer_pos].timer_data.it_interval.tv_nsec;
-
-
- return 0;
-
-}
-
-/*
- * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
- */
-
-/* *****************
- * timer_getoverrun
- * *****************/
-
-int timer_getoverrun(
- timer_t timerid
-)
-{
-
- /*
- * IDEA: This function must count the times the timer expires.
- *
- * The expiration of a timer must increase by one a counter.
- * After the signal handler associated to the timer finishs
- * its execution, FIRE_TIMER_S will have to set this counter to 0.
- */
-
- int timer_pos; /* Position of the timer in the structure */
- int overrun; /* Overflow count */
-
-
- timer_pos = TIMER_POSITION_F ( timerid );
-
- if ( timer_pos == BAD_TIMER_C ) {
- /* The timer identifier is erroneus */
-
- errno = EINVAL;
-
- return -1;
- }
-
- /* The overflow count of the timer is stored in "overrun" */
-
- overrun = timer_struct[timer_pos].overrun;
-
- /* It is set to 0 */
-
- timer_struct[timer_pos].overrun = 0;
-
- return overrun;
-
-}
diff --git a/c/src/exec/posix/src/ptimer1.c b/c/src/exec/posix/src/ptimer1.c
new file mode 100644
index 0000000000..d42d3dc522
--- /dev/null
+++ b/c/src/exec/posix/src/ptimer1.c
@@ -0,0 +1,941 @@
+/*
+ * ptimer.c,v 1.1 1996/06/03 16:29:58 joel Exp
+ */
+
+#include <assert.h>
+#include <time.h>
+#include <errno.h>
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/thread.h>
+#include <rtems/score/tod.h>
+
+#include <rtems/posix/time.h>
+
+/************************************/
+/* These includes are now necessary */
+/************************************/
+
+#include <sys/features.h>
+#include <rtems/rtems/status.h>
+#include <rtems/rtems/types.h>
+#include <rtems/rtems/timer.h>
+#include <rtems/rtems/clock.h>
+#include <rtems/posix/psignal.h>
+#include <rtems/score/wkspace.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <signal.h>
+
+#include <rtems/posix/timer.h>
+
+/*****************************/
+/* End of necessary includes */
+/*****************************/
+
+/* ************
+ * Constants
+ * ************/
+
+#define STATE_FREE_C 0x01 /* Free position of the table of timers */
+#define STATE_CREATE_NEW_C 0x02 /* Created timer but not running */
+#define STATE_CREATE_RUN_C 0x03 /* Created timer and running */
+#define STATE_CREATE_STOP_C 0x04 /* Created, ran and stopped timer */
+#define MAX_NSEC_C 1000000000 /* Maximum number of nsec allowed */
+#define MIN_NSEC_C 0 /* Minimum number of nsec allowew */
+#define TIMER_RELATIVE_C 0 /* Indicates that the fire time is
+ * relative to the current one */
+#define SEC_TO_TICKS_C _TOD_Ticks_per_second /* Number of ticks in a second*/
+#define NSEC_PER_SEC_C 1000000000 /* Nanoseconds in a second */
+
+#define NO_MORE_TIMERS_C 11 /* There is not available timers */
+#define BAD_TIMER_C 11 /* The timer does not exist in the table */
+
+#define SECONDS_PER_YEAR_C ( 360 * 24 * 60 * 60 )
+#define SECONDS_PER_MONTH_C ( 30 * 24 * 60 * 60 )
+#define SECONDS_PER_DAY_C ( 24 * 60 * 60 )
+#define SECONDS_PER_HOUR_C ( 60 * 60 )
+#define SECONDS_PER_MINUTE_C ( 60 )
+
+/*
+#define DEBUG_MESSAGES
+ */
+
+/*
+ * Data for the signals
+ */
+
+struct sigaction signal_inf[SIGRTMAX];
+
+/***********************************
+ * Definition of Internal Functions
+ ***********************************/
+
+/* ***************************************************************************
+ * PRINT_MSG_S
+ *
+ * Description: This function write a message in the display.
+ * It is used for debugging and all the calls must be deleted
+ * when the tests finish
+ * ***************************************************************************/
+
+static void PRINT_MSG_S ( char *msg )
+{
+
+#ifdef DEBUG_MESSAGES
+ printf("%s\n", msg);
+#endif
+
+}
+
+/* ***************************************************************************
+ * PRINT_ERRNO_S
+ *
+ * Description: Print the value of the global variable errno in the display
+ * ***************************************************************************/
+
+static void PRINT_ERRNO_S ()
+{
+#ifdef DEBUG_MESSAGES
+ switch (errno)
+ {
+ case EINVAL:
+ PRINT_MSG_S ( "errno EINVAL"); break;
+ case EPERM:
+ PRINT_MSG_S ( "errno EPERM"); break;
+ case ESRCH:
+ PRINT_MSG_S ( "errno ESRCH"); break;
+ case EAGAIN:
+ PRINT_MSG_S ( "errno EAGAIN"); break;
+ default :
+ printf ("errno: %d\n", errno);
+ break;
+ }
+#endif
+}
+
+/* ***************************************************************************
+ * TIMER_INITIALIZE_S
+ *
+ * Description: Initialize the data of a timer
+ * ***************************************************************************/
+
+void TIMER_INITIALIZE_S ( int timer_pos )
+{
+
+ /*
+ * Indicates that the position in the table is free
+ */
+
+ timer_struct[timer_pos].state = STATE_FREE_C;
+
+ /*
+ * The initial data of timing are set with null value
+ */
+
+ timer_struct[timer_pos].timer_data.it_value.tv_sec = 0;
+ timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0;
+ timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0;
+ timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
+
+ /*
+ * The count of expirations is 0
+ */
+
+ timer_struct[timer_pos].overrun = 0;
+
+}
+
+/* ***************************************************************************
+ * _POSIX_Timer_Manager_initialization
+ *
+ * Description: Initialize the internal structure in which the data of all
+ * the timers are stored
+ * ***************************************************************************/
+
+/* split to reduce minimum size */
+
+/* ***************************************************************************
+ * FIRST_FREE_POSITION_F
+ *
+ * Description: Returns the first free position in the table of timers.
+ * If there is not a free position, it returns NO_MORE_TIMERS_C
+ * ***************************************************************************/
+
+int FIRST_FREE_POSITION_F ()
+{
+ int index;
+
+ for (index=0; index<timer_max; index++) {
+ if ( timer_struct[index].state == STATE_FREE_C ) {
+ return index;
+ }
+ }
+
+ /* The function reaches this point only if all the position are occupied */
+
+ return NO_MORE_TIMERS_C;
+}
+
+/* ***************************************************************************
+ * TIMER_POSITION_F
+ *
+ * Description: Returns the position in the table of timers in which the
+ * data of the timer are stored.
+ * If the timer identifier does not exist, it returns
+ * BAD_TIMER_C
+ * ***************************************************************************/
+
+int TIMER_POSITION_F ( timer_t timer_id )
+{
+ int index;
+
+ for (index=0; index<timer_max; index++ ) {
+
+ /* Looks for the position of the timer. The timer must exist and the
+ * position can not be free */
+ if ( ( timer_struct[index].timer_id == timer_id ) &&
+ ( timer_struct[index].state != STATE_FREE_C ) ) {
+ return index;
+ }
+ }
+
+ /* If the function reaches this point is because the timer identifier
+ * is not correct */
+
+ return BAD_TIMER_C;
+
+}
+
+/* ***************************************************************************
+ * COPY_ITIMERSPEC_S
+ *
+ * Description: Does a copy of a variable of type struct itimerspec
+ * ***************************************************************************/
+
+void COPY_ITIMERSPEC_S ( const struct itimerspec *source,
+ struct itimerspec *target )
+{
+
+ target->it_value.tv_sec = source->it_value.tv_sec;
+ target->it_value.tv_nsec = source->it_value.tv_nsec;
+ target->it_interval.tv_sec = source->it_interval.tv_sec;
+ target->it_interval.tv_nsec = source->it_interval.tv_nsec;
+
+}
+
+/* ***************************************************************************
+ * ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
+ *
+ * Description: This function converts the data of a structure itimerspec
+ * into structure rtems_time_of_day
+ * ***************************************************************************/
+
+void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S
+ ( const struct itimerspec *itimer, rtems_time_of_day *rtems_time )
+{
+ unsigned long int seconds;
+
+ /* The leap years and the months with 28, 29 or 31 days have not been
+ * considerated. It will be made in the future */
+
+ seconds = itimer->it_value.tv_sec;
+
+ rtems_time->year = seconds / SECONDS_PER_YEAR_C;
+ seconds = seconds % SECONDS_PER_YEAR_C;
+
+ rtems_time->month = seconds / SECONDS_PER_MONTH_C;
+ seconds = seconds % SECONDS_PER_MONTH_C;
+
+ rtems_time->day = seconds / SECONDS_PER_DAY_C;
+ seconds = seconds % SECONDS_PER_DAY_C;
+
+ rtems_time->hour = seconds / SECONDS_PER_HOUR_C;
+ seconds = seconds % SECONDS_PER_HOUR_C;
+
+ rtems_time->minute = seconds / SECONDS_PER_MINUTE_C;
+ seconds = seconds % SECONDS_PER_MINUTE_C;
+
+ rtems_time->second = seconds;
+
+ rtems_time->ticks = ( itimer->it_value.tv_nsec * SEC_TO_TICKS_C ) /
+ NSEC_PER_SEC_C;
+
+}
+
+
+/* ***************************************************************************
+ * FIRE_TIMER_S
+ *
+ * Description: This is the operation that is ran when a timer expires
+ * ***************************************************************************/
+
+
+rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data)
+{
+ int timer_pos; /* Position in the table of the timer that
+ * has expirated */
+ rtems_status_code return_v; /* Return value of rtems_timer_fire_after */
+ int sig_number; /* Number of the signal to send */
+
+
+ /* The position of the table of timers that contains the data of the
+ * expired timer will be stored in "timer_pos". In theory a timer can not
+ * expire if it has not been created or has been deleted */
+
+ PRINT_MSG_S ("FIRE_TIMER_S");
+
+ timer_pos = TIMER_POSITION_F(timer);
+
+ /* Increases the number of expiration of the timer in one unit. */
+ timer_struct[timer_pos].overrun = timer_struct[timer_pos].overrun + 1;
+
+
+ if ( ( timer_struct[timer_pos].timer_data.it_interval.tv_sec != 0 ) ||
+ ( timer_struct[timer_pos].timer_data.it_interval.tv_nsec != 0 ) ) {
+
+ /* The timer must be reprogrammed */
+
+ return_v = rtems_timer_fire_after ( timer,
+ timer_struct[timer_pos].ticks,
+ FIRE_TIMER_S,
+ NULL );
+
+ /* Stores the time when the timer was started again */
+
+ return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD,
+ &timer_struct[timer_pos].time );
+
+ /* The state has not to be actualized, because nothing modifies it */
+
+ timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
+
+ } else {
+ /* Indicates that the timer is stopped */
+
+ timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
+
+ }
+
+ /*
+ * The sending of the signal to the process running the handling function
+ * specified for that signal is simulated
+ */
+
+ sig_number = timer_struct[timer_pos].inf.sigev_signo;
+
+ if( pthread_kill ( timer_struct[timer_pos].thread_id ,
+ timer_struct[timer_pos].inf.sigev_signo ) ) {
+ PRINT_MSG_S ("ERROR_PTHREAD_KILL");
+ } else {
+ PRINT_MSG_S ("SUCCESS_PTHREAD_KILL");
+ }
+
+ /*
+ * After the signal handler returns, the count of expirations of the
+ * timer must be set to 0.
+ */
+
+ timer_struct[timer_pos].overrun = 0;
+
+}
+
+/* *********************************************************************
+ * 14.2.2 Create a Per-Process Timer, P1003.1b-1993, p. 264
+ * ********************************************************************/
+
+/* **************
+ * timer_create
+ * **************/
+
+int timer_create(
+ clockid_t clock_id,
+ struct sigevent *evp,
+ timer_t *timerid
+)
+{
+
+ rtems_status_code return_v; /* return value of the operation */
+ rtems_id timer_id; /* created timer identifier */
+ int timer_pos; /* Position in the table of timers */
+
+ /*
+ * The data of the structure evp are checked in order to verify if they
+ * are coherent.
+ */
+
+ if (evp != NULL) {
+ /* The structure has data */
+
+ if ( ( evp->sigev_notify != SIGEV_NONE ) &&
+ ( evp->sigev_notify != SIGEV_SIGNAL ) ) {
+ /* The value of the field sigev_notify is not valid */
+
+ return (-1);
+
+ }
+ }
+
+ /*
+ * A timer is created using the primitive rtems_timer_create
+ */
+
+ return_v = rtems_timer_create ( clock_id, &timer_id );
+
+ switch (return_v) {
+ case RTEMS_SUCCESSFUL :
+
+ PRINT_MSG_S("SUCCESS: rtems create timer RTEMS_SUCCESSFUL");
+
+ /*
+ * The timer has been created properly
+ */
+
+ /* Obtains the first free position in the table of timers */
+
+ timer_pos = FIRST_FREE_POSITION_F();
+
+ if ( timer_pos == NO_MORE_TIMERS_C ) {
+ /* There is not position for another timers in spite of RTEMS
+ * supports it. It will necessaty to increase the structure used */
+
+ errno = EAGAIN;
+
+ return -1;
+ }
+
+ /* Exit parameter */
+
+ *timerid = timer_id;
+
+ /* The data of the created timer are stored to use them later */
+
+ timer_struct[timer_pos].state = STATE_CREATE_NEW_C;
+
+ /* NEW VERSION*/
+ timer_struct[timer_pos].thread_id = pthread_self ();
+
+
+ if ( evp != NULL ) {
+
+ timer_struct[timer_pos].inf.sigev_notify = evp->sigev_notify;
+ timer_struct[timer_pos].inf.sigev_signo = evp->sigev_signo;
+ timer_struct[timer_pos].inf.sigev_value = evp->sigev_value;
+
+ }
+
+
+ timer_struct[timer_pos].timer_id = timer_id;
+
+ timer_struct[timer_pos].overrun = 0;
+
+ timer_struct[timer_pos].timer_data.it_value.tv_sec = 0;
+ timer_struct[timer_pos].timer_data.it_value.tv_nsec = 0;
+ timer_struct[timer_pos].timer_data.it_interval.tv_sec = 0;
+ timer_struct[timer_pos].timer_data.it_interval.tv_nsec = 0;
+
+ return 0;
+
+
+ case RTEMS_INVALID_NAME : /* The assigned name is not valid*/
+
+ PRINT_MSG_S ("ERROR: rtems create timer RTEMS_INVALID_NAME");
+
+ errno = EINVAL;
+
+ return (-1);
+
+
+ case RTEMS_TOO_MANY :
+
+ PRINT_MSG_S ("ERROR: rtems create timer RTEMS_TOO_MANY ");
+
+ /* There has been created too much timers for the same process */
+
+ errno = EAGAIN;
+
+ return (-1);
+
+ default :
+
+ /*
+ * Does nothing. It only returns the error without assigning a value
+ * to errno. In theory, it can not happen because the call to
+ * rtems_timer_create can not return other different value.
+ */
+
+ return (-1);
+
+ }
+
+ /*
+ * The next sentence is used to avoid singular situations
+ */
+
+ return (-1);
+
+}
+
+/*
+ * 14.2.3 Delete a Per_process Timer, P1003.1b-1993, p. 266
+ */
+
+int timer_delete(
+ timer_t timerid
+)
+{
+
+ /*
+ * IDEA: This function must probably stop the timer first and then delete it
+ *
+ * It will have to do a call to rtems_timer_cancel and then another
+ * call to rtems_timer_delete.
+ * The call to rtems_timer_delete will be probably unnecessary,
+ * because rtems_timer_delete stops the timer before deleting it.
+ */
+
+ int timer_pos;
+ rtems_status_code status;
+
+
+ /* First the position in the table of timers is obtained */
+
+ timer_pos = TIMER_POSITION_F ( timerid );
+
+ if ( timer_pos == BAD_TIMER_C ) {
+ /* The timer identifier is erroneus */
+
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* The timer is deleted */
+
+ status = rtems_timer_delete ( timerid );
+
+ if ( status == RTEMS_INVALID_ID ) {
+ /* The timer identifier is erroneus */
+
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Initializes the data of the timer */
+
+ TIMER_INITIALIZE_S ( timer_pos );
+
+ return 0;
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+/* **************
+ * timer_settime
+ * **************/
+
+
+int timer_settime(
+ timer_t timerid,
+ int flags,
+ const struct itimerspec *value,
+ struct itimerspec *ovalue
+)
+{
+
+ rtems_status_code return_v; /* Return of the calls to RTEMS */
+ int timer_pos; /* Position of the timer in the table */
+ rtems_time_of_day rtems_time; /* Time in RTEMS */
+
+
+ /* First the position in the table of timers is obtained */
+
+ timer_pos = TIMER_POSITION_F ( timerid );
+
+ if ( timer_pos == BAD_TIMER_C ) {
+ /* The timer identifier is erroneus */
+
+ errno = EINVAL;
+ return -1;
+ }
+
+ if ( value == NULL ) {
+ /* The stucture of times of the timer is free, and then returns an
+ error but the variable errno is not actualized */
+
+ /* errno = ?????? */
+
+ return -1;
+ }
+
+ /* If the function reaches this point, then it will be necessary to do
+ * something with the structure of times of the timer: to stop, start
+ * or start it again */
+
+ /* First, it verifies if the timer must be stopped */
+
+ if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) {
+ /* The timer is stopped */
+
+ return_v = rtems_timer_cancel ( timerid );
+
+ /* The old data of the timer are returned */
+
+ if ( ovalue )
+ COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue );
+
+ /* The new data are set */
+
+ COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data );
+
+ /* Indicates that the timer is created and stopped */
+
+ timer_struct[timer_pos].state = STATE_CREATE_STOP_C;
+
+ /* Returns with success */
+
+ return 0;
+ }
+
+ /*
+ * If the function reaches this point, then the timer will have to be
+ * initialized with new values: to start it or start it again
+ */
+
+ /* First, it verifies if the structure "value" is correct */
+
+ if ( ( value->it_value.tv_nsec > MAX_NSEC_C ) ||
+ ( value->it_value.tv_nsec < MIN_NSEC_C ) ) {
+ /* The number of nanoseconds is not correct */
+
+ errno = EINVAL;
+
+ return -1;
+ }
+
+ /* Then, "value" must be converted from seconds and nanoseconds to clock
+ * ticks, to use it in the calls to RTEMS */
+
+ /* It is also necessary to take in account if the time is absolute
+ * or relative */
+
+ switch (flags) {
+ case TIMER_ABSTIME:
+
+ /* The fire time is absolute:
+ * It has to use "rtems_time_fire_when" */
+
+ /* First, it converts from struct itimerspec to rtems_time_of_day */
+
+ ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S ( value, &rtems_time );
+
+ return_v = rtems_timer_fire_when ( timerid, &rtems_time, FIRE_TIMER_S, NULL);
+
+ switch ( return_v ) {
+ case RTEMS_SUCCESSFUL:
+
+ PRINT_MSG_S ("SUCCESS: timer_settime RTEMS_SUCCESSFUL");
+
+ /* The timer has been started and is running */
+
+ /* Actualizes the data of the structure and
+ * returns the old ones in "ovalue" */
+
+ if ( ovalue )
+ COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue );
+
+ COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data );
+
+ /* It indicates that the time is running */
+
+ timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
+
+ /* Stores the time in which the timer was started again */
+
+ return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD,
+ &timer_struct[timer_pos].time );
+
+ return 0;
+
+ break;
+
+ case RTEMS_INVALID_ID:
+
+ PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_ID");
+ break;
+
+ case RTEMS_NOT_DEFINED:
+
+ PRINT_MSG_S ("ERROR: timer_settime RTEMS_NOT_DEFINED");
+ break;
+
+ case RTEMS_INVALID_CLOCK:
+
+ PRINT_MSG_S ("ERROR: timer_settime RTEMS_INVALID_CLOCK");
+ break;
+
+ default:
+
+
+ }
+
+ break;
+
+ case TIMER_RELATIVE_C:
+
+ /* The fire time is relative:
+ * It has to use "rtems_time_fire_after" */
+
+ /* First, it converts from seconds and nanoseconds to ticks */
+
+ /* The form in which this operation is done can produce a lost
+ * of precision of 1 second */
+
+/* This is the process to convert from nanoseconds to ticks
+ *
+ * There is a tick every 10 miliseconds, then the nanoseconds are
+ * divided between 10**7. The result of this operation will be the
+ * number of ticks
+ */
+
+ timer_struct[timer_pos].ticks =
+ ( SEC_TO_TICKS_C * value->it_value.tv_sec ) +
+ ( value->it_value.tv_nsec / ( 1000 * 1000 * 10 ) );
+
+ return_v = rtems_timer_fire_after ( timerid,
+ timer_struct[timer_pos].ticks,
+ FIRE_TIMER_S,
+ NULL );
+
+ switch (return_v) {
+ case RTEMS_SUCCESSFUL:
+
+ PRINT_MSG_S ( "SUCCESS: timer_settime RTEMS_SUCCESSFUL");
+
+ /* The timer has been started and is running */
+
+ /* Actualizes the data of the structure and
+ * returns the old ones in "ovalue" */
+
+ if ( ovalue )
+ COPY_ITIMERSPEC_S ( &timer_struct[timer_pos].timer_data, ovalue );
+
+ COPY_ITIMERSPEC_S ( value, &timer_struct[timer_pos].timer_data );
+
+ /* It indicates that the time is running */
+
+ timer_struct[timer_pos].state = STATE_CREATE_RUN_C;
+
+ /* Stores the time in which the timer was started again */
+
+ return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD,
+ &timer_struct[timer_pos].time );
+
+ return 0;
+
+ break;
+
+ case RTEMS_INVALID_ID:
+
+ PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_ID");
+
+ /* The timer identifier is not correct. In theory, this
+ * situation can not occur, but the solution is easy */
+
+ errno = EINVAL;
+
+ return -1;
+
+ break;
+
+ case RTEMS_INVALID_NUMBER:
+
+ PRINT_MSG_S ( "ERROR: timer_settime RTEMS_INVALID_NUMBER");
+
+ /* In this case, RTEMS fails because the values of timing
+ * are incorrect */
+
+ /*
+ * I do not know if errno must be actualized
+ *
+ * errno = EINVAL;
+ */
+
+ return -1;
+
+ break;
+
+ default:
+ }
+
+ break;
+
+ default:
+
+ /* It does nothing, although it will be probably necessary to
+ * return an error */
+
+ }
+
+ /* To avoid problems */
+
+ return 0;
+
+}
+
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+/* **************
+ * timer_gettime
+ * **************/
+
+int timer_gettime(
+ timer_t timerid,
+ struct itimerspec *value
+)
+{
+
+ /*
+ * IDEA: This function does not use functions of RTEMS to the handle
+ * of timers. It uses some functions for managing the time.
+ *
+ * A possible form to do this is the following:
+ *
+ * - When a timer is initialized, the value of the time in
+ * that moment is stored.
+ * - When this function is called, it returns the difference
+ * between the current time and the initialization time.
+ */
+
+ rtems_time_of_day current_time;
+ rtems_status_code return_v;
+ int timer_pos;
+ unsigned32 hours;
+ unsigned32 minutes;
+ unsigned32 seconds;
+ unsigned32 ticks;
+ unsigned32 nanosec;
+
+
+ /* Reads the current time */
+
+ return_v = rtems_clock_get ( RTEMS_CLOCK_GET_TOD, &current_time );
+
+ timer_pos = TIMER_POSITION_F ( timerid );
+
+ if ( timer_pos == BAD_TIMER_C ) {
+
+ /* The timer identifier is erroneus */
+
+ errno = EINVAL;
+
+ return (-1);
+
+ }
+
+ /* Calculates the difference between the start time of the timer and
+ * the current one */
+
+ hours = current_time.hour - timer_struct[timer_pos].time.hour;
+
+ if ( current_time.minute < timer_struct[timer_pos].time.minute ) {
+ minutes = 60 - timer_struct[timer_pos].time.minute + current_time.minute;
+ hours--;
+ } else {
+ minutes = current_time.minute - timer_struct[timer_pos].time.minute;
+ }
+
+ if ( current_time.second < timer_struct[timer_pos].time.second ) {
+ seconds = 60 - timer_struct[timer_pos].time.second + current_time.second;
+ minutes--;
+ } else {
+ seconds = current_time.second - timer_struct[timer_pos].time.second;
+ }
+
+ if ( current_time.ticks < timer_struct[timer_pos].time.ticks ) {
+ ticks = 100 - timer_struct[timer_pos].time.ticks + current_time.ticks;
+ seconds--;
+ } else {
+ ticks = current_time.ticks - timer_struct[timer_pos].time.ticks;
+ }
+
+ /* The time that the timer is running is calculated */
+ seconds = hours * 60 * 60 +
+ minutes * 60 +
+ seconds;
+
+ nanosec = ticks * 10 * /* msec */
+ 1000 * /* microsec */
+ 1000; /* nanosec */
+
+
+ /* Calculates the time left before the timer finishes */
+
+ value->it_value.tv_sec =
+ timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds;
+
+ value->it_value.tv_nsec =
+ timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec;
+
+
+ value->it_interval.tv_sec =
+ timer_struct[timer_pos].timer_data.it_interval.tv_sec;
+ value->it_interval.tv_nsec =
+ timer_struct[timer_pos].timer_data.it_interval.tv_nsec;
+
+
+ return 0;
+
+}
+
+/*
+ * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267
+ */
+
+/* *****************
+ * timer_getoverrun
+ * *****************/
+
+int timer_getoverrun(
+ timer_t timerid
+)
+{
+
+ /*
+ * IDEA: This function must count the times the timer expires.
+ *
+ * The expiration of a timer must increase by one a counter.
+ * After the signal handler associated to the timer finishs
+ * its execution, FIRE_TIMER_S will have to set this counter to 0.
+ */
+
+ int timer_pos; /* Position of the timer in the structure */
+ int overrun; /* Overflow count */
+
+
+ timer_pos = TIMER_POSITION_F ( timerid );
+
+ if ( timer_pos == BAD_TIMER_C ) {
+ /* The timer identifier is erroneus */
+
+ errno = EINVAL;
+
+ return -1;
+ }
+
+ /* The overflow count of the timer is stored in "overrun" */
+
+ overrun = timer_struct[timer_pos].overrun;
+
+ /* It is set to 0 */
+
+ timer_struct[timer_pos].overrun = 0;
+
+ return overrun;
+
+}