summaryrefslogtreecommitdiffstats
path: root/cpukit
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2003-10-02 12:39:05 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2003-10-02 12:39:05 +0000
commit6cff0f87fa5aaf96f73b93bcb9c482694ae10550 (patch)
treeaca1bc95122e294d07d5248d89ac1a5eac8eb73d /cpukit
parent2003-10-02 Ralf Corsepius <corsepiu@faw.uni-ulm.de> (diff)
downloadrtems-6cff0f87fa5aaf96f73b93bcb9c482694ae10550.tar.bz2
2003-10-02 Phil Torre <ptorre@zetron.com>
PR 504/rtems * src/newlibc.c: Fix memory allocation of libc extension so it is dispatch disabled safe See PR for detailed explanation.
Diffstat (limited to 'cpukit')
-rw-r--r--cpukit/libcsupport/ChangeLog6
-rw-r--r--cpukit/libcsupport/src/newlibc.c83
2 files changed, 58 insertions, 31 deletions
diff --git a/cpukit/libcsupport/ChangeLog b/cpukit/libcsupport/ChangeLog
index c7427ace52..cedef7874e 100644
--- a/cpukit/libcsupport/ChangeLog
+++ b/cpukit/libcsupport/ChangeLog
@@ -1,3 +1,9 @@
+2003-10-02 Phil Torre <ptorre@zetron.com>
+
+ PR 504/rtems
+ * src/newlibc.c: Fix memory allocation of libc extension so it is
+ dispatch disabled safe See PR for detailed explanation.
+
2003-09-26 Till Strauman <strauman@slac.stanford.edu>
PR 498/rtems
diff --git a/cpukit/libcsupport/src/newlibc.c b/cpukit/libcsupport/src/newlibc.c
index 4c0e1d5279..13c600731a 100644
--- a/cpukit/libcsupport/src/newlibc.c
+++ b/cpukit/libcsupport/src/newlibc.c
@@ -92,55 +92,72 @@ void libc_wrapup(void)
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
+)
+{
}
/*
@@ -200,7 +217,11 @@ rtems_extension libc_delete_hook(
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;