source: rtems/c/src/exec/libcsupport/src/newlibc.c @ 4b61ebfb

4.104.114.84.95
Last change on this file since 4b61ebfb was 3a4ae6c, checked in by Joel Sherrill <joel.sherrill@…>, on 09/11/95 at 19:35:39

The word "RTEMS" almost completely removed from the core.

Configuration Table Template file added and all tests
modified to use this. All gvar.h and conftbl.h files
removed from test directories.

Configuration parameter maximum_devices added.

Core semaphore and mutex handlers added and RTEMS API Semaphore
Manager updated to reflect this.

Initialization sequence changed to invoke API specific initialization
routines. Initialization tasks table now owned by RTEMS Tasks Manager.

Added user extension for post-switch.

Utilized user extensions to implement API specific functionality
like signal dispatching.

Added extensions to the System Initialization Thread so that an
API can register a function to be invoked while the system
is being initialized. These are largely equivalent to the
pre-driver and post-driver hooks.

Added the Modules file oar-go32_p5, modified oar-go32, and modified
the file make/custom/go32.cfg to look at an environment varable which
determines what CPU model is being used.

All BSPs updated to reflect named devices and clock driver's IOCTL
used by the Shared Memory Driver. Also merged clock isr into
main file and removed ckisr.c where possible.

Updated spsize to reflect new and moved variables.

Makefiles for the executive source and include files updated to show
break down of files into Core, RTEMS API, and Neither.

Header and inline files installed into subdirectory based on whether
logically in the Core or a part of the RTEMS API.

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 *      @(#)newlibc.c   1.9 - 95/05/16
3 *     
4 */
5
6#if defined(RTEMS_NEWLIB)
7
8/*
9 *  File:       newlibc.c,v
10 *  Project:    PixelFlow
11 *  Created:    94/12/7
12 *  Revision:   1.2
13 *  Last Mod:   1995/05/09 20:24:37
14 *
15 *  COPYRIGHT (c) 1994 by Division Incorporated
16 *
17 *  To anyone who acknowledges that this file is provided "AS IS"
18 *  without any express or implied warranty:
19 *      permission to use, copy, modify, and distribute this file
20 *      for any purpose is hereby granted without fee, provided that
21 *      the above copyright notice and this notice appears in all
22 *      copies, and that the name of Division Incorporated not be
23 *      used in advertising or publicity pertaining to distribution
24 *      of the software without specific, written prior permission.
25 *      Division Incorporated makes no representations about the
26 *      suitability of this software for any purpose.
27 *
28 *  Description:
29 *      Implementation of hooks for the CYGNUS newlib libc
30 *      These hooks set things up so that:
31 *              '_REENT' is switched at task switch time.
32 *
33 *
34 *  TODO:
35 *
36 *  NOTE:
37 *
38 *  $Id$
39 *
40 */
41
42#include <rtems.h>
43#include <libcsupport.h>
44#include <stdlib.h>             /* for free() */
45#include <string.h>             /* for memset() */
46
47#include <sys/reent.h>          /* for extern of _REENT (aka _impure_ptr) */
48
49#include "internal.h"
50
51#define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST
52
53
54int              libc_reentrant;        /* do we think we are reentrant? */
55struct _reent    libc_global_reent = _REENT_INIT(libc_global_reent);;
56
57/*
58 * CYGNUS newlib routine that does atexit() processing and flushes
59 *      stdio streams
60 *      undocumented
61 */
62
63extern void _wrapup_reent(struct _reent *);
64extern void _reclaim_reent(struct _reent *);
65
66void
67libc_wrapup(void)
68{
69    _wrapup_reent(0);
70    if (_REENT != &libc_global_reent)
71    {
72        _wrapup_reent(&libc_global_reent);
73#if 0
74        /* don't reclaim this one, just in case we do printfs */
75        /* on our way out to ROM */
76        _reclaim_reent(&libc_global_reent);
77#endif
78        _REENT = &libc_global_reent;
79    }
80}
81
82
83rtems_boolean
84libc_create_hook(rtems_tcb *current_task,
85                 rtems_tcb *creating_task)
86{
87    MY_task_set_note(creating_task, LIBC_NOTEPAD, 0);
88    return TRUE;
89}
90
91/*
92 * Called for all user TASKS (system tasks are SYSI and IDLE)
93 */
94
95rtems_extension
96libc_start_hook(rtems_tcb *current_task,
97                rtems_tcb *starting_task)
98{
99    struct _reent *ptr;
100
101    /* NOTE: our malloc is reentrant without a reent ptr since
102     *  it is based on region manager
103     */
104
105    ptr = (struct _reent *) malloc(sizeof(struct _reent));
106
107    /* GCC extension: structure constants */
108    *ptr = (struct _reent) _REENT_INIT((*ptr));
109
110    MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr);
111}
112
113rtems_extension
114libc_switch_hook(rtems_tcb *current_task,
115                 rtems_tcb *heir_task)
116{
117    rtems_unsigned32 impure_value;
118
119    /* XXX We can't use rtems_task_set_note() here since SYSI task has a
120     * tid of 0, which is treated specially (optimized, actually)
121     * by rtems_task_set_note
122     */
123
124    impure_value = (rtems_unsigned32) _REENT;
125    MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value);
126
127    _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD);
128
129}
130
131/*
132 *  Function:   libc_delete_hook
133 *  Created:    94/12/10
134 *
135 *  Description:
136 *      Called when a task is deleted.
137 *      Must restore the new lib reentrancy state for the new current
138 *      task.
139 *
140 *  Parameters:
141 *
142 *
143 *  Returns:
144 *
145 *
146 *  Side Effects:
147 *
148 *  Notes:
149 *
150 *
151 *  Deficiencies/ToDo:
152 *
153 *
154 */
155rtems_extension
156libc_delete_hook(rtems_tcb *current_task,
157                 rtems_tcb *deleted_task)
158{
159    struct _reent *ptr;
160
161    /*
162     * The reentrancy structure was allocated by newlib using malloc()
163     */
164
165    if (current_task == deleted_task)
166    {
167        ptr = _REENT;
168    }
169    else
170    {
171        ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD);
172    }
173
174    if (ptr)
175    {
176        _wrapup_reent(ptr);
177        _reclaim_reent(ptr);
178    }
179
180    MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0);
181
182    /*
183     * Require the switch back to another task to install its own
184     */
185
186    if (current_task == deleted_task)
187    {
188        _REENT = 0;
189    }
190}
191
192/*
193 *  Function:   libc_init
194 *  Created:    94/12/10
195 *
196 *  Description:
197 *      Init libc for CYGNUS newlib
198 *      Set up _REENT to use our global libc_global_reent.
199 *      (newlib provides a global of its own, but we prefer our
200 *      own name for it)
201 *
202 *      If reentrancy is desired (which it should be), then
203 *      we install the task extension hooks to maintain the
204 *      newlib reentrancy global variable _REENT on task
205 *      create, delete, switch, exit, etc.
206 *
207 *  Parameters:
208 *      reentrant               non-zero if reentrant library desired.
209 *
210 *  Returns:
211 *
212 *  Side Effects:
213 *      installs libc extensions if reentrant.
214 *
215 *  Notes:
216 *
217 *
218 *  Deficiencies/ToDo:
219 *
220 */
221
222void
223libc_init(int reentrant)
224{
225    rtems_extensions_table  libc_extension;
226    rtems_id                extension_id;
227    rtems_status_code       rc;
228
229    _REENT = &libc_global_reent;
230
231    if (reentrant)
232    {
233        memset(&libc_extension, 0, sizeof(libc_extension));
234
235        libc_extension.thread_create  = libc_create_hook;
236        libc_extension.thread_start   = libc_start_hook;
237        libc_extension.thread_switch  = libc_switch_hook;
238        libc_extension.thread_delete  = libc_delete_hook;
239
240        rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'),
241                              &libc_extension, &extension_id);
242        if (rc != RTEMS_SUCCESSFUL)
243            rtems_fatal_error_occurred(rc);
244
245        libc_reentrant = reentrant;
246    }
247}
248
249
250void
251exit(int status)
252{
253    libc_wrapup();
254    rtems_shutdown_executive(status);
255}
256
257
258/*
259 *  Function:   _exit
260 *  Created:    94/12/10
261 *
262 *  Description:
263 *      Called from exit() after it does atexit() processing and stdio fflush's
264 *
265 *      called from bottom of exit() to really delete the task.
266 *      If we are using reentrant libc, then let the delete extension
267 *      do all the work, otherwise if a shutdown is in progress,
268 *      then just do it.
269 *
270 *  Parameters:
271 *      exit status
272 *
273 *  Returns:
274 *      does not return
275 *
276 *  Side Effects:
277 *
278 *  Notes:
279 *
280 *
281 *  Deficiencies/ToDo:
282 *
283 *
284 */
285
286#if !defined(RTEMS_UNIX) && !defined(__GO32__)
287void _exit(int status)
288{
289    rtems_shutdown_executive(status);
290}
291#endif
292
293#endif
Note: See TracBrowser for help on using the repository browser.