diff options
-rw-r--r-- | cpukit/ChangeLog | 15 | ||||
-rw-r--r-- | cpukit/posix/Makefile.am | 5 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/priority.h | 43 | ||||
-rw-r--r-- | cpukit/posix/include/rtems/posix/pthread.h | 88 | ||||
-rw-r--r-- | cpukit/posix/inline/rtems/posix/priority.inl | 19 | ||||
-rw-r--r-- | cpukit/posix/src/killinfo.c | 22 | ||||
-rw-r--r-- | cpukit/posix/src/psxpriorityisvalid.c | 27 | ||||
-rw-r--r-- | cpukit/posix/src/psxtransschedparam.c | 65 | ||||
-rw-r--r-- | cpukit/posix/src/pthread.c | 9 | ||||
-rw-r--r-- | cpukit/posix/src/pthreadcreate.c | 100 | ||||
-rw-r--r-- | cpukit/posix/src/pthreadsetschedparam.c | 46 |
11 files changed, 265 insertions, 174 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index a3fac19229..39d0bba0ba 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,18 @@ +2009-06-24 Joel Sherrill <joel.sherrill@oarcorp.com> + + * posix/Makefile.am, posix/include/rtems/posix/priority.h, + posix/include/rtems/posix/pthread.h, + posix/inline/rtems/posix/priority.inl, posix/src/killinfo.c, + posix/src/pthread.c, posix/src/pthreadcreate.c, + posix/src/pthreadsetschedparam.c: Various modifications to improve + binary code coverage analysis. Some of these are to mark code as + debug only. Some are to break conditional expressions into multiple + lines. Some are to move inline methods that are not time critical + into subroutines to make them easier to test. Inlining them multiple + times means that their logic paths are spread across multiple + methods. This explodes the test cases required. + * posix/src/psxpriorityisvalid.c, posix/src/psxtransschedparam.c: New files. + 2009-06-18 Joel Sherrill <joel.sherrill@OARcorp.com> * rtems/src/regionextend.c: Restructure to eliminate dead code being diff --git a/cpukit/posix/Makefile.am b/cpukit/posix/Makefile.am index 8d10e3495f..8435779997 100644 --- a/cpukit/posix/Makefile.am +++ b/cpukit/posix/Makefile.am @@ -121,7 +121,7 @@ libposix_a_SOURCES += src/pthread.c src/pthreadsetcputime.c \ src/pthreadattrgetschedpolicy.c src/pthreadattrsetschedpolicy.c \ src/pthreadattrgetinheritsched.c src/pthreadattrsetinheritsched.c \ src/pthreadattrgetscope.c src/pthreadattrsetscope.c \ - src/pthreadinitthreads.c + src/pthreadinitthreads.c src/psxtransschedparam.c ## PSIGNAL_C_FILES libposix_a_SOURCES += src/psignal.c src/alarm.c src/kill.c src/killinfo.c \ @@ -167,6 +167,9 @@ libposix_a_SOURCES += src/ptimer.c src/timercreate.c src/timerdelete.c \ ## ITIMER_C_FILES libposix_a_SOURCES += src/getitimer.c src/setitimer.c +## SUPPORT_C_FILES +libposix_a_SOURCES += src/psxpriorityisvalid.c + EXTRA_DIST += src/README.mqueue libposix_a_SOURCES += src/sched_getparam.c src/sched_getprioritymax.c \ diff --git a/cpukit/posix/include/rtems/posix/priority.h b/cpukit/posix/include/rtems/posix/priority.h index 2111bd3118..8e5fb02634 100644 --- a/cpukit/posix/include/rtems/posix/priority.h +++ b/cpukit/posix/include/rtems/posix/priority.h @@ -3,7 +3,7 @@ */ /* - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -18,7 +18,7 @@ #include <rtems/score/priority.h> -/* +/** * 1003.1b-1993,2.2.2.80 definition of priority, p. 19 * * "Numerically higher values represent higher priorities." @@ -34,19 +34,54 @@ * But since RTEMS can be configured with fewer than 256 priorities, * we use the internal constant. */ - #define POSIX_SCHEDULER_MAXIMUM_PRIORITY (PRIORITY_MAXIMUM - 1) + +/** + * This is the numerically least important POSIX priority. + */ #define POSIX_SCHEDULER_MINIMUM_PRIORITY (1) -RTEMS_INLINE_ROUTINE bool _POSIX_Priority_Is_valid( +/** + * 1003.1b-1993,2.2.2.80 definition of priority, p. 19 + * + * "Numerically higher values represent higher priorities." + * + * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API. + * + * @param[in] priority is the priority to test + * + * @return This method returns true if the priority is valid and + * false otherwise. + */ +bool _POSIX_Priority_Is_valid( int priority ); +/** + * @brief Convert POSIX Priority To SuperCore Priority + * + * This method converts a POSIX API priority into onto the corresponding + * SuperCore value. + * + * @param[in] priority is the POSIX API priority. + * + * @return This method returns the corresponding SuperCore priority. + */ RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core( int priority ); +/** + * @brief Convert SuperCore Priority To POSIX Priority + * + * This method converts a SuperCore priority into onto the corresponding + * POSIX API value. + * + * @param[in] priority is the POSIX API priority. + * + * @return This method returns the corresponding POSIX priority. + */ RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core( Priority_Control priority ); diff --git a/cpukit/posix/include/rtems/posix/pthread.h b/cpukit/posix/include/rtems/posix/pthread.h index 27156dd886..66f3ab9f6d 100644 --- a/cpukit/posix/include/rtems/posix/pthread.h +++ b/cpukit/posix/include/rtems/posix/pthread.h @@ -36,9 +36,11 @@ extern "C" { * The following defines the information control block used to manage * this class of objects. */ - POSIX_EXTERN Objects_Information _POSIX_Threads_Information; +/** + * This variable contains the default POSIX Thread attributes. + */ extern const pthread_attr_t _POSIX_Threads_Default_attributes; /** @@ -50,44 +52,37 @@ extern const pthread_attr_t _POSIX_Threads_Default_attributes; */ extern void (*_POSIX_Threads_Initialize_user_threads_p)(void); -/* - * _POSIX_Threads_Manager_initialization - * - * DESCRIPTION: +/** + * @brief _POSIX_Threads_Manager_initialization * * This routine performs the initialization necessary for this manager. */ - void _POSIX_Threads_Manager_initialization(void); -/* - * _POSIX_Threads_Allocate - * - * DESCRIPTION: +/** + * @brief _POSIX_Threads_Allocate * * This function allocates a pthread control block from * the inactive chain of free pthread control blocks. + * + * @return This method returns a newly allocated thread. */ - RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate( void ); -/* - * _POSIX_Threads_Free - * - * DESCRIPTION: +/** + * @brief _POSIX_Threads_Free * * This routine frees a pthread control block to the * inactive chain of free pthread control blocks. + * + * @param[in] the_pthread is the thread to free */ - RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free( Thread_Control *the_pthread ); -/* - * _POSIX_Threads_Get - * - * DESCRIPTION: +/** + * @brief _POSIX_Threads_Get * * This function maps pthread IDs to pthread control blocks. * If ID corresponds to a local pthread, then it returns @@ -96,50 +91,73 @@ RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free( * resides on a remote node, then location is set to OBJECTS_REMOTE, * and the_pthread is undefined. Otherwise, location is set * to OBJECTS_ERROR and the_pthread is undefined. + * + * @param[in] id is the id to lookup + * @param[in] location points to the returned location value + * + * @return This methods returns a pointer to the corresponding Thread_Control. */ - RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Get( pthread_t id, Objects_Locations *location ); -/* - * _POSIX_Threads_Is_null - * - * DESCRIPTION: +/** + * @brief _POSIX_Threads_Is_null * * This function returns TRUE if the_pthread is NULL and FALSE otherwise. + * + * @param[in] the_pthread is the thread pointer to check. + * + * @return This method returns true if the thread pointer is null. */ - RTEMS_INLINE_ROUTINE bool _POSIX_Threads_Is_null( Thread_Control *the_pthread ); -/* - * _POSIX_Threads_Sporadic_budget_callout - * - * DESCRIPTION: +/** + * @brief _POSIX_Threads_Sporadic_budget_callout * * This routine handles the sporadic scheduling algorithm. + * + * @param[in] the_thread is the thread whose budget has been exceeded. */ - void _POSIX_Threads_Sporadic_budget_callout( Thread_Control *the_thread ); -/* +/** * _POSIX_Threads_Sporadic_budget_TSR * - * DESCRIPTION: - * * This routine supports the sporadic scheduling algorithm. + * + * @param[in] the_thread is the thread whose budget has been exceeded. */ - void _POSIX_Threads_Sporadic_budget_TSR( Objects_Id id, void *argument ); +/** + * @brief Translate sched_param into SuperCore Terms + * + * This method translates the POSIX API sched_param into the corresponding + * SuperCore settings. + * + * @param[in] policy is the POSIX scheduling policy + * @param[in] param points to the scheduling parameter structure + * @param[in] budget_algorithm points to the output CPU Budget algorithm + * @param[in] budget_callout points to the output CPU Callout + * + * @return This method returns 0 on success or a POSIX error code. + */ +int _POSIX_Thread_Translate_sched_param( + int policy, + struct sched_param *param, + Thread_CPU_budget_algorithms *budget_algorithm, + Thread_CPU_budget_algorithm_callout *budget_callout +); + #include <rtems/posix/pthread.inl> #ifdef __cplusplus diff --git a/cpukit/posix/inline/rtems/posix/priority.inl b/cpukit/posix/inline/rtems/posix/priority.inl index 74287bd9f3..9a9f538a61 100644 --- a/cpukit/posix/inline/rtems/posix/priority.inl +++ b/cpukit/posix/inline/rtems/posix/priority.inl @@ -3,7 +3,7 @@ */ /* - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -20,23 +20,6 @@ #ifndef _RTEMS_POSIX_PRIORITY_INL #define _RTEMS_POSIX_PRIORITY_INL -/* - * 1003.1b-1993,2.2.2.80 definition of priority, p. 19 - * - * "Numerically higher values represent higher priorities." - * - * Thus, RTEMS Core has priorities run in the opposite sense of the POSIX API. - */ - -RTEMS_INLINE_ROUTINE bool _POSIX_Priority_Is_valid( - int priority -) -{ - return ((priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY) && - (priority <= POSIX_SCHEDULER_MAXIMUM_PRIORITY)); - -} - RTEMS_INLINE_ROUTINE Priority_Control _POSIX_Priority_To_core( int priority ) diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c index 2eb0441fc6..e44016d125 100644 --- a/cpukit/posix/src/killinfo.c +++ b/cpukit/posix/src/killinfo.c @@ -186,13 +186,15 @@ int killinfo( the_info = _Objects_Information_table[ the_api ][ 1 ]; - /* - * This cannot happen in the current (as of June 2009) implementation - * of initialization but at some point, the object information - * structure for a particular manager may not be installed. - */ - if ( !the_info ) - continue; + #if defined(RTEMS_DEBUG) + /* + * This cannot happen in the current (as of June 2009) implementation + * of initialization but at some point, the object information + * structure for a particular manager may not be installed. + */ + if ( !the_info ) + continue; + #endif maximum = the_info->maximum; object_table = the_info->local_table; @@ -217,8 +219,10 @@ int killinfo( api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - if ( !api ) - continue; + #if defined(RTEMS_DEBUG) + if ( !api ) + continue; + #endif if ( !_POSIX_signals_Is_interested( api, mask ) ) continue; diff --git a/cpukit/posix/src/psxpriorityisvalid.c b/cpukit/posix/src/psxpriorityisvalid.c new file mode 100644 index 0000000000..4b35a81e62 --- /dev/null +++ b/cpukit/posix/src/psxpriorityisvalid.c @@ -0,0 +1,27 @@ +/* + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems/system.h> +#include <rtems/posix/priority.h> + +bool _POSIX_Priority_Is_valid( + int priority +) +{ + return ((priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY) && + (priority <= POSIX_SCHEDULER_MAXIMUM_PRIORITY)); + +} + diff --git a/cpukit/posix/src/psxtransschedparam.c b/cpukit/posix/src/psxtransschedparam.c new file mode 100644 index 0000000000..8e91af75d4 --- /dev/null +++ b/cpukit/posix/src/psxtransschedparam.c @@ -0,0 +1,65 @@ +/* COPYRIGHT (c) 1989-2009. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include <pthread.h> +#include <errno.h> + +#include <rtems/system.h> +#include <rtems/posix/pthread.h> +#include <rtems/posix/priority.h> +#include <rtems/posix/time.h> + +int _POSIX_Thread_Translate_sched_param( + int policy, + struct sched_param *param, + Thread_CPU_budget_algorithms *budget_algorithm, + Thread_CPU_budget_algorithm_callout *budget_callout +) +{ + if ( !_POSIX_Priority_Is_valid( param->sched_priority ) ) + return EINVAL; + + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + *budget_callout = NULL; + + switch ( policy ) { + case SCHED_OTHER: + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; + break; + + case SCHED_FIFO: + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; + break; + + case SCHED_RR: + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE; + break; + + case SCHED_SPORADIC: + *budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT; + *budget_callout = _POSIX_Threads_Sporadic_budget_callout; + + if ( _Timespec_To_ticks( ¶m->ss_replenish_period ) < + _Timespec_To_ticks( ¶m->ss_initial_budget ) ) + return EINVAL; + + if ( !_POSIX_Priority_Is_valid( param->ss_low_priority ) ) + return EINVAL; + break; + + default: + return EINVAL; + } + return 0; +} diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 72354ae49a..ae42dbe3fa 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -172,12 +172,17 @@ bool _POSIX_Threads_Create_extension( /* * If the thread is not a posix thread, then all posix signals are blocked * by default. + * + * The check for class == 1 is debug. Should never really happen. */ /* XXX use signal constants */ api->signals_pending = 0; - if ( _Objects_Get_API( created->Object.id ) == OBJECTS_POSIX_API && - _Objects_Get_class( created->Object.id ) == 1 ) { + if ( _Objects_Get_API( created->Object.id ) == OBJECTS_POSIX_API + #if defined(RTEMS_DEBUG) + && _Objects_Get_class( created->Object.id ) == 1 + #endif + ) { executing_api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; api->signals_blocked = executing_api->signals_blocked; } else { diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index 4ce8c2b2d1..b17da6b9ba 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -54,6 +54,7 @@ int pthread_create( int schedpolicy = SCHED_RR; struct sched_param schedparam; Objects_Name name; + int rc; if ( !start_routine ) return EFAULT; @@ -73,10 +74,10 @@ int pthread_create( if ( the_attr->stackaddr && !_Stack_Is_enough(the_attr->stacksize) ) return EINVAL; -#if 0 - int cputime_clock_allowed; /* see time.h */ - rtems_set_errno_and_return_minus_one( ENOSYS ); -#endif + #if 0 + int cputime_clock_allowed; /* see time.h */ + rtems_set_errno_and_return_minus_one( ENOSYS ); + #endif /* * P1003.1c/Draft 10, p. 121. @@ -86,7 +87,6 @@ int pthread_create( * PTHREAD_EXPLICIT_SCHED, then scheduling parameters come from the * attributes structure. */ - switch ( the_attr->inheritsched ) { case PTHREAD_INHERIT_SCHED: api = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ]; @@ -107,14 +107,12 @@ int pthread_create( * Check the contentionscope since rtems only supports PROCESS wide * contention (i.e. no system wide contention). */ - if ( the_attr->contentionscope != PTHREAD_SCOPE_PROCESS ) return ENOTSUP; /* * Interpret the scheduling parameters. */ - if ( !_POSIX_Priority_Is_valid( schedparam.sched_priority ) ) return EINVAL; @@ -123,51 +121,24 @@ int pthread_create( /* * Set the core scheduling policy information. */ - - budget_callout = NULL; - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; - - switch ( schedpolicy ) { - case SCHED_OTHER: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; - break; - - case SCHED_FIFO: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; - break; - - case SCHED_RR: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE; - break; - - case SCHED_SPORADIC: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT; - budget_callout = _POSIX_Threads_Sporadic_budget_callout; - - if ( _Timespec_To_ticks( &schedparam.ss_replenish_period ) < - _Timespec_To_ticks( &schedparam.ss_initial_budget ) ) - return EINVAL; - - if ( !_POSIX_Priority_Is_valid( schedparam.ss_low_priority ) ) - return EINVAL; - - break; - - default: - return EINVAL; - } + rc = _POSIX_Thread_Translate_sched_param( + schedpolicy, + &schedparam, + &budget_algorithm, + &budget_callout + ); + if ( rc ) + return rc; /* * Currently all POSIX threads are floating point if the hardware * supports it. */ - - -#if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) - is_fp = true; -#else - is_fp = false; -#endif + #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) + is_fp = true; + #else + is_fp = false; + #endif /* * Lock the allocator mutex for protection @@ -179,9 +150,7 @@ int pthread_create( * * NOTE: Global threads are not currently supported. */ - the_thread = _POSIX_Threads_Allocate(); - if ( !the_thread ) { _RTEMS_Unlock_allocator(); return EAGAIN; @@ -190,7 +159,6 @@ int pthread_create( /* * Initialize the core thread for this task. */ - name.name_p = NULL; /* posix threads don't have a name by default */ status = _Thread_Initialize( &_POSIX_Threads_Information, @@ -215,8 +183,6 @@ int pthread_create( /* * finish initializing the per API structure */ - - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; api->Attributes = *the_attr; @@ -230,13 +196,11 @@ int pthread_create( * * NOTE: Since the thread starts with all unblocked, this is necessary. */ - the_thread->do_post_task_switch_extension = true; /* * POSIX threads are allocated and started in one operation. */ - status = _Thread_Start( the_thread, THREAD_START_POINTER, @@ -245,6 +209,20 @@ int pthread_create( 0 /* unused */ ); + #if defined(RTEMS_DEBUG) + /* + * _Thread_Start only fails if the thread was in the incorrect state + * + * NOTE: This can only happen if someone slips in and touches the + * thread while we are creating it. + */ + if ( !status ) { + _POSIX_Threads_Free( the_thread ); + _RTEMS_Unlock_allocator(); + return EINVAL; + } + #endif + if ( schedpolicy == SCHED_SPORADIC ) { _Watchdog_Insert_ticks( &api->Sporadic_timer, @@ -253,22 +231,8 @@ int pthread_create( } /* - * _Thread_Start only fails if the thread was in the incorrect state - * - * NOTE: This can only happen if someone slips in and touches the - * thread while we are creating it. - */ - - if ( !status ) { - _POSIX_Threads_Free( the_thread ); - _RTEMS_Unlock_allocator(); - return EINVAL; - } - - /* * Return the id and indicate we successfully created the thread */ - *thread = the_thread->Object.id; _RTEMS_Unlock_allocator(); diff --git a/cpukit/posix/src/pthreadsetschedparam.c b/cpukit/posix/src/pthreadsetschedparam.c index 8d5ffb1888..e95659f2db 100644 --- a/cpukit/posix/src/pthreadsetschedparam.c +++ b/cpukit/posix/src/pthreadsetschedparam.c @@ -36,54 +36,26 @@ int pthread_setschedparam( Thread_CPU_budget_algorithms budget_algorithm; Thread_CPU_budget_algorithm_callout budget_callout; Objects_Locations location; + int rc; /* * Check all the parameters */ - if ( !param ) return EINVAL; - if ( !_POSIX_Priority_Is_valid( param->sched_priority ) ) - return EINVAL; - - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; - budget_callout = NULL; - - switch ( policy ) { - case SCHED_OTHER: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_RESET_TIMESLICE; - break; - - case SCHED_FIFO: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE; - break; - - case SCHED_RR: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_EXHAUST_TIMESLICE; - break; - - case SCHED_SPORADIC: - budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT; - budget_callout = _POSIX_Threads_Sporadic_budget_callout; - - if ( _Timespec_To_ticks( ¶m->ss_replenish_period ) < - _Timespec_To_ticks( ¶m->ss_initial_budget ) ) - return EINVAL; - - if ( !_POSIX_Priority_Is_valid( param->ss_low_priority ) ) - return EINVAL; - - break; - - default: - return EINVAL; - } + rc = _POSIX_Thread_Translate_sched_param( + policy, + param, + &budget_algorithm, + &budget_callout + ); + if ( rc ) + return rc; /* * Actually change the scheduling policy and parameters */ - the_thread = _POSIX_Threads_Get( thread, &location ); switch ( location ) { |