source: rtems/cpukit/libcsupport/src/newlibc.c @ c3db01d0

4.104.114.84.95
Last change on this file since c3db01d0 was c3db01d0, checked in by Joel Sherrill <joel.sherrill@…>, on 05/09/07 at 18:27:26

2007-05-09 Joel Sherrill <joel.sherrill@…>

  • libcsupport/include/rtems/libcsupport.h, libcsupport/src/newlibc.c, sapi/Makefile.am, sapi/include/confdefs.h, sapi/src/exinit.c, score/Makefile.am, score/preinstall.am, score/include/rtems/score/userext.h, score/src/chain.c, score/src/userext.c: Switch to newlib reentrancy extension being installed in the initial set instead of using rtems_extension_create. While implementing this, noticed that user extensions and chain code had multiple functions in a single file which is not desirable in the SuperCore? and API portions of RTEMS, so split these into multiple files with one function per file. Also noticed that some of user extension code was inlined for no particular reason so moved that to C bodies. Split executive shutdown from initialization since not every application shuts down. Moved fini call to executive shutdown to be more symmetrical with where it is called at startup.
  • sapi/src/exshutdown.c, score/src/chainappend.c, score/src/chainextract.c, score/src/chainget.c, score/src/chaininsert.c, score/src/userextaddapiset.c, score/src/userextaddset.c, score/src/userextremoveset.c, score/src/userextthreadbegin.c, score/src/userextthreadcreate.c, score/src/userextthreaddelete.c, score/src/userextthreadrestart.c, score/src/userextthreadstart.c, score/src/userextthreadswitch.c: New files.
  • score/inline/rtems/score/userext.inl: Removed.
  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[ac7d5ef0]1/*
[07a3253d]2 *  Implementation of hooks for the CYGNUS newlib libc
3 *  These hooks set things up so that:
4 *       + '_REENT' is switched at task switch time.
5 *
[ac7d5ef0]6 *  COPYRIGHT (c) 1994 by Division Incorporated
7 *
[98e4ebf5]8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
[0eae36c7]10 *  http://www.rtems.com/license/LICENSE.
[ac7d5ef0]11 *
[3235ad9]12 *  $Id$
[ac7d5ef0]13 *
14 */
15
[9c49db4]16#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
[1a8fde6c]20#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
[ac7d5ef0]21#include <rtems.h>
[dcec5a4]22
23#if defined(RTEMS_NEWLIB)
[3ba74c73]24#include <rtems/libcsupport.h>
[07e9194e]25
26/* Since we compile with strict ANSI we need to undef it to get
27 * prototypes for extensions
28 */
29#undef __STRICT_ANSI__
30
[ac7d5ef0]31#include <stdlib.h>             /* for free() */
32#include <string.h>             /* for memset() */
33
34#include <sys/reent.h>          /* for extern of _REENT (aka _impure_ptr) */
[8d7a1d76]35#include <errno.h>
[ac7d5ef0]36
[1f94ed6b]37/*
38 *  NOTE:
39 *        There is some problem with doing this on the hpux version
40 *        of the UNIX simulator (symptom is printf core dumps), so
41 *        we just don't for now.
42 *        Not sure if this is a problem with hpux, newlib, or something else.
43 */
[50f32b11]44
[1f94ed6b]45#if defined(RTEMS_UNIX) && !defined(hpux)
46#define NEED_SETVBUF
47#endif
[50f32b11]48
[1f94ed6b]49#include <stdio.h>
[eaa442fc]50
[c9a4da01]51int _fwalk(struct _reent *ptr, int (*function) (FILE *) );
52
[c3db01d0]53struct _reent    libc_global_reent
54    __ATTRIBUTE_IMPURE_PTR__ = _REENT_INIT(libc_global_reent);
[ac7d5ef0]55
[50f32b11]56/*
[6cff0f8]57 * reent struct allocation moved here from libc_start_hook() to avoid
58 * mutual exclusion problems when memory is allocated from the start hook.
59 *
60 * Memory is also now allocated from the workspace rather than the heap.
61 *  -- ptorre 9/30/03
62 */
[7edb9281]63rtems_boolean libc_create_hook(
64  rtems_tcb *current_task,
65  rtems_tcb *creating_task
66)
[ac7d5ef0]67{
[7edb9281]68  struct _reent *ptr;
[ac7d5ef0]69
[7edb9281]70  /*  NOTE: The RTEMS malloc is reentrant without a reent ptr since
71   *        it is based on the Classic API Region Manager.
72   */
[ac7d5ef0]73
[c3db01d0]74  #define REENT_MALLOCED 0
75  #if REENT_MALLOCED
76    ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
77  #else
78    /* It is OK to allocate from the workspace because these
79     * hooks run with thread dispatching disabled.
80     */
81    ptr = (struct _reent *) _Workspace_Allocate(sizeof(struct _reent));
82  #endif
[ac7d5ef0]83
[c3db01d0]84  if (ptr) {
[ac7d5ef0]85
[c3db01d0]86      _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */
[07e9194e]87      creating_task->libc_reent = ptr;
88      return TRUE;
89  }
[6cff0f8]90  else
[c3db01d0]91    return FALSE;
[ac7d5ef0]92}
93
[eaa442fc]94/*
[8cbbe312]95 * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
[eaa442fc]96 */
[50f32b11]97
[8b2ecf85]98#ifdef NEED_SETVBUF
[7edb9281]99rtems_extension libc_begin_hook(rtems_tcb *current_task)
[eaa442fc]100{
101  setvbuf( stdout, NULL, _IOLBF, BUFSIZ );
102}
103#endif
104
[ac7d5ef0]105/*
[c3db01d0]106 *  Called when a task is deleted.
107 *  Must restore the new lib reentrancy state for the new current
108 *  task.
[ac7d5ef0]109 *
110 */
[7edb9281]111
[c9a4da01]112int newlib_free_buffers(
113  FILE *fp
114)
115{
116  switch ( fileno(fp) ) {
117    case 0:
118    case 1:
119    case 2:
120      if (fp->_flags & __SMBF) {
121        free( fp->_bf._base );
122        fp->_flags &= ~__SMBF;
123        fp->_bf._base = fp->_p = (unsigned char *) NULL;
124      }
125      break;
126    default:
127     fclose(fp);
128  }
129  return 0;
130}
131
[7edb9281]132rtems_extension libc_delete_hook(
133  rtems_tcb *current_task,
134  rtems_tcb *deleted_task
135)
[ac7d5ef0]136{
[7edb9281]137  struct _reent *ptr;
138
139  /*
140   * The reentrancy structure was allocated by newlib using malloc()
141   */
142
143  if (current_task == deleted_task) {
144    ptr = _REENT;
145  } else {
[7bd88b54]146    ptr = deleted_task->libc_reent;
[7edb9281]147  }
148
149  if (ptr && ptr != &libc_global_reent) {
[c9a4da01]150/*
[7edb9281]151    _wrapup_reent(ptr);
152    _reclaim_reent(ptr);
[c9a4da01]153*/
154    /*
155     *  Just in case there are some buffers lying around.
[50f32b11]156     */
[c9a4da01]157    _fwalk(ptr, newlib_free_buffers);
[6cff0f8]158#if REENT_MALLOCED
[7edb9281]159    free(ptr);
[6cff0f8]160#else
[07e9194e]161    _Workspace_Free(ptr);
[6cff0f8]162#endif
[7edb9281]163  }
164
[c0d4abe6]165  deleted_task->libc_reent = NULL;
[7edb9281]166
167  /*
168   * Require the switch back to another task to install its own
169   */
170
171  if ( current_task == deleted_task ) {
172    _REENT = 0;
173  }
[ac7d5ef0]174}
175
176/*
[c3db01d0]177 *  Init libc for CYGNUS newlib
178 *
179 *  Set up _REENT to use our global libc_global_reent.
180 *  (newlib provides a global of its own, but we prefer our own name for it)
[ac7d5ef0]181 *
[c3db01d0]182 *  If reentrancy is desired (which it should be), then
183 *  we install the task extension hooks to maintain the
184 *  newlib reentrancy global variable _REENT on task
185 *  create, delete, switch, exit, etc.
[ac7d5ef0]186 *
187 */
188
[c3db01d0]189
[ac7d5ef0]190void
191libc_init(int reentrant)
192{
[7edb9281]193  _REENT = &libc_global_reent;
[ac7d5ef0]194
[c3db01d0]195  _Thread_Set_libc_reent (&_REENT);
[8d7a1d76]196}
[ac7d5ef0]197
198#endif
Note: See TracBrowser for help on using the repository browser.