Possible bug in _CORE_mutex_Seize()
Till Straumann
strauman at SLAC.Stanford.EDU
Wed Oct 1 00:55:26 UTC 2003
The patches look good to me...
-- T.
Phil Torre wrote:
> On Tue, Sep 30, 2003 at 03:19:30PM -0700, Till Straumann wrote:
>
>>Joel Sherrill wrote:
>>
>>>Phil Torre wrote:
>>>
>>>
>>>>I'm running now with some of the changes suggested by Till and Joel:
>>>>
>>>>1. "Paranoia" added to _CORE_mutex_Seize() which checks
>>>> _Thread_Dispatch_disable_level and throws an internal error if
>>>> its nonzero when it shouldn't be.
>>>
>>>
>>>Be careful with this one. I don't think this is the right place to
>>>check it. You can attempt to obtain a mutex in an ISR and
>>>_Thread_Dispatch_disable_level will definitely be non-zero. You
>>>can't use the Allocator Mutex when _Thread_Dispatch_disable_level
>>>is non-zero but it is conceivable that you could use another mutex.
>
>
> I am running our application now with the patches attached. The paranoia
> check in coremutex.h is there, along with the actual bugfix in newlibc.c.
> (If the call to _Workspace_Allocate() fails, we would rather have an error
> propagated back up to the application than have an RTEMS fatal error
> thrown. I don't know what the majority opinion would be of that.)
>
> I can file a PR and attach my patches to it as soon as a consensus is
> reached about the validity of the paranoia check.
>
> -Phil
>
>
>
>
>
>
>
>
>
>
> ------------------------------------------------------------------------
>
> --- /tmp/coremutex.h 2003-09-30 15:40:06.000000000 -0700
> +++ cpukit/score/include/rtems/score/coremutex.h 2003-09-29 17:53:23.000000000 -0700
> @@ -26,6 +26,8 @@
> #include <rtems/score/threadq.h>
> #include <rtems/score/priority.h>
> #include <rtems/score/watchdog.h>
> +#include <rtems/score/interr.h>
> +#include <rtems/score/sysstate.h>
>
> /*
> * The following type defines the callout which the API provides
> @@ -152,6 +154,7 @@
> * a macro that uses two support routines.
> */
>
> +
> #ifndef __RTEMS_APPLICATION__
> RTEMS_INLINE_ROUTINE int _CORE_mutex_Seize_interrupt_trylock(
> CORE_mutex_Control *the_mutex,
> @@ -166,6 +169,15 @@
> #define _CORE_mutex_Seize( \
> _the_mutex, _id, _wait, _timeout, _level ) \
> do { \
> + if ( _Thread_Dispatch_disable_level \
> + && (_wait) \
> + && (_System_state_Get() >= SYSTEM_STATE_BEGIN_MULTITASKING ) \
> + ) { \
> + _Internal_error_Occurred( \
> + INTERNAL_ERROR_CORE, \
> + FALSE, \
> + 18 /* called from wrong environment */); \
> + } \
> if ( _CORE_mutex_Seize_interrupt_trylock( _the_mutex, &_level ) ) { \
> if ( !_wait ) { \
> _ISR_Enable( _level ); \
>
>
> ------------------------------------------------------------------------
>
> --- /tmp/old_newlibc.c 2003-09-30 15:29:13.000000000 -0700
> +++ cpukit/libcsupport/src/newlibc.c 2003-09-30 15:37:15.000000000 -0700
> @@ -96,55 +96,72 @@
> fclose (stderr);
> }
>
> -
> +/*
> + * reent struct allocation moved here from libc_start_hook() to avoid
> + * mutual exclusion problems when memory is allocated from the start hook.
> + *
> + * Memory is also now allocated from the workspace rather than the heap.
> + * -- ptorre 9/30/03
> + */
> rtems_boolean libc_create_hook(
> rtems_tcb *current_task,
> rtems_tcb *creating_task
> )
> {
> - creating_task->libc_reent = NULL;
> - return TRUE;
> -}
> -
> -/*
> - * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
> - */
> -
> -rtems_extension libc_start_hook(
> - rtems_tcb *current_task,
> - rtems_tcb *starting_task
> -)
> -{
> struct _reent *ptr;
>
> /* NOTE: The RTEMS malloc is reentrant without a reent ptr since
> * it is based on the Classic API Region Manager.
> */
>
> +#define REENT_MALLOCED 0
> +#if REENT_MALLOCED
> ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
> +#else
> + /* It is OK to allocate from the workspace because these
> + * hooks run with thread dispatching disabled.
> + */
> + ptr = (struct _reent *) _Workspace_Allocate(sizeof(struct _reent));
> +#endif
>
> - if (!ptr)
> - rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
> + if (ptr)
> + {
>
> #ifdef __GNUC__
> - /* GCC extension: structure constants */
> - _REENT_INIT_PTR((ptr));
> + /* GCC extension: structure constants */
> + _REENT_INIT_PTR((ptr));
> #else
> - /*
> - * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!!
> - * Last visual check was against newlib 1.8.2 but last known
> - * use was against 1.7.0. This is basically an exansion of
> - * REENT_INIT() in <sys/reent.h>.
> - * NOTE: calloc() takes care of zeroing fields.
> - */
> - ptr->_stdin = &ptr->__sf[0];
> - ptr->_stdout = &ptr->__sf[1];
> - ptr->_stderr = &ptr->__sf[2];
> - ptr->_current_locale = "C";
> - ptr->_new._reent._rand_next = 1;
> + /*
> + * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!!
> + * Last visual check was against newlib 1.8.2 but last known
> + * use was against 1.7.0. This is basically an exansion of
> + * REENT_INIT() in <sys/reent.h>.
> + */
> + memset(ptr, 0, sizeof(*ptr));
> + ptr->_stdin = &ptr->__sf[0];
> + ptr->_stdout = &ptr->__sf[1];
> + ptr->_stderr = &ptr->__sf[2];
> + ptr->_current_locale = "C";
> + ptr->_new._reent._rand_next = 1;
> #endif
>
> - starting_task->libc_reent = ptr;
> + creating_task->libc_reent = ptr;
> + return TRUE;
> + }
> + else
> + return FALSE;
> +
> +}
> +
> +/*
> + * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
> + */
> +
> +rtems_extension libc_start_hook(
> + rtems_tcb *current_task,
> + rtems_tcb *starting_task
> +)
> +{
> }
>
> /*
> @@ -204,7 +221,11 @@
> if (ptr && ptr != &libc_global_reent) {
> _wrapup_reent(ptr);
> _reclaim_reent(ptr);
> +#if REENT_MALLOCED
> free(ptr);
> +#else
> + _Workspace_Free(ptr);
> +#endif
> }
>
> deleted_task->libc_reent = NULL;
More information about the users
mailing list