summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libc
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-05 19:02:03 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-11-05 19:02:03 +0000
commit7edb9281a2e9da28fdaa64a7a71905a24e0dc6f8 (patch)
treef401ae5204e4f045b1788bbdad709bbf85e0ab2b /c/src/lib/libc
parentPatch from Eric Valette <valette@crf.canon.fr> so this will build (diff)
downloadrtems-7edb9281a2e9da28fdaa64a7a71905a24e0dc6f8.tar.bz2
Following comments from Eric Norum <eric@cls.usask.ca>, a fairly
substantial upgrade of newlibc.c occurred. Now the user extension data area is used rather than notepads and as many routines as possible were split into other files further reducing the minimum footprint of an RTEMS executable.
Diffstat (limited to 'c/src/lib/libc')
-rw-r--r--c/src/lib/libc/Makefile.in4
-rw-r--r--c/src/lib/libc/__getpid.c14
-rw-r--r--c/src/lib/libc/newlibc.c430
-rw-r--r--c/src/lib/libc/no_posix.c101
4 files changed, 262 insertions, 287 deletions
diff --git a/c/src/lib/libc/Makefile.in b/c/src/lib/libc/Makefile.in
index e91e2dd478..8b88d51c8e 100644
--- a/c/src/lib/libc/Makefile.in
+++ b/c/src/lib/libc/Makefile.in
@@ -46,8 +46,8 @@ MALLOC_C_PIECES = malloc __brk __sbrk
PASSWORD_GROUP_C_PIECES = getpwent getgrent
-LIBC_GLUE_C_PIECES = __gettod __times truncate access stat lstat pathconf \
- newlibc no_libc
+LIBC_GLUE_C_PIECES = __getpid __gettod __times truncate access stat \
+ lstat pathconf newlibc no_posix no_libc
UNIX_LIBC_C_PIECES = unixlibc hosterr
diff --git a/c/src/lib/libc/__getpid.c b/c/src/lib/libc/__getpid.c
new file mode 100644
index 0000000000..32353b717d
--- /dev/null
+++ b/c/src/lib/libc/__getpid.c
@@ -0,0 +1,14 @@
+/*
+ * Some C Libraries reference this routine since they think getpid is
+ * a real system call.
+ *
+ * $Id$
+ */
+
+#include <unistd.h>
+
+pid_t __getpid(void)
+{
+ return getpid();
+}
+
diff --git a/c/src/lib/libc/newlibc.c b/c/src/lib/libc/newlibc.c
index 3a3812e1ae..cfa9100e96 100644
--- a/c/src/lib/libc/newlibc.c
+++ b/c/src/lib/libc/newlibc.c
@@ -40,24 +40,17 @@
#include <stdio.h>
#endif
+static int extension_index;
+
/*
* Private routines
*/
-void MY_task_set_note(
- rtems_tcb *tcb,
- rtems_unsigned32 notepad,
- rtems_unsigned32 note
-);
-
-rtems_unsigned32 MY_task_get_note(
- rtems_tcb *tcb,
- rtems_unsigned32 notepad
-);
-
-
-#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST
+#define set_newlib_extension( _the_thread, _value ) \
+ (_the_thread)->extensions[ extension_index ] = (_value);
+#define get_newlib_extension( _the_thread ) \
+ (_the_thread)->extensions[ extension_index ]
int libc_reentrant; /* do we think we are reentrant? */
struct _reent libc_global_reent;
@@ -73,90 +66,93 @@ extern void _reclaim_reent(struct _reent *);
#include <stdio.h>
-void
-libc_wrapup(void)
+void libc_wrapup(void)
{
- /*
- * In case RTEMS is already down, don't do this. It could be
- * dangerous.
- */
-
- if (!_System_state_Is_up(_System_state_Get()))
- return;
-
- /*
- * This was already done if the user called exit() directly .
-
- _wrapup_reent(0);
- */
- if (_REENT != &libc_global_reent)
- {
- _wrapup_reent(&libc_global_reent);
+ /*
+ * In case RTEMS is already down, don't do this. It could be
+ * dangerous.
+ */
+
+ if (!_System_state_Is_up(_System_state_Get()))
+ return;
+
+ /*
+ * This was already done if the user called exit() directly .
+ _wrapup_reent(0);
+ */
+
+ if (_REENT != &libc_global_reent) {
+ _wrapup_reent(&libc_global_reent);
#if 0
- /* don't reclaim this one, just in case we do printfs */
- /* on our way out to ROM */
- _reclaim_reent(&libc_global_reent);
+ /* Don't reclaim this one, just in case we do printfs
+ * on the way out to ROM.
+ */
+ _reclaim_reent(&libc_global_reent);
#endif
- _REENT = &libc_global_reent;
- }
-
- /*
- * Try to drain output buffers.
- *
- * Should this be changed to do *all* file streams?
- * _fwalk (_REENT, fclose);
- */
- fclose (stdin);
- fclose (stdout);
- fclose (stderr);
+ _REENT = &libc_global_reent;
+ }
+
+ /*
+ * Try to drain output buffers.
+ *
+ * Should this be changed to do *all* file streams?
+ * _fwalk (_REENT, fclose);
+ */
+
+ fclose (stdin);
+ fclose (stdout);
+ fclose (stderr);
}
-rtems_boolean
-libc_create_hook(rtems_tcb *current_task,
- rtems_tcb *creating_task)
+rtems_boolean libc_create_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *creating_task
+)
{
- MY_task_set_note(creating_task, LIBC_NOTEPAD, 0);
- return TRUE;
+ set_newlib_extension( creating_task, 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)
+rtems_extension libc_start_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *starting_task
+)
{
- struct _reent *ptr;
+ struct _reent *ptr;
- /* NOTE: our malloc is reentrant without a reent ptr since
- * it is based on region manager
- */
+ /* NOTE: The RTEMS malloc is reentrant without a reent ptr since
+ * it is based on the Classic API Region Manager.
+ */
- ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
+ ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
- if (!ptr)
- rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
+ if (!ptr)
+ rtems_fatal_error_occurred(RTEMS_NO_MEMORY);
#ifdef __GNUC__
- /* GCC extension: structure constants */
- *ptr = (struct _reent) _REENT_INIT((*ptr));
+ /* GCC extension: structure constants */
+ *ptr = (struct _reent) _REENT_INIT((*ptr));
#else
- /*
- * Warning: THIS IS VERY DEPENDENT ON NEWLIB!!! WRITTEN FOR 1.7.0
- */
- ptr->_errno=0;
- ptr->_stdin=&ptr->__sf[0];
- ptr->_stdout=&ptr->__sf[1];
- ptr->_stderr=&ptr->__sf[2];
- ptr->_scanpoint=0;
- ptr->_asctime[0]=0;
- ptr->_next=1;
- ptr->__sdidinit=0;
+ /*
+ * 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;
#endif
- MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr);
+ set_newlib_extension( starting_task, ptr );
}
/*
@@ -164,38 +160,26 @@ libc_start_hook(rtems_tcb *current_task,
*/
#ifdef NEED_SETVBUF
-rtems_extension
-libc_begin_hook(rtems_tcb *current_task)
+rtems_extension libc_begin_hook(rtems_tcb *current_task)
{
setvbuf( stdout, NULL, _IOLBF, BUFSIZ );
}
#endif
-rtems_extension
-libc_switch_hook(rtems_tcb *current_task,
- rtems_tcb *heir_task)
+rtems_extension libc_switch_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *heir_task
+)
{
- rtems_unsigned32 impure_value;
-
- /* XXX We can't use rtems_task_set_note() here since SYSI task has a
- * tid of 0, which is treated specially (optimized, actually)
- * by rtems_task_set_note
- *
- * NOTE: The above comment is no longer true and we need to use
- * the extension data areas added about the same time.
- */
-
- /*
- * Don't touch the outgoing task if it has been deleted.
- */
-
- if ( !_States_Is_transient( current_task->current_state ) ) {
- impure_value = (rtems_unsigned32) _REENT;
- MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value);
- }
+ /*
+ * Don't touch the outgoing task if it has been deleted.
+ */
- _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD);
+ if ( !_States_Is_transient( current_task->current_state ) ) {
+ set_newlib_extension( current_task, _REENT );
+ }
+ _REENT = (struct _reent *) get_newlib_extension( heir_task );
}
/*
@@ -222,43 +206,40 @@ libc_switch_hook(rtems_tcb *current_task,
*
*
*/
-rtems_extension
-libc_delete_hook(rtems_tcb *current_task,
- rtems_tcb *deleted_task)
+
+rtems_extension libc_delete_hook(
+ rtems_tcb *current_task,
+ rtems_tcb *deleted_task
+)
{
- struct _reent *ptr;
-
- /*
- * The reentrancy structure was allocated by newlib using malloc()
- */
-
- if (current_task == deleted_task)
- {
- ptr = _REENT;
- }
- else
- {
- ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD);
- }
-
- /* if (ptr) */
- if (ptr && ptr != &libc_global_reent)
- {
- _wrapup_reent(ptr);
- _reclaim_reent(ptr);
- free(ptr);
- }
-
- MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0);
-
- /*
- * Require the switch back to another task to install its own
- */
-
- if (current_task == deleted_task)
- {
- _REENT = 0;
- }
+ struct _reent *ptr;
+
+ /*
+ * The reentrancy structure was allocated by newlib using malloc()
+ */
+
+ if (current_task == deleted_task) {
+ ptr = _REENT;
+ } else {
+ ptr = (struct _reent *) get_newlib_extension( deleted_task );
+ }
+
+ /* if (ptr) */
+ if (ptr && ptr != &libc_global_reent) {
+ _wrapup_reent(ptr);
+ _reclaim_reent(ptr);
+ free(ptr);
+ }
+
+ set_newlib_extension( deleted_task, NULL );
+
+ /*
+ * Require the switch back to another task to install its own
+ */
+
+ if ( current_task == deleted_task ) {
+ _REENT = 0;
+ }
}
/*
@@ -294,44 +275,33 @@ libc_delete_hook(rtems_tcb *current_task,
void
libc_init(int reentrant)
{
- rtems_extensions_table libc_extension;
- rtems_id extension_id;
- rtems_status_code rc;
+ rtems_extensions_table libc_extension;
+ rtems_status_code rc;
+ rtems_id extension_id;
- libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent));
- _REENT = &libc_global_reent;
+ libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent));
+ _REENT = &libc_global_reent;
- if (reentrant)
- {
- memset(&libc_extension, 0, sizeof(libc_extension));
+ if (reentrant) {
+ memset(&libc_extension, 0, sizeof(libc_extension));
- libc_extension.thread_create = libc_create_hook;
- libc_extension.thread_start = libc_start_hook;
+ libc_extension.thread_create = libc_create_hook;
+ libc_extension.thread_start = libc_start_hook;
#ifdef NEED_SETVBUF
- libc_extension.thread_begin = libc_begin_hook;
+ libc_extension.thread_begin = libc_begin_hook;
#endif
- libc_extension.thread_switch = libc_switch_hook;
- libc_extension.thread_delete = libc_delete_hook;
-
- rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
- &libc_extension, &extension_id);
- if (rc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred( rc );
-
- libc_reentrant = reentrant;
- }
-}
+ libc_extension.thread_switch = libc_switch_hook;
+ libc_extension.thread_delete = libc_delete_hook;
-#if 0
-/*
- * Routines required by the gnat runtime.
- */
+ rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
+ &libc_extension, &extension_id);
+ if (rc != RTEMS_SUCCESSFUL)
+ rtems_fatal_error_occurred( rc );
-int get_errno()
-{
- return errno;
+ libc_reentrant = reentrant;
+ extension_index = rtems_get_index( extension_id );
+ }
}
-#endif
/*
* Function: _exit
@@ -366,134 +336,24 @@ int get_errno()
#if !defined(RTEMS_UNIX) && !defined(_AM29K)
void _exit(int status)
{
- /*
- * We need to do the exit processing on the global reentrancy structure.
- * This has already been done on the per task reentrancy structure
- * associated with this task.
- */
-
- libc_wrapup();
- rtems_shutdown_executive(status);
+ /*
+ * We need to do the exit processing on the global reentrancy structure.
+ * This has already been done on the per task reentrancy structure
+ * associated with this task.
+ */
+
+ libc_wrapup();
+ rtems_shutdown_executive(status);
}
#else
void exit(int status)
{
- libc_wrapup();
- rtems_shutdown_executive(status);
-}
-#endif
-
-
-/*
- * These are directly supported (and completely correct) in the posix api.
- */
-
-pid_t __getpid(void)
-{
- return getpid();
-}
-
-#if !defined(RTEMS_POSIX_API)
-pid_t getpid(void)
-{
- return 0;
-}
-
-pid_t _getpid_r(
- struct _reent *ptr
-)
-{
- return getpid();
+ libc_wrapup();
+ rtems_shutdown_executive(status);
}
#endif
-#if !defined(RTEMS_POSIX_API)
-int kill( pid_t pid, int sig )
-{
- return 0;
-}
-int _kill_r( pid_t pid, int sig )
-{
- return 0;
-}
-#endif
-
-int __kill( pid_t pid, int sig )
-{
- return 0;
-}
-
-#if !defined(RTEMS_POSIX_API)
-unsigned int sleep(
- unsigned int seconds
-)
-{
- rtems_status_code status;
- rtems_interval ticks_per_second;
- rtems_interval ticks;
-
- status = rtems_clock_get(
- RTEMS_CLOCK_GET_TICKS_PER_SECOND,
- &ticks_per_second
- );
-
- ticks = seconds * ticks_per_second;
-
- status = rtems_task_wake_after( ticks );
-
- /*
- * Returns the "unslept" amount of time. In RTEMS signals are not
- * interruptable, so tasks really sleep all of the requested time.
- */
-
- return 0;
-}
-#endif
-
-
-/*
- * Newlib Interface Support
- *
- * Routines to Access Internal RTEMS Resources without violating
- * kernel visibility.
- *
- */
-
-void MY_task_set_note(
- Thread_Control *the_thread,
- unsigned32 notepad,
- unsigned32 note
-)
-{
- RTEMS_API_Control *api;
-
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
-
- if ( api )
- api->Notepads[ notepad ] = note;
-}
-
-
-unsigned32 MY_task_get_note(
- Thread_Control *the_thread,
- unsigned32 notepad
-)
-{
- RTEMS_API_Control *api;
-
- api = the_thread->API_Extensions[ THREAD_API_RTEMS ];
-
- return api->Notepads[ notepad ];
-}
-
-void *MY_CPU_Context_FP_start(
- void *base,
- unsigned32 offset
-)
-{
- return _CPU_Context_Fp_start( base, offset );
-}
#endif
diff --git a/c/src/lib/libc/no_posix.c b/c/src/lib/libc/no_posix.c
new file mode 100644
index 0000000000..9973230e44
--- /dev/null
+++ b/c/src/lib/libc/no_posix.c
@@ -0,0 +1,101 @@
+/*
+ * Marginal implementations of some POSIX API routines
+ * to be used when POSIX is disabled.
+ *
+ * + getpid
+ * + _getpid_r
+ * + kill
+ * + _kill_r
+ * + __kill
+ * + sleep
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.OARcorp.com/rtems/license.html.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+
+#include <unistd.h>
+
+/*
+ * These are directly supported (and completely correct) in the posix api.
+ */
+
+#if !defined(RTEMS_POSIX_API)
+pid_t getpid(void)
+{
+ return 0;
+}
+
+#if defined(RTEMS_NEWLIB)
+#include <sys/reent.h>
+
+pid_t _getpid_r(
+ struct _reent *ptr
+)
+{
+ return getpid();
+}
+#endif
+
+#endif
+
+#if !defined(RTEMS_POSIX_API)
+int kill( pid_t pid, int sig )
+{
+ return 0;
+}
+
+int _kill_r( pid_t pid, int sig )
+{
+ return 0;
+}
+#endif
+
+int __kill( pid_t pid, int sig )
+{
+ return 0;
+}
+
+
+/*
+ * 3.4.3 Delay Process Execution, P1003.1b-1993, p. 81
+ *
+ * $Id$
+ */
+
+#include <time.h>
+#include <unistd.h>
+
+#include <rtems.h>
+
+#if !defined(RTEMS_POSIX_API)
+unsigned int sleep(
+ unsigned int seconds
+)
+{
+ rtems_status_code status;
+ rtems_interval ticks_per_second;
+ rtems_interval ticks;
+
+ status = rtems_clock_get(
+ RTEMS_CLOCK_GET_TICKS_PER_SECOND,
+ &ticks_per_second
+ );
+
+ ticks = seconds * ticks_per_second;
+
+ status = rtems_task_wake_after( ticks );
+
+ /*
+ * Returns the "unslept" amount of time. In RTEMS signals are not
+ * interruptable, so tasks really sleep all of the requested time.
+ */
+
+ return 0;
+}
+#endif
+