source: rtems/cpukit/libcsupport/src/newlibc.c @ 7e191133

4.104.114.95
Last change on this file since 7e191133 was 7e191133, checked in by Ralf Corsepius <ralf.corsepius@…>, on 08/25/08 at 11:19:33

Stop using old-style function-definitions.

  • Property mode set to 100644
File size: 3.7 KB
Line 
1/*
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 *
6 *  COPYRIGHT (c) 1994 by Division Incorporated
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 *
14 */
15
16#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
21#include <rtems.h>
22
23#if defined(RTEMS_NEWLIB)
24#include <rtems/libcsupport.h>
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
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) */
35#include <errno.h>
36
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 */
44
45#if defined(RTEMS_UNIX) && !defined(hpux)
46#define NEED_SETVBUF
47#endif
48
49#include <stdio.h>
50
51int _fwalk(struct _reent *ptr, int (*function) (FILE *) );
52
53extern struct _reent    libc_global_reent __ATTRIBUTE_IMPURE_PTR__;
54
55/*
56 * reent struct allocation moved here from libc_start_hook() to avoid
57 * mutual exclusion problems when memory is allocated from the start hook.
58 *
59 * Memory is also now allocated from the workspace rather than the heap.
60 *  -- ptorre 9/30/03
61 */
62bool libc_create_hook(
63  rtems_tcb *current_task,
64  rtems_tcb *creating_task
65)
66{
67  struct _reent *ptr;
68
69  /*  NOTE: The RTEMS malloc is reentrant without a reent ptr since
70   *        it is based on the Classic API Region Manager.
71   */
72
73  #define REENT_MALLOCED 0
74  #if REENT_MALLOCED
75    ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
76  #else
77    /* It is OK to allocate from the workspace because these
78     * hooks run with thread dispatching disabled.
79     */
80    ptr = (struct _reent *) _Workspace_Allocate(sizeof(struct _reent));
81  #endif
82
83  if (ptr) {
84
85      _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */
86      creating_task->libc_reent = ptr;
87      return TRUE;
88  }
89  else
90    return FALSE;
91}
92
93/*
94 * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
95 */
96
97#ifdef NEED_SETVBUF
98rtems_extension libc_begin_hook(rtems_tcb *current_task)
99{
100  setvbuf( stdout, NULL, _IOLBF, BUFSIZ );
101}
102#endif
103
104/*
105 *  Called when a task is deleted.
106 *  Must restore the new lib reentrancy state for the new current
107 *  task.
108 *
109 */
110
111int newlib_free_buffers(
112  FILE *fp
113)
114{
115  switch ( fileno(fp) ) {
116    case 0:
117    case 1:
118    case 2:
119      if (fp->_flags & __SMBF) {
120        free( fp->_bf._base );
121        fp->_flags &= ~__SMBF;
122        fp->_bf._base = fp->_p = (unsigned char *) NULL;
123      }
124      break;
125    default:
126     fclose(fp);
127  }
128  return 0;
129}
130
131rtems_extension libc_delete_hook(
132  rtems_tcb *current_task,
133  rtems_tcb *deleted_task
134)
135{
136  struct _reent *ptr;
137
138  /*
139   * The reentrancy structure was allocated by newlib using malloc()
140   */
141
142  if (current_task == deleted_task) {
143    ptr = _REENT;
144  } else {
145    ptr = deleted_task->libc_reent;
146  }
147
148  if (ptr && ptr != &libc_global_reent) {
149/*
150    _wrapup_reent(ptr);
151    _reclaim_reent(ptr);
152*/
153    /*
154     *  Just in case there are some buffers lying around.
155     */
156    _fwalk(ptr, newlib_free_buffers);
157#if REENT_MALLOCED
158    free(ptr);
159#else
160    _Workspace_Free(ptr);
161#endif
162  }
163
164  deleted_task->libc_reent = NULL;
165
166  /*
167   * Require the switch back to another task to install its own
168   */
169
170  if ( current_task == deleted_task ) {
171    _REENT = 0;
172  }
173}
174
175#endif
Note: See TracBrowser for help on using the repository browser.