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); }
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; }
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; }
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; }