Huint _destroy_thread( Huint id )
{
    // Deallocate the thread ID from the thread manager
    _clear_thread( id );

    // Give the architecture dependent code a chance to destroy the thread
    _arch_destroy_thread( id, &threads[id], id );

    // Deallocate the stack that the thread is using
    if( threads[id].stack != NULL )
    {
        //free( threads[ id ].stack );
        // Static allocation doesn't require free
    }

    // The stack pointer now points at nothing
    threads[ id ].stack = NULL;

    return SUCCESS;
}
Exemple #2
0
Huint _destroy_thread( Huint id )
{
    hthread_thread_t * global_context_ptr =(hthread_thread_t *) _vhwti_context_ptr_field();
    hthread_thread_t * threads = (hthread_thread_t *)global_context_ptr;

    // Deallocate the thread ID from the thread manager
	_clear_thread( id );

    // Give the architecture dependent code a change to destroy the thread
    //_arch_destroy_thread( id, &threads[id], id );

    // Deallocate the stack that the thread is using
    if( threads[id].stack != NULL )
    {
        //free( threads[ id ].stack );
        // No need to free statically allocated objects
    }

    // The stack pointer now points at nothing
    threads[ id ].stack = NULL;

    return SUCCESS;
}
/** \internal
  * \brief  The system call which implements the hthread_create functionality.
  *
  * \author     Wesley Peck <*****@*****.**>
  *
  * This function is the system call routine which implements the 
  * hthread_create functionality for hthreads. The user space function
  * hthread_create invokes this function to create a new thread.
  *
  * \param  th      If the thread was created successfully then the new
  *                 thread will be stored in the location pointed to
  *                 by this argument.
  * \param  attr    The attributes to apply to the newly created thread.
  *                 See the documentation for hthread_attr_t for more on
  *                 the allowable attributes.
  * \param  start   A function pointer which is used as the beginning of
  *                 the new threads execution. If this function ever returns
  *                 then the new thread will be terminated.
  * \param  arg     An arbitrary pointer which is used as the first and
  *                 only argument to the start routine.
  * \return         The return value is one of the following:
  *                 - EAGAIN  : There was an error when attempting to create
  *                             the new thread. Trying the attempt again might
  *                             have a different result.
  *                 - ENOMEM  : Not enough memory is available to satisfy the
  *                             request. Attempting again after more memory
  *                             is free might have different results.
  *                 - EINVAL  : One of the parameters used when calling this
  *                             function is invalid.
  *                 - FAILURE : A generic failure occurred in the hardware
  *                             when attempting to setup the thread.
  *                 - SUCCESS : The thread was created successfully
  */
Hint _syscall_create(	hthread_t *th, hthread_attr_t *attr,
						hthread_start_t start, void *arg )
{
	Huint threadStatus;
	Huint threadID;
	Huint addStatus;
    Huint setupStatus;
    Huint schedStatus;
    
    // Print out a trace message about this system call
    TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL,
                  "SYSCALL: (OP=CREATE) (THR=0x%8.8x) (ATTR=0x%8.8x) (STRT=0x%8.8x) (ARG=0x%8.8x)\n",
                  (Huint)th, (Huint)attr, (Huint)start, (Huint)arg );

    // Ask the thread manager to create a new thread for us. If it
    // is successful then the thread id will be encoded into the return
    // value.
    if( attr->detached )    threadStatus = _create_detached();
	else                    threadStatus = _create_joinable();

    TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (DET = 0x%8.8x)\n",(Huint)attr->detached );

    // Check if there was an error while creating the new thread. If
	// there was then it means that all of the available threads are
	// being used, so we return an error.
	if( has_error(threadStatus) )
    {
        TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (STA=0x%8.8x) (ERR=CREATE)\n", threadStatus );
        return EAGAIN;
    }

	// If there was no error then we need to get the new thread's id
	// out of the return status.
	threadID = extract_id( threadStatus );
    TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (TID=0x%8.8x)\n", threadID );
    
	// Initialize the software structures used to keep track of the thread.
	setupStatus = _setup_thread( threadID, attr, start, arg );
    if( setupStatus != SUCCESS )
    {
        TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (STA=0x%8.8x) (ERR=SETUP)\n", setupStatus );
        return setupStatus;
    }

    // Set the scheduling parameter for the thread.
    if( attr->hardware != Htrue )
    {
        TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (Software Thread Sched. Param = 0x%8.8x)\n",attr->sched_param);
        schedStatus = _set_schedparam( threadID, attr->sched_param );
    }
    else
    {
        TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (Hardware Thread Sched. Param = 0x%8.8x)\n",attr->hardware_addr);
        schedStatus = _set_schedparam( threadID, attr->hardware_addr );
    }

    if( schedStatus != SUCCESS )
    {
        TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (STA=0x%8.8x) (ERR=SCHED)\n", schedStatus );
        return schedStatus;
    }

    // Now that we have the new thread setup so that it can run we
    // can add the thread in the ready-to-run queue.
    addStatus = _add_thread( threadID );

	// Check if there was an error when adding the thread into the
	// ready-to-run queue. If there was then we need to clean up the
	// new thread and return an error condition.
	if( has_error(addStatus) )
	{
        TRACE_PRINTF( TRACE_DBG, TRACE_SYSCALL, "SYSCALL: (OP=CREATE) (STA=0x%8.8x) (ERR=ADD)\n", addStatus );

        addStatus = _read_sched_status(threadID);
        _decode_sched_status(addStatus);

		// Clean up the software structures used by the thread.
		_destroy_thread( threadID );

		// Remove the thread.
		_clear_thread( threadID );

		// Return an error condition.
		return EAGAIN;
	}

	// Return the thread ID to the caller. At this point the thread has
	// been successfully created and added to the queue so that we know
	// a valid thread ID will be returned to the user.
	*th = threadID;

    // Print out a trace message about this system call
    TRACE_PRINTF( TRACE_FINE, TRACE_SYSCALL, "SYSCALL DONE: (OP=CREATE) (THR=0x%8.8x) (ATTR=0x%8.8x) (STRT=0x%8.8x) (ARG=0x%8.8x)\n", (Huint)th, (Huint)attr, (Huint)start, (Huint)arg );

	// The thread was created and added to the ready-to-run queue
	// successfully. Return the success code.
	return SUCCESS;
}