Ejemplo n.º 1
0
Archivo: tx_taa.c Proyecto: igou/tx
UINT    _tx_timer_activate_api(TX_TIMER *timer_ptr)
{


    /* Check for an already active timer or a timer with a zero
       expiration.  */
    if ((timer_ptr -> tx_timer_internal.tx_list_head) ||
            (!timer_ptr -> tx_timer_internal.tx_remaining_ticks))
    {

        /* Timer is already active or is being activated with a zero
           expiration.  */
        return(TX_ACTIVATE_ERROR);
    }

    /* Call actual activation function.  */
    _tx_timer_activate(&(timer_ptr -> tx_timer_internal));

    /* Return TX_SUCCESS.  */
    return(TX_SUCCESS);
}
Ejemplo n.º 2
0
Archivo: tx_ba.c Proyecto: igou/tx
UINT    _tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option)
{

TX_INTERRUPT_SAVE_AREA

REG_1   UINT        status;                 /* Return status           */
REG_2   TX_THREAD   *thread_ptr;            /* Working thread pointer  */
REG_3   CHAR_PTR    work_ptr;               /* Working block pointer   */


    /* Disable interrupts to get a block from the pool.  */
    TX_DISABLE

    /* Determine if there is an available block.  */
    if (pool_ptr -> tx_block_pool_available)
    {

        /* Yes, a block is available.  Decrement the available count.  */
        pool_ptr -> tx_block_pool_available--;

        /* Pickup the current block pointer.  */
        work_ptr =  pool_ptr -> tx_block_pool_available_list;

        /* Return the first available block to the caller.  */
        *((CHAR_PTR *) block_ptr) =  work_ptr + sizeof(CHAR_PTR);

        /* Modify the available list to point at the next block in the pool. */
        pool_ptr -> tx_block_pool_available_list =
                *((CHAR_PTR *) work_ptr);

        /* Save the pool's address in the block for when it is released!  */
        *((CHAR_PTR *) work_ptr) =  (CHAR_PTR) pool_ptr;
    
        /* Set status to success.  */
        status =  TX_SUCCESS;
    }
    else
    {

        /* Determine if the request specifies suspension.  */
        if (wait_option)
        {

            /* Prepare for suspension of this thread.  */
            
            /* Pickup thread pointer.  */
            thread_ptr =  _tx_thread_current_ptr;

            /* Setup cleanup routine pointer.  */
            thread_ptr -> tx_suspend_cleanup =  _tx_block_pool_cleanup;

            /* Setup cleanup information, i.e. this pool control
               block.  */
            thread_ptr -> tx_suspend_control_block =  (VOID_PTR) pool_ptr;

            /* Save the return block pointer address as well.  */
            thread_ptr -> tx_additional_suspend_info =  (VOID_PTR) block_ptr;

            /* Setup suspension list.  */
            if (pool_ptr -> tx_block_pool_suspension_list)
            {

                /* This list is not NULL, add current thread to the end. */
                thread_ptr -> tx_suspended_next =      
                        pool_ptr -> tx_block_pool_suspension_list;
                thread_ptr -> tx_suspended_previous =  
                        (pool_ptr -> tx_block_pool_suspension_list) -> tx_suspended_previous;
                ((pool_ptr -> tx_block_pool_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =  
                        thread_ptr;
                (pool_ptr -> tx_block_pool_suspension_list) -> tx_suspended_previous =   thread_ptr;
            }
            else
            {

                /* No other threads are suspended.  Setup the head pointer and
                   just setup this threads pointers to itself.  */
                pool_ptr -> tx_block_pool_suspension_list =  thread_ptr;
                thread_ptr -> tx_suspended_next =            thread_ptr;
                thread_ptr -> tx_suspended_previous =        thread_ptr;
            }

            /* Increment the suspended thread count.  */
            pool_ptr -> tx_block_pool_suspended_count++;

            /* Set the state to suspended.  */
            thread_ptr -> tx_state =       TX_BLOCK_MEMORY;

            /* Set the suspending flag.  */
            thread_ptr -> tx_suspending =  TX_TRUE;

            /* Temporarily disable preemption.  */
            _tx_thread_preempt_disable++;

            /* Save the timeout value.  */
            thread_ptr -> tx_thread_timer.tx_remaining_ticks =  wait_option;

            /* Restore interrupts.  */
            TX_RESTORE

            /* See if we need to start a timer.  */
            if (wait_option != TX_WAIT_FOREVER)
            {

                /* A timeout is required.  */

                /* Activate the thread timer for the timeout.  */
                _tx_timer_activate(&(thread_ptr -> tx_thread_timer));
            }

            /* Call actual thread suspension routine.  */
            _tx_thread_suspend(thread_ptr);

            /* Return the completion status.  */
            return(thread_ptr -> tx_suspend_status);
        }
        else
    
            /* Immediate return, return error completion.  */
            status =  TX_NO_MEMORY;
    }
Ejemplo n.º 3
0
UINT    _tx_semaphore_get(TX_SEMAPHORE *semaphore_ptr, ULONG wait_option)
{

TX_INTERRUPT_SAVE_AREA

REG_1   UINT        status;                 /* Return status           */
REG_2   TX_THREAD   *thread_ptr;            /* Working thread pointer  */


    /* Disable interrupts to get an instance from the semaphore.  */
    TX_DISABLE

    /* Log this kernel call.  */
    TX_EL_SEMAPHORE_GET_INSERT

    /* Determine if there is an instance of the semaphore.  */
    if (semaphore_ptr -> tx_semaphore_count)
    {

        /* Decrement the semaphore count.  */
        semaphore_ptr -> tx_semaphore_count--;

        /* Set status to success.  */
        status =  TX_SUCCESS;
    }
    else
    {

        /* Determine if the request specifies suspension.  */
        if (wait_option)
        {

            /* Prepare for suspension of this thread.  */
            
            /* Pickup thread pointer.  */
            thread_ptr =  _tx_thread_current_ptr;

            /* Setup cleanup routine pointer.  */
            thread_ptr -> tx_suspend_cleanup =  _tx_semaphore_cleanup;

            /* Setup cleanup information, i.e. this semaphore control
               block.  */
            thread_ptr -> tx_suspend_control_block =  (VOID_PTR) semaphore_ptr;

            /* Setup suspension list.  */
            if (semaphore_ptr -> tx_semaphore_suspension_list)
            {

                /* This list is not NULL, add current thread to the end. */
                thread_ptr -> tx_suspended_next =      
                        semaphore_ptr -> tx_semaphore_suspension_list;
                thread_ptr -> tx_suspended_previous =  
                        (semaphore_ptr -> tx_semaphore_suspension_list) -> tx_suspended_previous;
                ((semaphore_ptr -> tx_semaphore_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =  
                        thread_ptr;
                (semaphore_ptr -> tx_semaphore_suspension_list) -> tx_suspended_previous =   thread_ptr;
            }
            else
            {

                /* No other threads are suspended.  Setup the head pointer and
                   just setup this threads pointers to itself.  */
                semaphore_ptr -> tx_semaphore_suspension_list =  thread_ptr;
                thread_ptr -> tx_suspended_next =                thread_ptr;
                thread_ptr -> tx_suspended_previous =            thread_ptr;
            }

            /* Increment the suspended thread count.  */
            semaphore_ptr -> tx_semaphore_suspended_count++;

            /* Set the state to suspended.  */
            thread_ptr -> tx_state =    TX_SEMAPHORE_SUSP;

            /* Set the suspending flag.  */
            thread_ptr -> tx_suspending =  TX_TRUE;

            /* Temporarily disable preemption.  */
            _tx_thread_preempt_disable++;

            /* Save the timeout value.  */
            thread_ptr -> tx_thread_timer.tx_remaining_ticks =  wait_option;

            /* Restore interrupts.  */
            TX_RESTORE

            /* See if we need to start a timer.  */
            if (wait_option != TX_WAIT_FOREVER)
            {

                /* A timeout is required.  */
                _tx_timer_activate(&(thread_ptr -> tx_thread_timer));
            }

            /* Call actual thread suspension routine.  */
            _tx_thread_suspend(thread_ptr);

            /* Return the completion status.  */
            return(thread_ptr -> tx_suspend_status);
        }
        else
    
            /* Immediate return, return error completion.  */
            status =  TX_NO_INSTANCE;
    }
Ejemplo n.º 4
0
Archivo: tx_efg.c Proyecto: igou/tx
UINT        _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags,
                    UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option)
{

TX_INTERRUPT_SAVE_AREA

REG_1   UINT        status;                 /* Return status           */
REG_2   TX_THREAD   *thread_ptr;            /* Working thread pointer  */


    /* Disable interrupts to examine the event flags group.  */
    TX_DISABLE

    /* Determine if the event flags are present, based on the get option.  */
    if (get_option & TX_EVENT_FLAGS_AND_MASK)
    {

        /* All flags must be present to satisfy request.  */
        if ((group_ptr -> tx_event_flags_current & requested_flags) == requested_flags)
    
            /* Yes, all the events are present.  */
            status =  TX_SUCCESS;
        else

            /* No, not all the events are present.  */
            status =  TX_NO_EVENTS;
    }
    else
    {

        /* Any of the events will satisfy the request.  */
        if (group_ptr -> tx_event_flags_current & requested_flags)

            /* Yes, one or more of the requested events are set.  */
            status =  TX_SUCCESS;
        else
    
            /* No, none of the events are currently set.  */
            status =  TX_NO_EVENTS;
    }

    /* Now determine if the request can be satisfied immediately.  */
    if (status == TX_SUCCESS)
    {

        /* Yes, this request can be handled immediately.  */

        /* Return the actual event flags that satisfied the request.  */
        *actual_flags_ptr =  group_ptr -> tx_event_flags_current;

        /* Determine whether or not clearing needs to take place.  */
        if (get_option & TX_EVENT_FLAGS_CLEAR_MASK)

            /* Yes, clear the flags that satisfied this request.  */
            group_ptr -> tx_event_flags_current =
                group_ptr -> tx_event_flags_current & ~requested_flags;
    }
    else
    {

        /* Determine if the request specifies suspension.  */
        if (wait_option)
        {

            /* Prepare for suspension of this thread.  */
            
            /* Pickup thread pointer.  */
            thread_ptr =  _tx_thread_current_ptr;

            /* Setup cleanup routine pointer.  */
            thread_ptr -> tx_suspend_cleanup =  _tx_event_flags_cleanup;

            /* Remember which event flags we are looking for.  */
            thread_ptr -> tx_suspend_info =  requested_flags;

            /* Save the get option as well.  */
            thread_ptr -> tx_suspend_option =  get_option;

            /* Save the destination for the current events.  */
            thread_ptr -> tx_additional_suspend_info =  (VOID_PTR) actual_flags_ptr;

            /* Setup cleanup information, i.e. this event flags group control
               block.  */
            thread_ptr -> tx_suspend_control_block =  (VOID_PTR) group_ptr;

            /* Setup suspension list.  */
            if (group_ptr -> tx_event_flags_suspension_list)
            {

                /* This list is not NULL, add current thread to the end. */
                thread_ptr -> tx_suspended_next =      
                        group_ptr -> tx_event_flags_suspension_list;
                thread_ptr -> tx_suspended_previous =  
                        (group_ptr -> tx_event_flags_suspension_list) -> tx_suspended_previous;
                ((group_ptr -> tx_event_flags_suspension_list) -> tx_suspended_previous) -> tx_suspended_next =  
                        thread_ptr;
                (group_ptr -> tx_event_flags_suspension_list) -> tx_suspended_previous =   thread_ptr;
            }
            else
            {

                /* No other threads are suspended.  Setup the head pointer and
                   just setup this threads pointers to itself.  */
                group_ptr -> tx_event_flags_suspension_list =  thread_ptr;
                thread_ptr -> tx_suspended_next =              thread_ptr;
                thread_ptr -> tx_suspended_previous =          thread_ptr;
            }

            /* Increment the suspended thread count.  */
            group_ptr -> tx_event_flags_suspended_count++;

            /* Set the state to suspended.  */
            thread_ptr -> tx_state =    TX_EVENT_FLAG;

            /* Set the suspending flag.  */
            thread_ptr -> tx_suspending =  TX_TRUE;

            /* Temporarily disable preemption.  */
            _tx_thread_preempt_disable++;

            /* Save the timeout value.  */
            thread_ptr -> tx_thread_timer.tx_remaining_ticks =  wait_option;

            /* Restore interrupts.  */
            TX_RESTORE

            /* See if we need to start a timer.  */
            if (wait_option != TX_WAIT_FOREVER)
            {

                /* A timeout is required.  */

                /* Activate the thread timer for the timeout.  */
                _tx_timer_activate(&(thread_ptr -> tx_thread_timer));
            }

            /* Call actual thread suspension routine.  */
            _tx_thread_suspend(thread_ptr);

            /* Return the completion status.  */
            return(thread_ptr -> tx_suspend_status);
        }
        else
    
            /* Immediate return, return error completion.  */
            status =  TX_NO_EVENTS;
    }