diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2006-06-08 20:47:48 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2006-06-08 20:47:48 +0000 |
commit | 0243b0d8d396191662c6da16e0e38dbb845652ce (patch) | |
tree | 6d37c2a4167d65eea38c0986df39439ef2bb3479 | |
parent | B.Robinson MIPS patch (diff) | |
download | rtems-0243b0d8d396191662c6da16e0e38dbb845652ce.tar.bz2 |
2006-06-08 Joel Sherrill <joel@OARcorp.com>
* posix/Makefile.am, posix/preinstall.am,
posix/include/rtems/posix/timer.h, posix/src/ptimer.c,
posix/src/ptimer1.c, sapi/src/posixapi.c,
score/include/rtems/score/object.h:
Diffstat (limited to '')
-rw-r--r-- | cpukit/ChangeLog | 7 | ||||
-rw-r--r-- | cpukit/posix/Makefile.am | 6 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/timer.h | 25 | ||||
-rw-r--r-- | cpukit/posix/preinstall.am | 4 | ||||
-rw-r--r-- | cpukit/posix/src/ptimer.c | 76 | ||||
-rw-r--r-- | cpukit/posix/src/ptimer1.c | 863 | ||||
-rw-r--r-- | cpukit/sapi/src/posixapi.c | 2 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/object.h | 5 |
8 files changed, 360 insertions, 628 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 64dfe75b61..5a7817abfa 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,10 @@ +2006-06-08 Joel Sherrill <joel@OARcorp.com> + + * posix/Makefile.am, posix/preinstall.am, + posix/include/rtems/posix/timer.h, posix/src/ptimer.c, + posix/src/ptimer1.c, sapi/src/posixapi.c, + score/include/rtems/score/object.h: + 2006-06-02 Joel Sherrill <joel@OARcorp.com> * itron/src/trcv_mbf.c, posix/src/semopen.c, diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am index aee56f641e..46ba563029 100644 --- a/cpukit/posix/Makefile.am +++ b/cpukit/posix/Makefile.am @@ -23,9 +23,9 @@ include_rtems_posix_HEADERS = include/rtems/posix/cancel.h \ include/rtems/posix/key.h include/rtems/posix/mqueue.h \ include/rtems/posix/mutex.h include/rtems/posix/posixapi.h \ include/rtems/posix/priority.h include/rtems/posix/psignal.h \ - include/rtems/posix/pthread.h include/rtems/posix/ptimer.h \ - include/rtems/posix/semaphore.h include/rtems/posix/threadsup.h \ - include/rtems/posix/time.h include/rtems/posix/timer.h + include/rtems/posix/pthread.h include/rtems/posix/semaphore.h \ + include/rtems/posix/threadsup.h include/rtems/posix/time.h \ + include/rtems/posix/timer.h if HAS_MP include_rtems_posix_HEADERS += include/rtems/posix/condmp.h \ diff --git a/cpukit/posix/include/rtems/posix/timer.h b/cpukit/posix/include/rtems/posix/timer.h index fe23831045..20c80f273d 100644 --- a/cpukit/posix/include/rtems/posix/timer.h +++ b/cpukit/posix/include/rtems/posix/timer.h @@ -9,9 +9,10 @@ #ifndef _RTEMS_POSIX_TIMER_H #define _RTEMS_POSIX_TIMER_H -/* ************ +#include <rtems/posix/config.h> +/* * Constants - * ************/ + */ #define STATE_FREE_C 0x01 /* Free position of the table of timers */ #define STATE_CREATE_NEW_C 0x02 /* Created timer but not running */ @@ -26,9 +27,6 @@ /* Nanoseconds in a second */ #define NSEC_PER_SEC_C (uint32_t )1000000000 -#define NO_MORE_TIMERS_C -1 /* There is not available timers */ -#define BAD_TIMER_C -2 /* The timer does not exist in the table */ - #define SECONDS_PER_YEAR_C (uint32_t )(360 * 24) * (uint32_t )(60 * 60) #define SECONDS_PER_MONTH_C (uint32_t )( 30 * 24) * (uint32_t )(60 * 60) #define SECONDS_PER_DAY_C (uint32_t )( 24 * 60) * (uint32_t )(60) @@ -42,31 +40,32 @@ typedef struct { Objects_Control Object; - Watchdog_Control Ticker; - + Watchdog_Control Timer; /* Internal Timer */ 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 */ uint32_t ticks; /* Number of ticks of the initialization */ uint32_t overrun; /* Number of expirations of the timer */ - rtems_time_of_day time; /* Time in which the timer was started */ + TOD_Control time; /* Time in which the timer was started */ } POSIX_Timer_Control; /* - * Array of Timers + * _POSIX_Timers_Manager_initialization + * + * DESCRIPTION: + * + * This routine performs the initialization necessary for this manager. */ -extern int timer_max; -extern POSIX_Timer_Control *timer_struct; +void _POSIX_Timer_Manager_initialization ( int max_timers ); /* * The following defines the information control block used to manage * this class of objects. */ -RTEMS_EXTERN Objects_Information _POSIX_Timer_Information; +POSIX_EXTERN Objects_Information _POSIX_Timer_Information; #ifndef __RTEMS_APPLICATION__ #include <rtems/posix/timer.inl> diff --git a/cpukit/posix/preinstall.am b/cpukit/posix/preinstall.am index f2a1b8f08d..b636f38a3f 100644 --- a/cpukit/posix/preinstall.am +++ b/cpukit/posix/preinstall.am @@ -84,10 +84,6 @@ $(PROJECT_INCLUDE)/rtems/posix/pthread.h: include/rtems/posix/pthread.h $(PROJEC $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/pthread.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/pthread.h -$(PROJECT_INCLUDE)/rtems/posix/ptimer.h: include/rtems/posix/ptimer.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) - $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/ptimer.h -PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/ptimer.h - $(PROJECT_INCLUDE)/rtems/posix/semaphore.h: include/rtems/posix/semaphore.h $(PROJECT_INCLUDE)/rtems/posix/$(dirstamp) $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/posix/semaphore.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/posix/semaphore.h diff --git a/cpukit/posix/src/ptimer.c b/cpukit/posix/src/ptimer.c index 3bbf830356..2d0316484e 100644 --- a/cpukit/posix/src/ptimer.c +++ b/cpukit/posix/src/ptimer.c @@ -32,70 +32,30 @@ #include <stdio.h> #include <signal.h> -/*****************************/ -/* End of necessary includes */ -/*****************************/ - #include <rtems/posix/timer.h> -/* *************************************************************************** - * 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 - * ***************************************************************************/ - -int timer_max; -POSIX_Timer_Control *timer_struct; - + */ -void _POSIX_Timer_Manager_initialization ( int max_timers ) +void _POSIX_Timer_Manager_initialization ( int maximum_timers ) { - int index; - - timer_struct = _Workspace_Allocate_or_fatal_error( - max_timers * sizeof(POSIX_Timer_Control) ); - - /* - * Initialize all the timers - */ - - timer_max = max_timers; - - for (index=0; index<max_timers; index++) - TIMER_INITIALIZE_S( index ); - - timer_max = max_timers; + _Objects_Initialize_information( + &_POSIX_Timer_Information, /* object information table */ + OBJECTS_POSIX_API, /* object API */ + OBJECTS_POSIX_TIMERS, /* object class */ + maximum_timers, /* maximum objects of this class */ + sizeof( POSIX_Timer_Control ), + /* size of this object's control block */ + FALSE, /* TRUE if names for this object are strings */ + _POSIX_PATH_MAX /* maximum length of each object's name */ +#if defined(RTEMS_MULTIPROCESSING) + , + FALSE, /* TRUE if this is a global object class */ + NULL /* Proxy extraction support callout */ +#endif + ); } diff --git a/cpukit/posix/src/ptimer1.c b/cpukit/posix/src/ptimer1.c index efecce0cf7..87a17f22d2 100644 --- a/cpukit/posix/src/ptimer1.c +++ b/cpukit/posix/src/ptimer1.c @@ -27,7 +27,6 @@ #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> @@ -35,126 +34,56 @@ #include <rtems/seterr.h> #include <rtems/posix/timer.h> -/*****************************/ -/* End of necessary includes */ -/*****************************/ - -/* ************ - * Constants - * ************/ - -/* -#define DEBUG_MESSAGES - */ - -/* - * Data for the signals - */ - -/*********************************** - * Definition of Internal Functions - ***********************************/ - -/* *************************************************************************** - * TIMER_INITIALIZE_S - * - * Description: Initialize the data of a timer - * ***************************************************************************/ - -extern void TIMER_INITIALIZE_S ( int timer_pos ); - -/* *************************************************************************** - * _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 ) +boolean _Watchdog_Insert_ticks_helper( + Watchdog_Control *timer, + Watchdog_Interval ticks, + Objects_Id id, + Watchdog_Service_routine_entry TSR, + void *arg +) { - 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; + ISR_Level level; + + (void) _Watchdog_Remove( timer ); + _ISR_Disable( level ); + + /* + * Check to see if the watchdog has just been inserted by a + * higher priority interrupt. If so, abandon this insert. + */ + if ( timer->state != WATCHDOG_INACTIVE ) { + _ISR_Enable( level ); + return FALSE; + } + /* + * OK. Now we now the timer was not rescheduled by an interrupt + * so we can atomically initialize it as in use. + */ + _Watchdog_Initialize( timer, TSR, id, arg ); + _Watchdog_Insert_ticks( timer, ticks ); + _ISR_Enable( level ); + return TRUE; } -/* *************************************************************************** - * 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; +/* #define DEBUG_MESSAGES */ -} - -/* *************************************************************************** +/* * 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 ) +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 */ + * considered. It will be made in the future */ seconds = itimer->it_value.tv_sec; @@ -182,53 +111,46 @@ void ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S /* *************************************************************************** - * FIRE_TIMER_S + * _POSIX_Timer_TSR * * Description: This is the operation that is ran when a timer expires * ***************************************************************************/ -rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data) +void _POSIX_Timer_TSR(Objects_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 */ - - 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 */ - - timer_struct[timer_pos].time = _TOD_Current; - - /* The state has not to be actualized, because nothing modifies it */ - - timer_struct[timer_pos].state = STATE_CREATE_RUN_C; - + POSIX_Timer_Control *ptimer; + boolean activated; + + ptimer = (POSIX_Timer_Control *)data; + + /* Increment the number of expirations. */ + ptimer->overrun = ptimer->overrun + 1; + /* The timer must be reprogrammed */ + if ( ( ptimer->timer_data.it_interval.tv_sec != 0 ) || + ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) { +#if 0 + status = rtems_timer_fire_after( + ptimer->timer_id, ptimer->ticks, _POSIX_Timer_TSR, ptimer ); +#endif + activated = _Watchdog_Insert_ticks_helper( + &ptimer->Timer, + ptimer->ticks, + ptimer->Object.id, + _POSIX_Timer_TSR, + ptimer + ); + if ( !activated ) + return; + + /* Store the time when the timer was started again */ + ptimer->time = _TOD_Current; + + /* The state really did not change but just to be safe */ + ptimer->state = STATE_CREATE_RUN_C; } else { - /* Indicates that the timer is stopped */ - - timer_struct[timer_pos].state = STATE_CREATE_STOP_C; - + /* Indicates that the timer is stopped */ + ptimer->state = STATE_CREATE_STOP_C; } /* @@ -236,20 +158,14 @@ rtems_timer_service_routine FIRE_TIMER_S (rtems_id timer, void *data) * 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 ) ) { - /* XXX error handling */ + if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) { + /* XXX error handling */ } - /* - * After the signal handler returns, the count of expirations of the + /* After the signal handler returns, the count of expirations of the * timer must be set to 0. */ - - timer_struct[timer_pos].overrun = 0; - + ptimer->overrun = 0; } /* ********************************************************************* @@ -266,10 +182,7 @@ int timer_create( 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 */ + POSIX_Timer_Control *ptimer; if ( clock_id != CLOCK_REALTIME ) rtems_set_errno_and_return_minus_one( EINVAL ); @@ -294,82 +207,40 @@ int timer_create( rtems_set_errno_and_return_minus_one( EINVAL ); } - /* - * 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 : - - /* - * 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 */ - - rtems_set_errno_and_return_minus_one( EAGAIN ); - } - - /* 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 */ + _Thread_Disable_dispatch(); /* to prevent deletion */ - rtems_set_errno_and_return_minus_one( EINVAL ); - - case RTEMS_TOO_MANY : - - /* There has been created too much timers for the same process */ - rtems_set_errno_and_return_minus_one( EAGAIN ); + /* + * Allocate a timer + */ + ptimer = _POSIX_Timer_Allocate(); + if ( !ptimer ) { + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EAGAIN ); + } - default : + /* The data of the created timer are stored to use them later */ - /* - * 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. - */ + ptimer->state = STATE_CREATE_NEW_C; + ptimer->thread_id = _Thread_Executing->Object.id; - rtems_set_errno_and_return_minus_one( EINVAL ); + if ( evp != NULL ) { + ptimer->inf.sigev_notify = evp->sigev_notify; + ptimer->inf.sigev_signo = evp->sigev_signo; + ptimer->inf.sigev_value = evp->sigev_value; } - /* - * The next sentence is used to avoid singular situations - */ + ptimer->overrun = 0; + ptimer->timer_data.it_value.tv_sec = 0; + ptimer->timer_data.it_value.tv_nsec = 0; + ptimer->timer_data.it_interval.tv_sec = 0; + ptimer->timer_data.it_interval.tv_nsec = 0; + + _Watchdog_Initialize( &ptimer->Timer, NULL, 0, NULL ); + _Objects_Open(&_POSIX_Timer_Information, &ptimer->Object, (Objects_Name) 0); - rtems_set_errno_and_return_minus_one( EINVAL ); + *timerid = ptimer->Object.id; + _Thread_Enable_dispatch(); + return 0; } /* @@ -380,7 +251,6 @@ int timer_delete( timer_t timerid ) { - /* * IDEA: This function must probably stop the timer first and then delete it * @@ -389,33 +259,29 @@ int 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 */ + POSIX_Timer_Control *ptimer; + Objects_Locations location; + + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); - } - - /* The timer is deleted */ - - status = rtems_timer_delete ( timerid ); - - if ( status == RTEMS_INVALID_ID ) { - /* The timer identifier is erroneus */ - rtems_set_errno_and_return_minus_one( EINVAL ); - } +#endif - /* Initializes the data of the timer */ + case OBJECTS_ERROR: + rtems_set_errno_and_return_minus_one( EINVAL ); - TIMER_INITIALIZE_S ( timer_pos ); - return 0; + case OBJECTS_LOCAL: + _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); + ptimer->state = STATE_FREE_C; + (void) _Watchdog_Remove( &ptimer->Timer ); + _POSIX_Timer_Free( ptimer ); + _Thread_Enable_dispatch(); + return 0; + } + return -1; /* unreached - only to remove warnings */ } /* @@ -434,225 +300,133 @@ int timer_settime( struct itimerspec *ovalue ) { + POSIX_Timer_Control *ptimer; + Objects_Locations location; + boolean activated; - 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 */ + if ( value == NULL ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } - timer_pos = TIMER_POSITION_F ( timerid ); + /* 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 */ + rtems_set_errno_and_return_minus_one( EINVAL ); + } + + /* XXX check for seconds in the past */ - if ( timer_pos == BAD_TIMER_C ) { - /* The timer identifier is erroneus */ - rtems_set_errno_and_return_minus_one( EINVAL ); - } + if ( flags != TIMER_ABSTIME && flags != TIMER_RELATIVE_C ) { + rtems_set_errno_and_return_minus_one( EINVAL ); + } - if ( value == NULL ) { - /* The stucture of times of the timer is free, and then returns an - error but the variable errno is not actualized */ + /* 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 + */ + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + return -1; rtems_set_errno_and_return_minus_one( EINVAL ); - } - - /* 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 ) - *ovalue = timer_struct[timer_pos].timer_data; - - /* The new data are set */ - - timer_struct[timer_pos].timer_data = *value; - - /* 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 */ - - rtems_set_errno_and_return_minus_one( EINVAL ); - } - - /* 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: - - /* The timer has been started and is running */ - - /* Actualizes the data of the structure and - * returns the old ones in "ovalue" */ - - if ( ovalue ) - *ovalue = timer_struct[timer_pos].timer_data; - - timer_struct[timer_pos].timer_data = *value; - - /* 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 */ - - timer_struct[timer_pos].time = _TOD_Current; - return 0; - - break; - - case RTEMS_INVALID_ID: - - /* XXX error handling */ - break; - - case RTEMS_NOT_DEFINED: - - /* XXX error handling */ - break; - - case RTEMS_INVALID_CLOCK: - - /* XXX error handling */ - break; - - default: break; - - - } - - 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 / (NSEC_PER_SEC_C / SEC_TO_TICKS_C)); - - return_v = rtems_timer_fire_after ( timerid, - timer_struct[timer_pos].ticks, - FIRE_TIMER_S, - NULL ); - - switch (return_v) { - case 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 ) - *ovalue = timer_struct[timer_pos].timer_data; - - timer_struct[timer_pos].timer_data = *value; - - /* 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 */ - - timer_struct[timer_pos].time = _TOD_Current; - - return 0; - - break; - - case RTEMS_INVALID_ID: - - /* The timer identifier is not correct. In theory, this - * situation can not occur, but the solution is easy */ - - rtems_set_errno_and_return_minus_one( EINVAL ); - - break; - - case 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; - */ - - rtems_set_errno_and_return_minus_one( EINVAL ); - break; - - default: break; - } +#endif - break; + case OBJECTS_ERROR: + return -1; + + case OBJECTS_LOCAL: + /* First, it verifies if the timer must be stopped */ + if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) { + /* Stop the timer */ + (void) _Watchdog_Remove( &ptimer->Timer ); + /* The old data of the timer are returned */ + if ( ovalue ) + *ovalue = ptimer->timer_data; + /* The new data are set */ + ptimer->timer_data = *value; + /* Indicates that the timer is created and stopped */ + ptimer->state = STATE_CREATE_STOP_C; + /* Returns with success */ + _Thread_Enable_dispatch(); + return 0; + } - default: break; + /* absolute or relative? */ + switch (flags) { + case TIMER_ABSTIME: - /* It does nothing, although it will be probably necessary to - * return an error */ - } + /* The fire time is absolute: use "rtems_time_fire_when" */ + /* First, it converts from struct itimerspec to rtems_time_of_day */ - /* To avoid problems */ - return 0; +#if 0 + ITIMERSPEC_TO_RTEMS_TIME_OF_DAY_S( value, &tod ); + status = rtems_timer_fire_when( + ptimer->timer_id, &tod, _POSIX_Timer_TSR, ptimer); +#endif + _Watchdog_Initialize( + &ptimer->Timer, _POSIX_Timer_TSR, ptimer->Object.id, ptimer ); + + _Watchdog_Insert_seconds( + &ptimer->Timer, + value->it_value.tv_sec - _TOD_Seconds_since_epoch + ); + + /* Returns the old ones in "ovalue" */ + if ( ovalue ) + *ovalue = ptimer->timer_data; + ptimer->timer_data = *value; + + /* Indicate that the time is running */ + ptimer->state = STATE_CREATE_RUN_C; + + /* Stores the time in which the timer was started again */ + ptimer->time = _TOD_Current; + _Thread_Enable_dispatch(); + return 0; + break; + + /* The fire time is relative: use "rtems_time_fire_after" */ + case TIMER_RELATIVE_C: + /* First, convert from seconds and nanoseconds to ticks */ + ptimer->ticks = ( SEC_TO_TICKS_C * value->it_value.tv_sec ) + + ( value->it_value.tv_nsec / (NSEC_PER_SEC_C / SEC_TO_TICKS_C)); + +#if 0 + status = rtems_timer_fire_after( + ptimer->timer_id, ptimer->ticks, _POSIX_Timer_TSR, ptimer ); +#endif + activated = _Watchdog_Insert_ticks_helper( + &ptimer->Timer, + ptimer->ticks, + ptimer->Object.id, + _POSIX_Timer_TSR, + ptimer + ); + if ( !activated ) + return 0; + + /* The timer has been started and is running */ + /* return the old ones in "ovalue" */ + if ( ovalue ) + *ovalue = ptimer->timer_data; + ptimer->timer_data = *value; + + /* Indicate that the time is running */ + ptimer->state = STATE_CREATE_RUN_C; + ptimer->time = _TOD_Current; + _Thread_Enable_dispatch(); + return 0; + } + _Thread_Enable_dispatch(); + rtems_set_errno_and_return_minus_one( EINVAL ); + } + return -1; /* unreached - only to remove warnings */ } - /* * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 */ @@ -679,121 +453,116 @@ int timer_gettime( * between the current time and the initialization time. */ - rtems_time_of_day current_time; - int timer_pos; - uint32_t hours; - uint32_t minutes; - uint32_t seconds; - uint32_t ticks; - uint32_t nanosec; - + POSIX_Timer_Control *ptimer; + Objects_Locations location; + rtems_time_of_day current_time; + uint32_t hours; + uint32_t minutes; + uint32_t seconds; + uint32_t ticks; + uint32_t nanosec; /* Reads the current time */ - current_time = _TOD_Current; - timer_pos = TIMER_POSITION_F ( timerid ); - - if ( timer_pos == BAD_TIMER_C ) { - /* The timer identifier is erroneus */ - rtems_set_errno_and_return_minus_one( EINVAL ); - } - - /* 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; - } + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + rtems_set_errno_and_return_minus_one( EINVAL ); +#endif - 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; - } + case OBJECTS_ERROR: + rtems_set_errno_and_return_minus_one( EINVAL ); - 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; - } + case OBJECTS_LOCAL: + /* Calculates the difference between the start time of the timer and + * the current one */ - /* The time that the timer is running is calculated */ - seconds = hours * 60 * 60 + - minutes * 60 + - seconds; + hours = current_time.hour - ptimer->time.hour; - nanosec = ticks * 10 * /* msec */ - 1000 * /* microsec */ - 1000; /* nanosec */ + if ( current_time.minute < ptimer->time.minute ) { + minutes = 60 - ptimer->time.minute + current_time.minute; + hours--; + } else { + minutes = current_time.minute - ptimer->time.minute; + } + if ( current_time.second < ptimer->time.second ) { + seconds = 60 - ptimer->time.second + current_time.second; + minutes--; + } else { + seconds = current_time.second - ptimer->time.second; + } - /* Calculates the time left before the timer finishes */ + if ( current_time.ticks < ptimer->time.ticks ) { + ticks = 100 - ptimer->time.ticks + current_time.ticks; + seconds--; + } else { + ticks = current_time.ticks - ptimer->time.ticks; + } - value->it_value.tv_sec = - timer_struct[timer_pos].timer_data.it_value.tv_sec - seconds; + /* The time that the timer is running is calculated */ + seconds = hours * 60 * 60 + + minutes * 60 + + seconds; - value->it_value.tv_nsec = - timer_struct[timer_pos].timer_data.it_value.tv_nsec - nanosec; + nanosec = ticks * 10 * /* msec */ + 1000 * /* microsec */ + 1000; /* 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; + /* Calculates the time left before the timer finishes */ + value->it_value.tv_sec = ptimer->timer_data.it_value.tv_sec - seconds; + value->it_value.tv_nsec = ptimer->timer_data.it_value.tv_nsec - nanosec; - return 0; + value->it_interval.tv_sec = ptimer->timer_data.it_interval.tv_sec; + value->it_interval.tv_nsec = ptimer->timer_data.it_interval.tv_nsec; + _Thread_Enable_dispatch(); + return 0; + } + return -1; /* unreached - only to remove warnings */ } /* * 14.2.4 Per-Process Timers, P1003.1b-1993, p. 267 */ -/* ***************** +/* * timer_getoverrun - * *****************/ + * + * The expiration of a timer must increase by one a counter. + * After the signal handler associated to the timer finishes + * its execution, _POSIX_Timer_TSR will have to set this counter to 0. + */ int timer_getoverrun( timer_t timerid ) { + int overrun; + POSIX_Timer_Control *ptimer; + Objects_Locations location; + + ptimer = _POSIX_Timer_Get( timerid, &location ); + switch ( location ) { + case OBJECTS_REMOTE: +#if defined(RTEMS_MULTIPROCESSING) + _Thread_Dispatch(); + rtems_set_errno_and_return_minus_one( EINVAL ); +#endif - /* - * 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 ); + case OBJECTS_ERROR: + rtems_set_errno_and_return_minus_one( EINVAL ); - if ( timer_pos == BAD_TIMER_C ) { - /* The timer identifier is erroneus */ - rtems_set_errno_and_return_minus_one( EINVAL ); + case OBJECTS_LOCAL: + overrun = ptimer->overrun; + ptimer->overrun = 0; + _Thread_Enable_dispatch(); + return overrun; } - - /* 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; - + return -1; /* unreached - only to remove warnings */ } diff --git a/cpukit/sapi/src/posixapi.c b/cpukit/sapi/src/posixapi.c index d1163c79f0..a86962c912 100644 --- a/cpukit/sapi/src/posixapi.c +++ b/cpukit/sapi/src/posixapi.c @@ -41,7 +41,7 @@ #include <rtems/posix/priority.h> #include <rtems/posix/psignal.h> #include <rtems/posix/pthread.h> -#include <rtems/posix/ptimer.h> +#include <rtems/posix/timer.h> #include <rtems/posix/semaphore.h> #include <rtems/posix/time.h> diff --git a/cpukit/score/include/rtems/score/object.h b/cpukit/score/include/rtems/score/object.h index 661f53eb11..2a9c0b0280 100644 --- a/cpukit/score/include/rtems/score/object.h +++ b/cpukit/score/include/rtems/score/object.h @@ -249,11 +249,12 @@ typedef enum { OBJECTS_POSIX_MESSAGE_QUEUES = 5, OBJECTS_POSIX_MUTEXES = 6, OBJECTS_POSIX_SEMAPHORES = 7, - OBJECTS_POSIX_CONDITION_VARIABLES = 8 + OBJECTS_POSIX_CONDITION_VARIABLES = 8, + OBJECTS_POSIX_TIMERS = 9 } Objects_POSIX_API; /** This macro is used to generically specify the last API index. */ -#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_CONDITION_VARIABLES +#define OBJECTS_POSIX_CLASSES_LAST OBJECTS_POSIX_TIMERS /** * This enumerated type is used in the class field of the object ID |