source: rtems/cpukit/libcsupport/src/newlibc_reent.c @ ad8010c

4.11
Last change on this file since ad8010c was ad8010c, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 24, 2013 at 7:21:09 AM

libcsupport: Use copyright notice of original file

  • Property mode set to 100644
File size: 3.6 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Newlib Support
5 *  @ingroup libcsupport
6 */
7
8/*
9 *  COPYRIGHT (c) 1994 by Division Incorporated
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.com/license/LICENSE.
14 *
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
22#include <rtems.h>
23
24#if defined(RTEMS_NEWLIB)
25#include <rtems/libcsupport.h>
26
27/* Since we compile with strict ANSI we need to undef it to get
28 * prototypes for extensions
29 */
30#undef __STRICT_ANSI__
31
32#include <stdlib.h>             /* for free() */
33#include <string.h>             /* for memset() */
34
35#include <sys/reent.h>          /* for extern of _REENT (aka _impure_ptr) */
36#include <errno.h>
37
38/*
39 *  NOTE:
40 *        There is some problem with doing this on the hpux version
41 *        of the UNIX simulator (symptom is printf core dumps), so
42 *        we just don't for now.
43 *        Not sure if this is a problem with hpux, newlib, or something else.
44 */
45
46#include <stdio.h>
47
48int _fwalk(struct _reent *ptr, int (*function) (FILE *) );
49
50extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
51/*
52 * reent struct allocation moved here from libc_start_hook() to avoid
53 * mutual exclusion problems when memory is allocated from the start hook.
54 *
55 * Memory is also now allocated from the workspace rather than the heap.
56 *  -- ptorre 9/30/03
57 */
58bool newlib_create_hook(
59  rtems_tcb *current_task __attribute__((unused)),
60  rtems_tcb *creating_task
61)
62{
63  struct _reent *ptr;
64
65  if (_Thread_libc_reent == 0)
66  {
67    _REENT = _global_impure_ptr;
68
69    _Thread_Set_libc_reent (&_REENT);
70  }
71
72  /*  NOTE: The RTEMS malloc is reentrant without a reent ptr since
73   *        it is based on the Classic API Region Manager.
74   */
75
76  #define REENT_MALLOCED 0
77  #if REENT_MALLOCED
78    ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
79  #else
80    /* It is OK to allocate from the workspace because these
81     * hooks run with thread dispatching disabled.
82     */
83    ptr = (struct _reent *) _Workspace_Allocate(sizeof(struct _reent));
84  #endif
85
86  if (ptr) {
87    _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */
88    creating_task->libc_reent = ptr;
89    return TRUE;
90  }
91
92  return FALSE;
93}
94
95/*
96 * Called for all user TASKS (system tasks are MPCI Receive Server and IDLE)
97 */
98
99#ifdef NEED_SETVBUF
100void newlib_begin_hook(rtems_tcb *current_task)
101{
102  setvbuf( stdout, NULL, _IOLBF, BUFSIZ );
103}
104#endif
105
106/*
107 *  Called when a task is deleted.
108 *  Must restore the new lib reentrancy state for the new current
109 *  task.
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
131void newlib_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 != _global_impure_ptr) {
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.