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

4.11
Last change on this file since bcd0ea64 was bcd0ea64, checked in by Alex Ivanov <alexivanov97@…>, on Dec 9, 2012 at 10:55:17 PM

libcsupport: Doxygen enhancement task #2

http://www.google-melange.com/gci/task/view/google/gci2012/8017203

  • 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 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.com/license/LICENSE.
12 *
13 */
14
15#if HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
20#include <rtems.h>
21
22#if defined(RTEMS_NEWLIB)
23#include <rtems/libcsupport.h>
24
25/* Since we compile with strict ANSI we need to undef it to get
26 * prototypes for extensions
27 */
28#undef __STRICT_ANSI__
29
30#include <stdlib.h>             /* for free() */
31#include <string.h>             /* for memset() */
32
33#include <sys/reent.h>          /* for extern of _REENT (aka _impure_ptr) */
34#include <errno.h>
35
36/*
37 *  NOTE:
38 *        There is some problem with doing this on the hpux version
39 *        of the UNIX simulator (symptom is printf core dumps), so
40 *        we just don't for now.
41 *        Not sure if this is a problem with hpux, newlib, or something else.
42 */
43
44#include <stdio.h>
45
46int _fwalk(struct _reent *ptr, int (*function) (FILE *) );
47
48extern struct _reent * const _global_impure_ptr __ATTRIBUTE_IMPURE_PTR__;
49/*
50 * reent struct allocation moved here from libc_start_hook() to avoid
51 * mutual exclusion problems when memory is allocated from the start hook.
52 *
53 * Memory is also now allocated from the workspace rather than the heap.
54 *  -- ptorre 9/30/03
55 */
56bool newlib_create_hook(
57  rtems_tcb *current_task __attribute__((unused)),
58  rtems_tcb *creating_task
59)
60{
61  struct _reent *ptr;
62
63  if (_Thread_libc_reent == 0)
64  {
65    _REENT = _global_impure_ptr;
66
67    _Thread_Set_libc_reent (&_REENT);
68  }
69
70  /*  NOTE: The RTEMS malloc is reentrant without a reent ptr since
71   *        it is based on the Classic API Region Manager.
72   */
73
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
83
84  if (ptr) {
85    _REENT_INIT_PTR((ptr)); /* GCC extension: structure constants */
86    creating_task->libc_reent = ptr;
87    return TRUE;
88  }
89
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
98void newlib_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 */
109int newlib_free_buffers(
110  FILE *fp
111)
112{
113  switch ( fileno(fp) ) {
114    case 0:
115    case 1:
116    case 2:
117      if (fp->_flags & __SMBF) {
118        free( fp->_bf._base );
119        fp->_flags &= ~__SMBF;
120        fp->_bf._base = fp->_p = (unsigned char *) NULL;
121      }
122      break;
123    default:
124     fclose(fp);
125  }
126  return 0;
127}
128
129void newlib_delete_hook(
130  rtems_tcb *current_task,
131  rtems_tcb *deleted_task
132)
133{
134  struct _reent *ptr;
135
136  /*
137   * The reentrancy structure was allocated by newlib using malloc()
138   */
139
140  if (current_task == deleted_task) {
141    ptr = _REENT;
142  } else {
143    ptr = deleted_task->libc_reent;
144  }
145
146  if (ptr && ptr != _global_impure_ptr) {
147/*
148    _wrapup_reent(ptr);
149    _reclaim_reent(ptr);
150*/
151    /*
152     *  Just in case there are some buffers lying around.
153     */
154    _fwalk(ptr, newlib_free_buffers);
155#if REENT_MALLOCED
156    free(ptr);
157#else
158    _Workspace_Free(ptr);
159#endif
160  }
161
162  deleted_task->libc_reent = NULL;
163
164  /*
165   * Require the switch back to another task to install its own
166   */
167
168  if ( current_task == deleted_task ) {
169    _REENT = 0;
170  }
171}
172
173#endif
Note: See TracBrowser for help on using the repository browser.