Esempio n. 1
0
/**
 * \b thread_shell
 *
 * Shell routine which is used to call all thread entry points.
 *
 * This routine is called whenever a new thread is starting, and
 * provides a simple wrapper around the thread entry point that
 * allows us to carry out any actions we want to do on thread's
 * first starting up, or returning after completion.
 *
 * We mainly just want to make sure interrupts are enabled when a
 * thread is run for the first time. This can be done via stack
 * restores when threads are first run, but it's handy to have this
 * wrapper anyway to run some common code if threads run to
 * completion.
 *
 * A thread shell is also handy for providing port users with a place
 * to do any other initialisation that must be done for each thread
 * (e.g. opening stdio files etc).
 *
 * @return None
 */
static void thread_shell (void)
{
    ATOM_TCB *curr_tcb;

    /* Get the TCB of the thread being started */
    curr_tcb = atomCurrentContext();

    /**
     * Open a stdout file descriptor so that the thread has its own stdout.
     * In theory threads could open stdout to different output drivers
     * if syscalls.s supported different output write functions.
     */
    stdout = fopen ("/debuguart", "w");
    setvbuf (stdout, 0, _IONBF, 0);
 
    /**
     * Enable interrupts - these will not be enabled when a thread
     * is first restored.
     */
    contextEnableInterrupts ();

    /* Call the thread entry point */
    if (curr_tcb && curr_tcb->entry_point)
    {
        curr_tcb->entry_point(curr_tcb->entry_param);
    }

    /* Clean up after thread completion */
    fclose (stdout);
    _reclaim_reent (&(curr_tcb->port_priv.reent));

    /* Thread has run to completion: remove it from the ready list */
    curr_tcb->terminated = TRUE;
    atomSched (FALSE);
}
Esempio n. 2
0
ThreadControlBlock::~ThreadControlBlock()
{
	sequenceNumber_ = ~sequenceNumber_;

	const InterruptMaskingLock interruptMaskingLock;

	_reclaim_reent(&reent_);
}
Esempio n. 3
0
 EXPORT_C void CloseSTDLIB()
 {
     struct _reent* p=(struct _reent*)Dll::Tls();
     if (p==0)
         return;
     _reclaim_reent(p);	// Reclaiming calls the atexit processing and generally tries to tidy up
     User::Free(p);		// then we give back the struct _reent itself
     Dll::SetTls(0);		// ... so we don't free it again when the DLL exits
 }
Esempio n. 4
0
int __libc_delete_hook(lwp_cntrl *curr_thr, lwp_cntrl *delete_thr)
{
	struct _reent *ptr;

	if(curr_thr==delete_thr)
		ptr = _REENT;
	else
		ptr = (struct _reent*)delete_thr->libc_reent;
	
	if(ptr && ptr!=&libc_globl_reent) {
		_wrapup_reent(ptr);
		_reclaim_reent(ptr);
		free(ptr);
	}
	delete_thr->libc_reent = 0;

	if(curr_thr==delete_thr) _REENT = 0;

	return 1;
}
Esempio n. 5
0
void libc_wrapup(void)
{
  /*
   *  In case RTEMS is already down, don't do this.  It could be
   *  dangerous.
   */

  if (!_System_state_Is_up(_System_state_Get()))
     return;

  /*
   *  This was already done if the user called exit() directly .
  _wrapup_reent(0);
   */

  if (_REENT != _global_impure_ptr) {
      _wrapup_reent(_global_impure_ptr);
#if 0
      /*  Don't reclaim this one, just in case we do printfs
       *  on the way out to ROM.
       */
      _reclaim_reent(&libc_global_reent);
#endif
      _REENT = _global_impure_ptr;
  }

  /*
   * Try to drain output buffers.
   *
   * Should this be changed to do *all* file streams?
   *    _fwalk (_REENT, fclose);
   */

  fclose (stdin);
  fclose (stdout);
  fclose (stderr);
}
Esempio n. 6
0
ThreadControlBlock::~ThreadControlBlock()
{
	architecture::InterruptMaskingLock interruptMaskingLock;

	_reclaim_reent(&reent_);
}