Changeset 7edb9281 in rtems
- Timestamp:
- 11/05/99 19:02:03 (24 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- 1c55d2e8
- Parents:
- 0fab6dde
- Files:
-
- 6 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/libcsupport/src/newlibc.c
r0fab6dde r7edb9281 41 41 #endif 42 42 43 static int extension_index; 44 43 45 /* 44 46 * Private routines 45 47 */ 46 48 47 void MY_task_set_note( 48 rtems_tcb *tcb, 49 rtems_unsigned32 notepad, 50 rtems_unsigned32 note 51 ); 52 53 rtems_unsigned32 MY_task_get_note( 54 rtems_tcb *tcb, 55 rtems_unsigned32 notepad 56 ); 57 58 59 #define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST 60 49 #define set_newlib_extension( _the_thread, _value ) \ 50 (_the_thread)->extensions[ extension_index ] = (_value); 51 52 #define get_newlib_extension( _the_thread ) \ 53 (_the_thread)->extensions[ extension_index ] 61 54 62 55 int libc_reentrant; /* do we think we are reentrant? */ … … 74 67 #include <stdio.h> 75 68 76 void 77 libc_wrapup(void) 78 { 79 /* 80 * In case RTEMS is already down, don't do this. It could be 81 * dangerous. 82 */ 83 84 if (!_System_state_Is_up(_System_state_Get())) 85 return; 86 87 /* 88 * This was already done if the user called exit() directly . 89 90 _wrapup_reent(0); 91 */ 92 if (_REENT != &libc_global_reent) 93 { 94 _wrapup_reent(&libc_global_reent); 69 void libc_wrapup(void) 70 { 71 /* 72 * In case RTEMS is already down, don't do this. It could be 73 * dangerous. 74 */ 75 76 if (!_System_state_Is_up(_System_state_Get())) 77 return; 78 79 /* 80 * This was already done if the user called exit() directly . 81 _wrapup_reent(0); 82 */ 83 84 if (_REENT != &libc_global_reent) { 85 _wrapup_reent(&libc_global_reent); 95 86 #if 0 96 /* don't reclaim this one, just in case we do printfs */ 97 /* on our way out to ROM */ 98 _reclaim_reent(&libc_global_reent); 99 #endif 100 _REENT = &libc_global_reent; 101 } 102 103 /* 104 * Try to drain output buffers. 105 * 106 * Should this be changed to do *all* file streams? 107 * _fwalk (_REENT, fclose); 108 */ 109 fclose (stdin); 110 fclose (stdout); 111 fclose (stderr); 112 } 113 114 115 rtems_boolean 116 libc_create_hook(rtems_tcb *current_task, 117 rtems_tcb *creating_task) 118 { 119 MY_task_set_note(creating_task, LIBC_NOTEPAD, 0); 120 return TRUE; 87 /* Don't reclaim this one, just in case we do printfs 88 * on the way out to ROM. 89 */ 90 _reclaim_reent(&libc_global_reent); 91 #endif 92 _REENT = &libc_global_reent; 93 } 94 95 /* 96 * Try to drain output buffers. 97 * 98 * Should this be changed to do *all* file streams? 99 * _fwalk (_REENT, fclose); 100 */ 101 102 fclose (stdin); 103 fclose (stdout); 104 fclose (stderr); 105 } 106 107 108 rtems_boolean libc_create_hook( 109 rtems_tcb *current_task, 110 rtems_tcb *creating_task 111 ) 112 { 113 set_newlib_extension( creating_task, NULL ); 114 return TRUE; 121 115 } 122 116 … … 125 119 */ 126 120 127 rtems_extension 128 libc_start_hook(rtems_tcb *current_task, 129 rtems_tcb *starting_task) 130 { 131 struct _reent *ptr; 132 133 /* NOTE: our malloc is reentrant without a reent ptr since 134 * it is based on region manager 135 */ 136 137 ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); 138 139 if (!ptr) 140 rtems_fatal_error_occurred(RTEMS_NO_MEMORY); 121 rtems_extension libc_start_hook( 122 rtems_tcb *current_task, 123 rtems_tcb *starting_task 124 ) 125 { 126 struct _reent *ptr; 127 128 /* NOTE: The RTEMS malloc is reentrant without a reent ptr since 129 * it is based on the Classic API Region Manager. 130 */ 131 132 ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); 133 134 if (!ptr) 135 rtems_fatal_error_occurred(RTEMS_NO_MEMORY); 141 136 142 137 #ifdef __GNUC__ 143 144 138 /* GCC extension: structure constants */ 139 *ptr = (struct _reent) _REENT_INIT((*ptr)); 145 140 #else 146 /* 147 * Warning: THIS IS VERY DEPENDENT ON NEWLIB!!! WRITTEN FOR 1.7.0 148 */ 149 ptr->_errno=0; 150 ptr->_stdin=&ptr->__sf[0]; 151 ptr->_stdout=&ptr->__sf[1]; 152 ptr->_stderr=&ptr->__sf[2]; 153 ptr->_scanpoint=0; 154 ptr->_asctime[0]=0; 155 ptr->_next=1; 156 ptr->__sdidinit=0; 157 #endif 158 159 MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr); 141 /* 142 * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!! 143 * Last visual check was against newlib 1.8.2 but last known 144 * use was against 1.7.0. This is basically an exansion of 145 * REENT_INIT() in <sys/reent.h>. 146 * NOTE: calloc() takes care of zeroing fields. 147 */ 148 ptr->_stdin = &ptr->__sf[0]; 149 ptr->_stdout = &ptr->__sf[1]; 150 ptr->_stderr = &ptr->__sf[2]; 151 ptr->_current_locale = "C"; 152 ptr->_new._reent._rand_next = 1; 153 #endif 154 155 set_newlib_extension( starting_task, ptr ); 160 156 } 161 157 … … 165 161 166 162 #ifdef NEED_SETVBUF 167 rtems_extension 168 libc_begin_hook(rtems_tcb *current_task) 163 rtems_extension libc_begin_hook(rtems_tcb *current_task) 169 164 { 170 165 setvbuf( stdout, NULL, _IOLBF, BUFSIZ ); … … 172 167 #endif 173 168 174 rtems_extension 175 libc_switch_hook(rtems_tcb *current_task, 176 rtems_tcb *heir_task) 177 { 178 rtems_unsigned32 impure_value; 179 180 /* XXX We can't use rtems_task_set_note() here since SYSI task has a 181 * tid of 0, which is treated specially (optimized, actually) 182 * by rtems_task_set_note 183 * 184 * NOTE: The above comment is no longer true and we need to use 185 * the extension data areas added about the same time. 186 */ 187 188 /* 189 * Don't touch the outgoing task if it has been deleted. 190 */ 191 192 if ( !_States_Is_transient( current_task->current_state ) ) { 193 impure_value = (rtems_unsigned32) _REENT; 194 MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value); 195 } 196 197 _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD); 198 169 rtems_extension libc_switch_hook( 170 rtems_tcb *current_task, 171 rtems_tcb *heir_task 172 ) 173 { 174 /* 175 * Don't touch the outgoing task if it has been deleted. 176 */ 177 178 if ( !_States_Is_transient( current_task->current_state ) ) { 179 set_newlib_extension( current_task, _REENT ); 180 } 181 182 _REENT = (struct _reent *) get_newlib_extension( heir_task ); 199 183 } 200 184 … … 223 207 * 224 208 */ 225 rtems_extension 226 libc_delete_hook(rtems_tcb *current_task, 227 rtems_tcb *deleted_task) 228 { 229 struct _reent *ptr; 230 231 /* 232 * The reentrancy structure was allocated by newlib using malloc() 233 */ 234 235 if (current_task == deleted_task) 236 { 237 ptr = _REENT; 238 } 239 else 240 { 241 ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD); 242 } 243 244 /* if (ptr) */ 245 if (ptr && ptr != &libc_global_reent) 246 { 247 _wrapup_reent(ptr); 248 _reclaim_reent(ptr); 249 free(ptr); 250 } 251 252 MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0); 253 254 /* 255 * Require the switch back to another task to install its own 256 */ 257 258 if (current_task == deleted_task) 259 { 260 _REENT = 0; 261 } 209 210 rtems_extension libc_delete_hook( 211 rtems_tcb *current_task, 212 rtems_tcb *deleted_task 213 ) 214 { 215 struct _reent *ptr; 216 217 /* 218 * The reentrancy structure was allocated by newlib using malloc() 219 */ 220 221 if (current_task == deleted_task) { 222 ptr = _REENT; 223 } else { 224 ptr = (struct _reent *) get_newlib_extension( deleted_task ); 225 } 226 227 /* if (ptr) */ 228 if (ptr && ptr != &libc_global_reent) { 229 _wrapup_reent(ptr); 230 _reclaim_reent(ptr); 231 free(ptr); 232 } 233 234 set_newlib_extension( deleted_task, NULL ); 235 236 /* 237 * Require the switch back to another task to install its own 238 */ 239 240 if ( current_task == deleted_task ) { 241 _REENT = 0; 242 } 262 243 } 263 244 … … 295 276 libc_init(int reentrant) 296 277 { 297 rtems_extensions_table libc_extension; 298 rtems_id extension_id; 299 rtems_status_code rc; 300 301 libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent)); 302 _REENT = &libc_global_reent; 303 304 if (reentrant) 305 { 306 memset(&libc_extension, 0, sizeof(libc_extension)); 307 308 libc_extension.thread_create = libc_create_hook; 309 libc_extension.thread_start = libc_start_hook; 278 rtems_extensions_table libc_extension; 279 rtems_status_code rc; 280 rtems_id extension_id; 281 282 libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent)); 283 _REENT = &libc_global_reent; 284 285 if (reentrant) { 286 memset(&libc_extension, 0, sizeof(libc_extension)); 287 288 libc_extension.thread_create = libc_create_hook; 289 libc_extension.thread_start = libc_start_hook; 310 290 #ifdef NEED_SETVBUF 311 libc_extension.thread_begin = libc_begin_hook; 312 #endif 313 libc_extension.thread_switch = libc_switch_hook; 314 libc_extension.thread_delete = libc_delete_hook; 315 316 rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), 317 &libc_extension, &extension_id); 318 if (rc != RTEMS_SUCCESSFUL) 319 rtems_fatal_error_occurred( rc ); 320 321 libc_reentrant = reentrant; 322 } 323 } 324 325 #if 0 326 /* 327 * Routines required by the gnat runtime. 328 */ 329 330 int get_errno() 331 { 332 return errno; 333 } 334 #endif 291 libc_extension.thread_begin = libc_begin_hook; 292 #endif 293 libc_extension.thread_switch = libc_switch_hook; 294 libc_extension.thread_delete = libc_delete_hook; 295 296 rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), 297 &libc_extension, &extension_id); 298 if (rc != RTEMS_SUCCESSFUL) 299 rtems_fatal_error_occurred( rc ); 300 301 libc_reentrant = reentrant; 302 extension_index = rtems_get_index( extension_id ); 303 } 304 } 335 305 336 306 /* … … 367 337 void _exit(int status) 368 338 { 369 370 371 372 373 374 375 376 339 /* 340 * We need to do the exit processing on the global reentrancy structure. 341 * This has already been done on the per task reentrancy structure 342 * associated with this task. 343 */ 344 345 libc_wrapup(); 346 rtems_shutdown_executive(status); 377 347 } 378 348 … … 381 351 void exit(int status) 382 352 { 383 libc_wrapup(); 384 rtems_shutdown_executive(status); 385 } 386 #endif 387 388 389 /* 390 * These are directly supported (and completely correct) in the posix api. 391 */ 392 393 pid_t __getpid(void) 394 { 395 return getpid(); 396 } 397 398 #if !defined(RTEMS_POSIX_API) 399 pid_t getpid(void) 400 { 401 return 0; 402 } 403 404 pid_t _getpid_r( 405 struct _reent *ptr 406 ) 407 { 408 return getpid(); 409 } 410 #endif 411 412 #if !defined(RTEMS_POSIX_API) 413 int kill( pid_t pid, int sig ) 414 { 415 return 0; 416 } 417 418 int _kill_r( pid_t pid, int sig ) 419 { 420 return 0; 421 } 422 #endif 423 424 int __kill( pid_t pid, int sig ) 425 { 426 return 0; 427 } 428 429 #if !defined(RTEMS_POSIX_API) 430 unsigned int sleep( 431 unsigned int seconds 432 ) 433 { 434 rtems_status_code status; 435 rtems_interval ticks_per_second; 436 rtems_interval ticks; 437 438 status = rtems_clock_get( 439 RTEMS_CLOCK_GET_TICKS_PER_SECOND, 440 &ticks_per_second 441 ); 442 443 ticks = seconds * ticks_per_second; 444 445 status = rtems_task_wake_after( ticks ); 446 447 /* 448 * Returns the "unslept" amount of time. In RTEMS signals are not 449 * interruptable, so tasks really sleep all of the requested time. 450 */ 451 452 return 0; 453 } 454 #endif 455 456 457 /* 458 * Newlib Interface Support 459 * 460 * Routines to Access Internal RTEMS Resources without violating 461 * kernel visibility. 462 * 463 */ 464 465 void MY_task_set_note( 466 Thread_Control *the_thread, 467 unsigned32 notepad, 468 unsigned32 note 469 ) 470 { 471 RTEMS_API_Control *api; 472 473 api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; 474 475 if ( api ) 476 api->Notepads[ notepad ] = note; 477 } 478 479 480 unsigned32 MY_task_get_note( 481 Thread_Control *the_thread, 482 unsigned32 notepad 483 ) 484 { 485 RTEMS_API_Control *api; 486 487 api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; 488 489 return api->Notepads[ notepad ]; 490 } 491 492 void *MY_CPU_Context_FP_start( 493 void *base, 494 unsigned32 offset 495 ) 496 { 497 return _CPU_Context_Fp_start( base, offset ); 498 } 499 #endif 353 libc_wrapup(); 354 rtems_shutdown_executive(status); 355 } 356 #endif 357 358 359 #endif -
c/src/lib/libc/Makefile.in
r0fab6dde r7edb9281 47 47 PASSWORD_GROUP_C_PIECES = getpwent getgrent 48 48 49 LIBC_GLUE_C_PIECES = __get tod __times truncate access stat lstat pathconf\50 newlibcno_libc49 LIBC_GLUE_C_PIECES = __getpid __gettod __times truncate access stat \ 50 lstat pathconf newlibc no_posix no_libc 51 51 52 52 UNIX_LIBC_C_PIECES = unixlibc hosterr -
c/src/lib/libc/newlibc.c
r0fab6dde r7edb9281 41 41 #endif 42 42 43 static int extension_index; 44 43 45 /* 44 46 * Private routines 45 47 */ 46 48 47 void MY_task_set_note( 48 rtems_tcb *tcb, 49 rtems_unsigned32 notepad, 50 rtems_unsigned32 note 51 ); 52 53 rtems_unsigned32 MY_task_get_note( 54 rtems_tcb *tcb, 55 rtems_unsigned32 notepad 56 ); 57 58 59 #define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST 60 49 #define set_newlib_extension( _the_thread, _value ) \ 50 (_the_thread)->extensions[ extension_index ] = (_value); 51 52 #define get_newlib_extension( _the_thread ) \ 53 (_the_thread)->extensions[ extension_index ] 61 54 62 55 int libc_reentrant; /* do we think we are reentrant? */ … … 74 67 #include <stdio.h> 75 68 76 void 77 libc_wrapup(void) 78 { 79 /* 80 * In case RTEMS is already down, don't do this. It could be 81 * dangerous. 82 */ 83 84 if (!_System_state_Is_up(_System_state_Get())) 85 return; 86 87 /* 88 * This was already done if the user called exit() directly . 89 90 _wrapup_reent(0); 91 */ 92 if (_REENT != &libc_global_reent) 93 { 94 _wrapup_reent(&libc_global_reent); 69 void libc_wrapup(void) 70 { 71 /* 72 * In case RTEMS is already down, don't do this. It could be 73 * dangerous. 74 */ 75 76 if (!_System_state_Is_up(_System_state_Get())) 77 return; 78 79 /* 80 * This was already done if the user called exit() directly . 81 _wrapup_reent(0); 82 */ 83 84 if (_REENT != &libc_global_reent) { 85 _wrapup_reent(&libc_global_reent); 95 86 #if 0 96 /* don't reclaim this one, just in case we do printfs */ 97 /* on our way out to ROM */ 98 _reclaim_reent(&libc_global_reent); 99 #endif 100 _REENT = &libc_global_reent; 101 } 102 103 /* 104 * Try to drain output buffers. 105 * 106 * Should this be changed to do *all* file streams? 107 * _fwalk (_REENT, fclose); 108 */ 109 fclose (stdin); 110 fclose (stdout); 111 fclose (stderr); 112 } 113 114 115 rtems_boolean 116 libc_create_hook(rtems_tcb *current_task, 117 rtems_tcb *creating_task) 118 { 119 MY_task_set_note(creating_task, LIBC_NOTEPAD, 0); 120 return TRUE; 87 /* Don't reclaim this one, just in case we do printfs 88 * on the way out to ROM. 89 */ 90 _reclaim_reent(&libc_global_reent); 91 #endif 92 _REENT = &libc_global_reent; 93 } 94 95 /* 96 * Try to drain output buffers. 97 * 98 * Should this be changed to do *all* file streams? 99 * _fwalk (_REENT, fclose); 100 */ 101 102 fclose (stdin); 103 fclose (stdout); 104 fclose (stderr); 105 } 106 107 108 rtems_boolean libc_create_hook( 109 rtems_tcb *current_task, 110 rtems_tcb *creating_task 111 ) 112 { 113 set_newlib_extension( creating_task, NULL ); 114 return TRUE; 121 115 } 122 116 … … 125 119 */ 126 120 127 rtems_extension 128 libc_start_hook(rtems_tcb *current_task, 129 rtems_tcb *starting_task) 130 { 131 struct _reent *ptr; 132 133 /* NOTE: our malloc is reentrant without a reent ptr since 134 * it is based on region manager 135 */ 136 137 ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); 138 139 if (!ptr) 140 rtems_fatal_error_occurred(RTEMS_NO_MEMORY); 121 rtems_extension libc_start_hook( 122 rtems_tcb *current_task, 123 rtems_tcb *starting_task 124 ) 125 { 126 struct _reent *ptr; 127 128 /* NOTE: The RTEMS malloc is reentrant without a reent ptr since 129 * it is based on the Classic API Region Manager. 130 */ 131 132 ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); 133 134 if (!ptr) 135 rtems_fatal_error_occurred(RTEMS_NO_MEMORY); 141 136 142 137 #ifdef __GNUC__ 143 144 138 /* GCC extension: structure constants */ 139 *ptr = (struct _reent) _REENT_INIT((*ptr)); 145 140 #else 146 /* 147 * Warning: THIS IS VERY DEPENDENT ON NEWLIB!!! WRITTEN FOR 1.7.0 148 */ 149 ptr->_errno=0; 150 ptr->_stdin=&ptr->__sf[0]; 151 ptr->_stdout=&ptr->__sf[1]; 152 ptr->_stderr=&ptr->__sf[2]; 153 ptr->_scanpoint=0; 154 ptr->_asctime[0]=0; 155 ptr->_next=1; 156 ptr->__sdidinit=0; 157 #endif 158 159 MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr); 141 /* 142 * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!! 143 * Last visual check was against newlib 1.8.2 but last known 144 * use was against 1.7.0. This is basically an exansion of 145 * REENT_INIT() in <sys/reent.h>. 146 * NOTE: calloc() takes care of zeroing fields. 147 */ 148 ptr->_stdin = &ptr->__sf[0]; 149 ptr->_stdout = &ptr->__sf[1]; 150 ptr->_stderr = &ptr->__sf[2]; 151 ptr->_current_locale = "C"; 152 ptr->_new._reent._rand_next = 1; 153 #endif 154 155 set_newlib_extension( starting_task, ptr ); 160 156 } 161 157 … … 165 161 166 162 #ifdef NEED_SETVBUF 167 rtems_extension 168 libc_begin_hook(rtems_tcb *current_task) 163 rtems_extension libc_begin_hook(rtems_tcb *current_task) 169 164 { 170 165 setvbuf( stdout, NULL, _IOLBF, BUFSIZ ); … … 172 167 #endif 173 168 174 rtems_extension 175 libc_switch_hook(rtems_tcb *current_task, 176 rtems_tcb *heir_task) 177 { 178 rtems_unsigned32 impure_value; 179 180 /* XXX We can't use rtems_task_set_note() here since SYSI task has a 181 * tid of 0, which is treated specially (optimized, actually) 182 * by rtems_task_set_note 183 * 184 * NOTE: The above comment is no longer true and we need to use 185 * the extension data areas added about the same time. 186 */ 187 188 /* 189 * Don't touch the outgoing task if it has been deleted. 190 */ 191 192 if ( !_States_Is_transient( current_task->current_state ) ) { 193 impure_value = (rtems_unsigned32) _REENT; 194 MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value); 195 } 196 197 _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD); 198 169 rtems_extension libc_switch_hook( 170 rtems_tcb *current_task, 171 rtems_tcb *heir_task 172 ) 173 { 174 /* 175 * Don't touch the outgoing task if it has been deleted. 176 */ 177 178 if ( !_States_Is_transient( current_task->current_state ) ) { 179 set_newlib_extension( current_task, _REENT ); 180 } 181 182 _REENT = (struct _reent *) get_newlib_extension( heir_task ); 199 183 } 200 184 … … 223 207 * 224 208 */ 225 rtems_extension 226 libc_delete_hook(rtems_tcb *current_task, 227 rtems_tcb *deleted_task) 228 { 229 struct _reent *ptr; 230 231 /* 232 * The reentrancy structure was allocated by newlib using malloc() 233 */ 234 235 if (current_task == deleted_task) 236 { 237 ptr = _REENT; 238 } 239 else 240 { 241 ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD); 242 } 243 244 /* if (ptr) */ 245 if (ptr && ptr != &libc_global_reent) 246 { 247 _wrapup_reent(ptr); 248 _reclaim_reent(ptr); 249 free(ptr); 250 } 251 252 MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0); 253 254 /* 255 * Require the switch back to another task to install its own 256 */ 257 258 if (current_task == deleted_task) 259 { 260 _REENT = 0; 261 } 209 210 rtems_extension libc_delete_hook( 211 rtems_tcb *current_task, 212 rtems_tcb *deleted_task 213 ) 214 { 215 struct _reent *ptr; 216 217 /* 218 * The reentrancy structure was allocated by newlib using malloc() 219 */ 220 221 if (current_task == deleted_task) { 222 ptr = _REENT; 223 } else { 224 ptr = (struct _reent *) get_newlib_extension( deleted_task ); 225 } 226 227 /* if (ptr) */ 228 if (ptr && ptr != &libc_global_reent) { 229 _wrapup_reent(ptr); 230 _reclaim_reent(ptr); 231 free(ptr); 232 } 233 234 set_newlib_extension( deleted_task, NULL ); 235 236 /* 237 * Require the switch back to another task to install its own 238 */ 239 240 if ( current_task == deleted_task ) { 241 _REENT = 0; 242 } 262 243 } 263 244 … … 295 276 libc_init(int reentrant) 296 277 { 297 rtems_extensions_table libc_extension; 298 rtems_id extension_id; 299 rtems_status_code rc; 300 301 libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent)); 302 _REENT = &libc_global_reent; 303 304 if (reentrant) 305 { 306 memset(&libc_extension, 0, sizeof(libc_extension)); 307 308 libc_extension.thread_create = libc_create_hook; 309 libc_extension.thread_start = libc_start_hook; 278 rtems_extensions_table libc_extension; 279 rtems_status_code rc; 280 rtems_id extension_id; 281 282 libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent)); 283 _REENT = &libc_global_reent; 284 285 if (reentrant) { 286 memset(&libc_extension, 0, sizeof(libc_extension)); 287 288 libc_extension.thread_create = libc_create_hook; 289 libc_extension.thread_start = libc_start_hook; 310 290 #ifdef NEED_SETVBUF 311 libc_extension.thread_begin = libc_begin_hook; 312 #endif 313 libc_extension.thread_switch = libc_switch_hook; 314 libc_extension.thread_delete = libc_delete_hook; 315 316 rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), 317 &libc_extension, &extension_id); 318 if (rc != RTEMS_SUCCESSFUL) 319 rtems_fatal_error_occurred( rc ); 320 321 libc_reentrant = reentrant; 322 } 323 } 324 325 #if 0 326 /* 327 * Routines required by the gnat runtime. 328 */ 329 330 int get_errno() 331 { 332 return errno; 333 } 334 #endif 291 libc_extension.thread_begin = libc_begin_hook; 292 #endif 293 libc_extension.thread_switch = libc_switch_hook; 294 libc_extension.thread_delete = libc_delete_hook; 295 296 rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), 297 &libc_extension, &extension_id); 298 if (rc != RTEMS_SUCCESSFUL) 299 rtems_fatal_error_occurred( rc ); 300 301 libc_reentrant = reentrant; 302 extension_index = rtems_get_index( extension_id ); 303 } 304 } 335 305 336 306 /* … … 367 337 void _exit(int status) 368 338 { 369 370 371 372 373 374 375 376 339 /* 340 * We need to do the exit processing on the global reentrancy structure. 341 * This has already been done on the per task reentrancy structure 342 * associated with this task. 343 */ 344 345 libc_wrapup(); 346 rtems_shutdown_executive(status); 377 347 } 378 348 … … 381 351 void exit(int status) 382 352 { 383 libc_wrapup(); 384 rtems_shutdown_executive(status); 385 } 386 #endif 387 388 389 /* 390 * These are directly supported (and completely correct) in the posix api. 391 */ 392 393 pid_t __getpid(void) 394 { 395 return getpid(); 396 } 397 398 #if !defined(RTEMS_POSIX_API) 399 pid_t getpid(void) 400 { 401 return 0; 402 } 403 404 pid_t _getpid_r( 405 struct _reent *ptr 406 ) 407 { 408 return getpid(); 409 } 410 #endif 411 412 #if !defined(RTEMS_POSIX_API) 413 int kill( pid_t pid, int sig ) 414 { 415 return 0; 416 } 417 418 int _kill_r( pid_t pid, int sig ) 419 { 420 return 0; 421 } 422 #endif 423 424 int __kill( pid_t pid, int sig ) 425 { 426 return 0; 427 } 428 429 #if !defined(RTEMS_POSIX_API) 430 unsigned int sleep( 431 unsigned int seconds 432 ) 433 { 434 rtems_status_code status; 435 rtems_interval ticks_per_second; 436 rtems_interval ticks; 437 438 status = rtems_clock_get( 439 RTEMS_CLOCK_GET_TICKS_PER_SECOND, 440 &ticks_per_second 441 ); 442 443 ticks = seconds * ticks_per_second; 444 445 status = rtems_task_wake_after( ticks ); 446 447 /* 448 * Returns the "unslept" amount of time. In RTEMS signals are not 449 * interruptable, so tasks really sleep all of the requested time. 450 */ 451 452 return 0; 453 } 454 #endif 455 456 457 /* 458 * Newlib Interface Support 459 * 460 * Routines to Access Internal RTEMS Resources without violating 461 * kernel visibility. 462 * 463 */ 464 465 void MY_task_set_note( 466 Thread_Control *the_thread, 467 unsigned32 notepad, 468 unsigned32 note 469 ) 470 { 471 RTEMS_API_Control *api; 472 473 api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; 474 475 if ( api ) 476 api->Notepads[ notepad ] = note; 477 } 478 479 480 unsigned32 MY_task_get_note( 481 Thread_Control *the_thread, 482 unsigned32 notepad 483 ) 484 { 485 RTEMS_API_Control *api; 486 487 api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; 488 489 return api->Notepads[ notepad ]; 490 } 491 492 void *MY_CPU_Context_FP_start( 493 void *base, 494 unsigned32 offset 495 ) 496 { 497 return _CPU_Context_Fp_start( base, offset ); 498 } 499 #endif 353 libc_wrapup(); 354 rtems_shutdown_executive(status); 355 } 356 #endif 357 358 359 #endif -
cpukit/libcsupport/src/newlibc.c
r0fab6dde r7edb9281 41 41 #endif 42 42 43 static int extension_index; 44 43 45 /* 44 46 * Private routines 45 47 */ 46 48 47 void MY_task_set_note( 48 rtems_tcb *tcb, 49 rtems_unsigned32 notepad, 50 rtems_unsigned32 note 51 ); 52 53 rtems_unsigned32 MY_task_get_note( 54 rtems_tcb *tcb, 55 rtems_unsigned32 notepad 56 ); 57 58 59 #define LIBC_NOTEPAD RTEMS_NOTEPAD_LAST 60 49 #define set_newlib_extension( _the_thread, _value ) \ 50 (_the_thread)->extensions[ extension_index ] = (_value); 51 52 #define get_newlib_extension( _the_thread ) \ 53 (_the_thread)->extensions[ extension_index ] 61 54 62 55 int libc_reentrant; /* do we think we are reentrant? */ … … 74 67 #include <stdio.h> 75 68 76 void 77 libc_wrapup(void) 78 { 79 /* 80 * In case RTEMS is already down, don't do this. It could be 81 * dangerous. 82 */ 83 84 if (!_System_state_Is_up(_System_state_Get())) 85 return; 86 87 /* 88 * This was already done if the user called exit() directly . 89 90 _wrapup_reent(0); 91 */ 92 if (_REENT != &libc_global_reent) 93 { 94 _wrapup_reent(&libc_global_reent); 69 void libc_wrapup(void) 70 { 71 /* 72 * In case RTEMS is already down, don't do this. It could be 73 * dangerous. 74 */ 75 76 if (!_System_state_Is_up(_System_state_Get())) 77 return; 78 79 /* 80 * This was already done if the user called exit() directly . 81 _wrapup_reent(0); 82 */ 83 84 if (_REENT != &libc_global_reent) { 85 _wrapup_reent(&libc_global_reent); 95 86 #if 0 96 /* don't reclaim this one, just in case we do printfs */ 97 /* on our way out to ROM */ 98 _reclaim_reent(&libc_global_reent); 99 #endif 100 _REENT = &libc_global_reent; 101 } 102 103 /* 104 * Try to drain output buffers. 105 * 106 * Should this be changed to do *all* file streams? 107 * _fwalk (_REENT, fclose); 108 */ 109 fclose (stdin); 110 fclose (stdout); 111 fclose (stderr); 112 } 113 114 115 rtems_boolean 116 libc_create_hook(rtems_tcb *current_task, 117 rtems_tcb *creating_task) 118 { 119 MY_task_set_note(creating_task, LIBC_NOTEPAD, 0); 120 return TRUE; 87 /* Don't reclaim this one, just in case we do printfs 88 * on the way out to ROM. 89 */ 90 _reclaim_reent(&libc_global_reent); 91 #endif 92 _REENT = &libc_global_reent; 93 } 94 95 /* 96 * Try to drain output buffers. 97 * 98 * Should this be changed to do *all* file streams? 99 * _fwalk (_REENT, fclose); 100 */ 101 102 fclose (stdin); 103 fclose (stdout); 104 fclose (stderr); 105 } 106 107 108 rtems_boolean libc_create_hook( 109 rtems_tcb *current_task, 110 rtems_tcb *creating_task 111 ) 112 { 113 set_newlib_extension( creating_task, NULL ); 114 return TRUE; 121 115 } 122 116 … … 125 119 */ 126 120 127 rtems_extension 128 libc_start_hook(rtems_tcb *current_task, 129 rtems_tcb *starting_task) 130 { 131 struct _reent *ptr; 132 133 /* NOTE: our malloc is reentrant without a reent ptr since 134 * it is based on region manager 135 */ 136 137 ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); 138 139 if (!ptr) 140 rtems_fatal_error_occurred(RTEMS_NO_MEMORY); 121 rtems_extension libc_start_hook( 122 rtems_tcb *current_task, 123 rtems_tcb *starting_task 124 ) 125 { 126 struct _reent *ptr; 127 128 /* NOTE: The RTEMS malloc is reentrant without a reent ptr since 129 * it is based on the Classic API Region Manager. 130 */ 131 132 ptr = (struct _reent *) calloc(1, sizeof(struct _reent)); 133 134 if (!ptr) 135 rtems_fatal_error_occurred(RTEMS_NO_MEMORY); 141 136 142 137 #ifdef __GNUC__ 143 144 138 /* GCC extension: structure constants */ 139 *ptr = (struct _reent) _REENT_INIT((*ptr)); 145 140 #else 146 /* 147 * Warning: THIS IS VERY DEPENDENT ON NEWLIB!!! WRITTEN FOR 1.7.0 148 */ 149 ptr->_errno=0; 150 ptr->_stdin=&ptr->__sf[0]; 151 ptr->_stdout=&ptr->__sf[1]; 152 ptr->_stderr=&ptr->__sf[2]; 153 ptr->_scanpoint=0; 154 ptr->_asctime[0]=0; 155 ptr->_next=1; 156 ptr->__sdidinit=0; 157 #endif 158 159 MY_task_set_note(starting_task, LIBC_NOTEPAD, (rtems_unsigned32) ptr); 141 /* 142 * WARNING: THIS IS VERY DEPENDENT ON NEWLIB!!! 143 * Last visual check was against newlib 1.8.2 but last known 144 * use was against 1.7.0. This is basically an exansion of 145 * REENT_INIT() in <sys/reent.h>. 146 * NOTE: calloc() takes care of zeroing fields. 147 */ 148 ptr->_stdin = &ptr->__sf[0]; 149 ptr->_stdout = &ptr->__sf[1]; 150 ptr->_stderr = &ptr->__sf[2]; 151 ptr->_current_locale = "C"; 152 ptr->_new._reent._rand_next = 1; 153 #endif 154 155 set_newlib_extension( starting_task, ptr ); 160 156 } 161 157 … … 165 161 166 162 #ifdef NEED_SETVBUF 167 rtems_extension 168 libc_begin_hook(rtems_tcb *current_task) 163 rtems_extension libc_begin_hook(rtems_tcb *current_task) 169 164 { 170 165 setvbuf( stdout, NULL, _IOLBF, BUFSIZ ); … … 172 167 #endif 173 168 174 rtems_extension 175 libc_switch_hook(rtems_tcb *current_task, 176 rtems_tcb *heir_task) 177 { 178 rtems_unsigned32 impure_value; 179 180 /* XXX We can't use rtems_task_set_note() here since SYSI task has a 181 * tid of 0, which is treated specially (optimized, actually) 182 * by rtems_task_set_note 183 * 184 * NOTE: The above comment is no longer true and we need to use 185 * the extension data areas added about the same time. 186 */ 187 188 /* 189 * Don't touch the outgoing task if it has been deleted. 190 */ 191 192 if ( !_States_Is_transient( current_task->current_state ) ) { 193 impure_value = (rtems_unsigned32) _REENT; 194 MY_task_set_note(current_task, LIBC_NOTEPAD, impure_value); 195 } 196 197 _REENT = (struct _reent *) MY_task_get_note(heir_task, LIBC_NOTEPAD); 198 169 rtems_extension libc_switch_hook( 170 rtems_tcb *current_task, 171 rtems_tcb *heir_task 172 ) 173 { 174 /* 175 * Don't touch the outgoing task if it has been deleted. 176 */ 177 178 if ( !_States_Is_transient( current_task->current_state ) ) { 179 set_newlib_extension( current_task, _REENT ); 180 } 181 182 _REENT = (struct _reent *) get_newlib_extension( heir_task ); 199 183 } 200 184 … … 223 207 * 224 208 */ 225 rtems_extension 226 libc_delete_hook(rtems_tcb *current_task, 227 rtems_tcb *deleted_task) 228 { 229 struct _reent *ptr; 230 231 /* 232 * The reentrancy structure was allocated by newlib using malloc() 233 */ 234 235 if (current_task == deleted_task) 236 { 237 ptr = _REENT; 238 } 239 else 240 { 241 ptr = (struct _reent *) MY_task_get_note(deleted_task, LIBC_NOTEPAD); 242 } 243 244 /* if (ptr) */ 245 if (ptr && ptr != &libc_global_reent) 246 { 247 _wrapup_reent(ptr); 248 _reclaim_reent(ptr); 249 free(ptr); 250 } 251 252 MY_task_set_note(deleted_task, LIBC_NOTEPAD, 0); 253 254 /* 255 * Require the switch back to another task to install its own 256 */ 257 258 if (current_task == deleted_task) 259 { 260 _REENT = 0; 261 } 209 210 rtems_extension libc_delete_hook( 211 rtems_tcb *current_task, 212 rtems_tcb *deleted_task 213 ) 214 { 215 struct _reent *ptr; 216 217 /* 218 * The reentrancy structure was allocated by newlib using malloc() 219 */ 220 221 if (current_task == deleted_task) { 222 ptr = _REENT; 223 } else { 224 ptr = (struct _reent *) get_newlib_extension( deleted_task ); 225 } 226 227 /* if (ptr) */ 228 if (ptr && ptr != &libc_global_reent) { 229 _wrapup_reent(ptr); 230 _reclaim_reent(ptr); 231 free(ptr); 232 } 233 234 set_newlib_extension( deleted_task, NULL ); 235 236 /* 237 * Require the switch back to another task to install its own 238 */ 239 240 if ( current_task == deleted_task ) { 241 _REENT = 0; 242 } 262 243 } 263 244 … … 295 276 libc_init(int reentrant) 296 277 { 297 rtems_extensions_table libc_extension; 298 rtems_id extension_id; 299 rtems_status_code rc; 300 301 libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent)); 302 _REENT = &libc_global_reent; 303 304 if (reentrant) 305 { 306 memset(&libc_extension, 0, sizeof(libc_extension)); 307 308 libc_extension.thread_create = libc_create_hook; 309 libc_extension.thread_start = libc_start_hook; 278 rtems_extensions_table libc_extension; 279 rtems_status_code rc; 280 rtems_id extension_id; 281 282 libc_global_reent = (struct _reent) _REENT_INIT((libc_global_reent)); 283 _REENT = &libc_global_reent; 284 285 if (reentrant) { 286 memset(&libc_extension, 0, sizeof(libc_extension)); 287 288 libc_extension.thread_create = libc_create_hook; 289 libc_extension.thread_start = libc_start_hook; 310 290 #ifdef NEED_SETVBUF 311 libc_extension.thread_begin = libc_begin_hook; 312 #endif 313 libc_extension.thread_switch = libc_switch_hook; 314 libc_extension.thread_delete = libc_delete_hook; 315 316 rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), 317 &libc_extension, &extension_id); 318 if (rc != RTEMS_SUCCESSFUL) 319 rtems_fatal_error_occurred( rc ); 320 321 libc_reentrant = reentrant; 322 } 323 } 324 325 #if 0 326 /* 327 * Routines required by the gnat runtime. 328 */ 329 330 int get_errno() 331 { 332 return errno; 333 } 334 #endif 291 libc_extension.thread_begin = libc_begin_hook; 292 #endif 293 libc_extension.thread_switch = libc_switch_hook; 294 libc_extension.thread_delete = libc_delete_hook; 295 296 rc = rtems_extension_create(rtems_build_name('L', 'I', 'B', 'C'), 297 &libc_extension, &extension_id); 298 if (rc != RTEMS_SUCCESSFUL) 299 rtems_fatal_error_occurred( rc ); 300 301 libc_reentrant = reentrant; 302 extension_index = rtems_get_index( extension_id ); 303 } 304 } 335 305 336 306 /* … … 367 337 void _exit(int status) 368 338 { 369 370 371 372 373 374 375 376 339 /* 340 * We need to do the exit processing on the global reentrancy structure. 341 * This has already been done on the per task reentrancy structure 342 * associated with this task. 343 */ 344 345 libc_wrapup(); 346 rtems_shutdown_executive(status); 377 347 } 378 348 … … 381 351 void exit(int status) 382 352 { 383 libc_wrapup(); 384 rtems_shutdown_executive(status); 385 } 386 #endif 387 388 389 /* 390 * These are directly supported (and completely correct) in the posix api. 391 */ 392 393 pid_t __getpid(void) 394 { 395 return getpid(); 396 } 397 398 #if !defined(RTEMS_POSIX_API) 399 pid_t getpid(void) 400 { 401 return 0; 402 } 403 404 pid_t _getpid_r( 405 struct _reent *ptr 406 ) 407 { 408 return getpid(); 409 } 410 #endif 411 412 #if !defined(RTEMS_POSIX_API) 413 int kill( pid_t pid, int sig ) 414 { 415 return 0; 416 } 417 418 int _kill_r( pid_t pid, int sig ) 419 { 420 return 0; 421 } 422 #endif 423 424 int __kill( pid_t pid, int sig ) 425 { 426 return 0; 427 } 428 429 #if !defined(RTEMS_POSIX_API) 430 unsigned int sleep( 431 unsigned int seconds 432 ) 433 { 434 rtems_status_code status; 435 rtems_interval ticks_per_second; 436 rtems_interval ticks; 437 438 status = rtems_clock_get( 439 RTEMS_CLOCK_GET_TICKS_PER_SECOND, 440 &ticks_per_second 441 ); 442 443 ticks = seconds * ticks_per_second; 444 445 status = rtems_task_wake_after( ticks ); 446 447 /* 448 * Returns the "unslept" amount of time. In RTEMS signals are not 449 * interruptable, so tasks really sleep all of the requested time. 450 */ 451 452 return 0; 453 } 454 #endif 455 456 457 /* 458 * Newlib Interface Support 459 * 460 * Routines to Access Internal RTEMS Resources without violating 461 * kernel visibility. 462 * 463 */ 464 465 void MY_task_set_note( 466 Thread_Control *the_thread, 467 unsigned32 notepad, 468 unsigned32 note 469 ) 470 { 471 RTEMS_API_Control *api; 472 473 api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; 474 475 if ( api ) 476 api->Notepads[ notepad ] = note; 477 } 478 479 480 unsigned32 MY_task_get_note( 481 Thread_Control *the_thread, 482 unsigned32 notepad 483 ) 484 { 485 RTEMS_API_Control *api; 486 487 api = the_thread->API_Extensions[ THREAD_API_RTEMS ]; 488 489 return api->Notepads[ notepad ]; 490 } 491 492 void *MY_CPU_Context_FP_start( 493 void *base, 494 unsigned32 offset 495 ) 496 { 497 return _CPU_Context_Fp_start( base, offset ); 498 } 499 #endif 353 libc_wrapup(); 354 rtems_shutdown_executive(status); 355 } 356 #endif 357 358 359 #endif
Note: See TracChangeset
for help on using the changeset viewer.