Possible bug in _CORE_mutex_Seize()
Joel Sherrill
joel.sherrill at OARcorp.com
Wed Oct 1 00:36:27 UTC 2003
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.)
>
>
It is a case that is normally an API level error code because it is
equivalent to running out of
memory for task stacks on a task create or memory for pending messages
on a message queue
create.
>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.
>
>
Please do. I am waiting on this one to cut a new tarball.
>-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