add SMP, Modules, and more processor/tools releases
This commit is contained in:
620
common_smp/src/tx_event_flags_set.c
Normal file
620
common_smp/src/tx_event_flags_set.c
Normal file
@@ -0,0 +1,620 @@
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* Copyright (c) Microsoft Corporation. All rights reserved. */
|
||||
/* */
|
||||
/* This software is licensed under the Microsoft Software License */
|
||||
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
|
||||
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
|
||||
/* and in the root directory of this software. */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
/** */
|
||||
/** ThreadX Component */
|
||||
/** */
|
||||
/** Event Flags */
|
||||
/** */
|
||||
/**************************************************************************/
|
||||
/**************************************************************************/
|
||||
|
||||
#define TX_SOURCE_CODE
|
||||
|
||||
|
||||
/* Include necessary system files. */
|
||||
|
||||
#include "tx_api.h"
|
||||
#include "tx_trace.h"
|
||||
#include "tx_thread.h"
|
||||
#include "tx_event_flags.h"
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
/* */
|
||||
/* FUNCTION RELEASE */
|
||||
/* */
|
||||
/* _tx_event_flags_set PORTABLE C */
|
||||
/* 6.0.1 */
|
||||
/* AUTHOR */
|
||||
/* */
|
||||
/* William E. Lamie, Microsoft Corporation */
|
||||
/* */
|
||||
/* DESCRIPTION */
|
||||
/* */
|
||||
/* This function sets the specified flags in the event group based on */
|
||||
/* the set option specified. All threads suspended on the group whose */
|
||||
/* get request can now be satisfied are resumed. */
|
||||
/* */
|
||||
/* INPUT */
|
||||
/* */
|
||||
/* group_ptr Pointer to group control block */
|
||||
/* flags_to_set Event flags to set */
|
||||
/* set_option Specified either AND or OR */
|
||||
/* operation on the event flags */
|
||||
/* */
|
||||
/* OUTPUT */
|
||||
/* */
|
||||
/* TX_SUCCESS Always returns success */
|
||||
/* */
|
||||
/* CALLS */
|
||||
/* */
|
||||
/* _tx_thread_system_preempt_check Check for preemption */
|
||||
/* _tx_thread_system_resume Resume thread service */
|
||||
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
|
||||
/* */
|
||||
/* CALLED BY */
|
||||
/* */
|
||||
/* Application Code */
|
||||
/* */
|
||||
/* RELEASE HISTORY */
|
||||
/* */
|
||||
/* DATE NAME DESCRIPTION */
|
||||
/* */
|
||||
/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
|
||||
/* */
|
||||
/**************************************************************************/
|
||||
UINT _tx_event_flags_set(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG flags_to_set, UINT set_option)
|
||||
{
|
||||
|
||||
TX_INTERRUPT_SAVE_AREA
|
||||
|
||||
TX_THREAD *thread_ptr;
|
||||
TX_THREAD *next_thread_ptr;
|
||||
TX_THREAD *next_thread;
|
||||
TX_THREAD *previous_thread;
|
||||
TX_THREAD *satisfied_list;
|
||||
TX_THREAD *last_satisfied;
|
||||
TX_THREAD *suspended_list;
|
||||
UINT suspended_count;
|
||||
ULONG current_event_flags;
|
||||
ULONG requested_flags;
|
||||
ULONG flags_satisfied;
|
||||
ULONG *suspend_info_ptr;
|
||||
UINT and_request;
|
||||
UINT get_option;
|
||||
UINT clear_request;
|
||||
UINT preempt_check;
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
UINT interrupted_set_request;
|
||||
#endif
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
VOID (*events_set_notify)(struct TX_EVENT_FLAGS_GROUP_STRUCT *notify_group_ptr);
|
||||
#endif
|
||||
|
||||
|
||||
/* Disable interrupts to remove the semaphore from the created list. */
|
||||
TX_DISABLE
|
||||
|
||||
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
|
||||
|
||||
/* Increment the total event flags set counter. */
|
||||
_tx_event_flags_performance_set_count++;
|
||||
|
||||
/* Increment the number of event flags sets on this semaphore. */
|
||||
group_ptr -> tx_event_flags_group_performance_set_count++;
|
||||
#endif
|
||||
|
||||
/* If trace is enabled, insert this event into the trace buffer. */
|
||||
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_SET, group_ptr, flags_to_set, set_option, group_ptr -> tx_event_flags_group_suspended_count, TX_TRACE_EVENT_FLAGS_EVENTS)
|
||||
|
||||
/* Log this kernel call. */
|
||||
TX_EL_EVENT_FLAGS_SET_INSERT
|
||||
|
||||
/* Determine how to set this group's event flags. */
|
||||
if ((set_option & TX_EVENT_FLAGS_AND_MASK) == TX_AND)
|
||||
{
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Set interrupted set request flag to false. */
|
||||
interrupted_set_request = TX_FALSE;
|
||||
|
||||
/* Determine if the suspension list is being processed by an interrupted
|
||||
set request. */
|
||||
if (group_ptr -> tx_event_flags_group_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
if (group_ptr -> tx_event_flags_group_suspension_list == TX_NULL)
|
||||
{
|
||||
|
||||
/* Set the interrupted set request flag. */
|
||||
interrupted_set_request = TX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Was a set request interrupted? */
|
||||
if (interrupted_set_request == TX_TRUE)
|
||||
{
|
||||
|
||||
/* A previous set operation was interrupted, we need to defer the
|
||||
event clearing until the set operation is complete. */
|
||||
|
||||
/* Remember the events to clear. */
|
||||
group_ptr -> tx_event_flags_group_delayed_clear =
|
||||
group_ptr -> tx_event_flags_group_delayed_clear | ~flags_to_set;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Previous set operation was not interrupted, simply clear the
|
||||
specified flags by "ANDing" the flags into the current events
|
||||
of the group. */
|
||||
group_ptr -> tx_event_flags_group_current =
|
||||
group_ptr -> tx_event_flags_group_current & flags_to_set;
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Pickup the notify callback routine for this event flag group. */
|
||||
events_set_notify = group_ptr -> tx_event_flags_group_set_notify;
|
||||
#endif
|
||||
|
||||
/* "OR" the flags into the current events of the group. */
|
||||
group_ptr -> tx_event_flags_group_current =
|
||||
group_ptr -> tx_event_flags_group_current | flags_to_set;
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Determine if there are any delayed flags to clear. */
|
||||
if (group_ptr -> tx_event_flags_group_delayed_clear != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Yes, we need to neutralize the delayed clearing as well. */
|
||||
group_ptr -> tx_event_flags_group_delayed_clear =
|
||||
group_ptr -> tx_event_flags_group_delayed_clear & ~flags_to_set;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Clear the preempt check flag. */
|
||||
preempt_check = TX_FALSE;
|
||||
|
||||
/* Pickup the thread suspended count. */
|
||||
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
|
||||
|
||||
/* Determine if there are any threads suspended on the event flag group. */
|
||||
if (group_ptr -> tx_event_flags_group_suspension_list != TX_NULL)
|
||||
{
|
||||
|
||||
/* Determine if there is just a single thread waiting on the event
|
||||
flag group. */
|
||||
if (suspended_count == ((UINT) 1))
|
||||
{
|
||||
|
||||
/* Single thread waiting for event flags. Bypass the multiple thread
|
||||
logic. */
|
||||
|
||||
/* Setup thread pointer. */
|
||||
thread_ptr = group_ptr -> tx_event_flags_group_suspension_list;
|
||||
|
||||
/* Pickup the current event flags. */
|
||||
current_event_flags = group_ptr -> tx_event_flags_group_current;
|
||||
|
||||
/* Pickup the suspend information. */
|
||||
requested_flags = thread_ptr -> tx_thread_suspend_info;
|
||||
|
||||
/* Pickup the suspend option. */
|
||||
get_option = thread_ptr -> tx_thread_suspend_option;
|
||||
|
||||
/* Isolate the AND selection. */
|
||||
and_request = (get_option & TX_AND);
|
||||
|
||||
/* Check for AND condition. All flags must be present to satisfy request. */
|
||||
if (and_request == TX_AND)
|
||||
{
|
||||
|
||||
/* AND request is present. */
|
||||
|
||||
/* Calculate the flags present. */
|
||||
flags_satisfied = (current_event_flags & requested_flags);
|
||||
|
||||
/* Determine if they satisfy the AND request. */
|
||||
if (flags_satisfied != requested_flags)
|
||||
{
|
||||
|
||||
/* No, not all the requested flags are present. Clear the flags present variable. */
|
||||
flags_satisfied = ((ULONG) 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* OR request is present. Simply or the requested flags and the current flags. */
|
||||
flags_satisfied = (current_event_flags & requested_flags);
|
||||
}
|
||||
|
||||
/* Determine if the request is satisfied. */
|
||||
if (flags_satisfied != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Yes, resume the thread and apply any event flag
|
||||
clearing. */
|
||||
|
||||
/* Set the preempt check flag. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Return the actual event flags that satisfied the request. */
|
||||
suspend_info_ptr = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_additional_suspend_info);
|
||||
*suspend_info_ptr = current_event_flags;
|
||||
|
||||
/* Pickup the clear bit. */
|
||||
clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK);
|
||||
|
||||
/* Determine whether or not clearing needs to take place. */
|
||||
if (clear_request == TX_TRUE)
|
||||
{
|
||||
|
||||
/* Yes, clear the flags that satisfied this request. */
|
||||
group_ptr -> tx_event_flags_group_current = group_ptr -> tx_event_flags_group_current & (~requested_flags);
|
||||
}
|
||||
|
||||
/* Clear the suspension information in the event flag group. */
|
||||
group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
|
||||
group_ptr -> tx_event_flags_group_suspended_count = TX_NO_SUSPENSIONS;
|
||||
|
||||
/* Clear cleanup routine to avoid timeout. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Put return status into the thread control block. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_SUCCESS;
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
#else
|
||||
|
||||
/* Temporarily disable preemption. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume thread. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
|
||||
/* Disable interrupts to remove the semaphore from the created list. */
|
||||
TX_DISABLE
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Otherwise, the event flag requests of multiple threads must be
|
||||
examined. */
|
||||
|
||||
/* Setup thread pointer, keep a local copy of the head pointer. */
|
||||
suspended_list = group_ptr -> tx_event_flags_group_suspension_list;
|
||||
thread_ptr = suspended_list;
|
||||
|
||||
/* Clear the suspended list head pointer to thwart manipulation of
|
||||
the list in ISR's while we are processing here. */
|
||||
group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
|
||||
|
||||
/* Setup the satisfied thread pointers. */
|
||||
satisfied_list = TX_NULL;
|
||||
last_satisfied = TX_NULL;
|
||||
|
||||
/* Pickup the current event flags. */
|
||||
current_event_flags = group_ptr -> tx_event_flags_group_current;
|
||||
|
||||
/* Disable preemption while we process the suspended list. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Loop to examine all of the suspended threads. */
|
||||
do
|
||||
{
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Restore interrupts temporarily. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Disable interrupts again. */
|
||||
TX_DISABLE
|
||||
#endif
|
||||
|
||||
/* Determine if we need to reset the search. */
|
||||
if (group_ptr -> tx_event_flags_group_reset_search != TX_FALSE)
|
||||
{
|
||||
|
||||
/* Clear the reset search flag. */
|
||||
group_ptr -> tx_event_flags_group_reset_search = TX_FALSE;
|
||||
|
||||
/* Move the thread pointer to the beginning of the search list. */
|
||||
thread_ptr = suspended_list;
|
||||
|
||||
/* Reset the suspended count. */
|
||||
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
|
||||
|
||||
/* Update the current events with any new ones that might
|
||||
have been set in a nested set events call from an ISR. */
|
||||
current_event_flags = current_event_flags | group_ptr -> tx_event_flags_group_current;
|
||||
}
|
||||
|
||||
/* Save next thread pointer. */
|
||||
next_thread_ptr = thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Pickup the suspend information. */
|
||||
requested_flags = thread_ptr -> tx_thread_suspend_info;
|
||||
|
||||
/* Pickup this thread's suspension get option. */
|
||||
get_option = thread_ptr -> tx_thread_suspend_option;
|
||||
|
||||
/* Isolate the AND selection. */
|
||||
and_request = (get_option & TX_AND);
|
||||
|
||||
/* Check for AND condition. All flags must be present to satisfy request. */
|
||||
if (and_request == TX_AND)
|
||||
{
|
||||
|
||||
/* AND request is present. */
|
||||
|
||||
/* Calculate the flags present. */
|
||||
flags_satisfied = (current_event_flags & requested_flags);
|
||||
|
||||
/* Determine if they satisfy the AND request. */
|
||||
if (flags_satisfied != requested_flags)
|
||||
{
|
||||
|
||||
/* No, not all the requested flags are present. Clear the flags present variable. */
|
||||
flags_satisfied = ((ULONG) 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* OR request is present. Simply or the requested flags and the current flags. */
|
||||
flags_satisfied = (current_event_flags & requested_flags);
|
||||
}
|
||||
|
||||
/* Check to see if the thread had a timeout or wait abort during the event search processing.
|
||||
If so, just set the flags satisfied to ensure the processing here removes the thread from
|
||||
the suspension list. */
|
||||
if (thread_ptr -> tx_thread_state != TX_EVENT_FLAG)
|
||||
{
|
||||
|
||||
/* Simply set the satisfied flags to 1 in order to remove the thread from the suspension list. */
|
||||
flags_satisfied = ((ULONG) 1);
|
||||
}
|
||||
|
||||
/* Determine if the request is satisfied. */
|
||||
if (flags_satisfied != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Yes, this request can be handled now. */
|
||||
|
||||
/* Set the preempt check flag. */
|
||||
preempt_check = TX_TRUE;
|
||||
|
||||
/* Determine if the thread is still suspended on the event flag group. If not, a wait
|
||||
abort must have been done from an ISR. */
|
||||
if (thread_ptr -> tx_thread_state == TX_EVENT_FLAG)
|
||||
{
|
||||
|
||||
/* Return the actual event flags that satisfied the request. */
|
||||
suspend_info_ptr = TX_VOID_TO_ULONG_POINTER_CONVERT(thread_ptr -> tx_thread_additional_suspend_info);
|
||||
*suspend_info_ptr = current_event_flags;
|
||||
|
||||
/* Pickup the clear bit. */
|
||||
clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK);
|
||||
|
||||
/* Determine whether or not clearing needs to take place. */
|
||||
if (clear_request == TX_TRUE)
|
||||
{
|
||||
|
||||
/* Yes, clear the flags that satisfied this request. */
|
||||
group_ptr -> tx_event_flags_group_current = group_ptr -> tx_event_flags_group_current & ~requested_flags;
|
||||
}
|
||||
|
||||
/* Prepare for resumption of the first thread. */
|
||||
|
||||
/* Clear cleanup routine to avoid timeout. */
|
||||
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
|
||||
|
||||
/* Put return status into the thread control block. */
|
||||
thread_ptr -> tx_thread_suspend_status = TX_SUCCESS;
|
||||
}
|
||||
|
||||
/* We need to remove the thread from the suspension list and place it in the
|
||||
expired list. */
|
||||
|
||||
/* See if this is the only suspended thread on the list. */
|
||||
if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
|
||||
{
|
||||
|
||||
/* Yes, the only suspended thread. */
|
||||
|
||||
/* Update the head pointer. */
|
||||
suspended_list = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* At least one more thread is on the same expiration list. */
|
||||
|
||||
/* Update the links of the adjacent threads. */
|
||||
next_thread = thread_ptr -> tx_thread_suspended_next;
|
||||
previous_thread = thread_ptr -> tx_thread_suspended_previous;
|
||||
next_thread -> tx_thread_suspended_previous = previous_thread;
|
||||
previous_thread -> tx_thread_suspended_next = next_thread;
|
||||
|
||||
/* Update the list head pointer, if removing the head of the
|
||||
list. */
|
||||
if (suspended_list == thread_ptr)
|
||||
{
|
||||
|
||||
/* Yes, head pointer needs to be updated. */
|
||||
suspended_list = thread_ptr -> tx_thread_suspended_next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decrement the suspension count. */
|
||||
group_ptr -> tx_event_flags_group_suspended_count--;
|
||||
|
||||
/* Place this thread on the expired list. */
|
||||
if (satisfied_list == TX_NULL)
|
||||
{
|
||||
|
||||
/* First thread on the satisfied list. */
|
||||
satisfied_list = thread_ptr;
|
||||
last_satisfied = thread_ptr;
|
||||
|
||||
/* Setup initial next pointer. */
|
||||
thread_ptr -> tx_thread_suspended_next = TX_NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Not the first thread on the satisfied list. */
|
||||
|
||||
/* Link it up at the end. */
|
||||
last_satisfied -> tx_thread_suspended_next = thread_ptr;
|
||||
thread_ptr -> tx_thread_suspended_next = TX_NULL;
|
||||
last_satisfied = thread_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy next thread pointer to working thread ptr. */
|
||||
thread_ptr = next_thread_ptr;
|
||||
|
||||
/* Decrement the suspension count. */
|
||||
suspended_count--;
|
||||
|
||||
} while (suspended_count != TX_NO_SUSPENSIONS);
|
||||
|
||||
/* Setup the group's suspension list head again. */
|
||||
group_ptr -> tx_event_flags_group_suspension_list = suspended_list;
|
||||
|
||||
#ifndef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Determine if there is any delayed event clearing to perform. */
|
||||
if (group_ptr -> tx_event_flags_group_delayed_clear != ((ULONG) 0))
|
||||
{
|
||||
|
||||
/* Perform the delayed event clearing. */
|
||||
group_ptr -> tx_event_flags_group_current =
|
||||
group_ptr -> tx_event_flags_group_current & ~(group_ptr -> tx_event_flags_group_delayed_clear);
|
||||
|
||||
/* Clear the delayed event flag clear value. */
|
||||
group_ptr -> tx_event_flags_group_delayed_clear = ((ULONG) 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Walk through the satisfied list, setup initial thread pointer. */
|
||||
thread_ptr = satisfied_list;
|
||||
while(thread_ptr != TX_NULL)
|
||||
{
|
||||
|
||||
/* Get next pointer first. */
|
||||
next_thread_ptr = thread_ptr -> tx_thread_suspended_next;
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
#ifdef TX_NOT_INTERRUPTABLE
|
||||
|
||||
/* Resume the thread! */
|
||||
_tx_thread_system_ni_resume(thread_ptr);
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
#else
|
||||
|
||||
/* Disable preemption again. */
|
||||
_tx_thread_preempt_disable++;
|
||||
|
||||
/* Restore interrupt posture. */
|
||||
TX_RESTORE
|
||||
|
||||
/* Resume the thread. */
|
||||
_tx_thread_system_resume(thread_ptr);
|
||||
#endif
|
||||
|
||||
/* Move next thread to current. */
|
||||
thread_ptr = next_thread_ptr;
|
||||
}
|
||||
|
||||
/* Disable interrupts. */
|
||||
TX_DISABLE
|
||||
|
||||
/* Release thread preemption disable. */
|
||||
_tx_thread_preempt_disable--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* Determine if we need to set the reset search field. */
|
||||
if (group_ptr -> tx_event_flags_group_suspended_count != TX_NO_SUSPENSIONS)
|
||||
{
|
||||
|
||||
/* We interrupted a search of an event flag group suspension
|
||||
list. Make sure we reset the search. */
|
||||
group_ptr -> tx_event_flags_group_reset_search = TX_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore interrupts. */
|
||||
TX_RESTORE
|
||||
|
||||
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
|
||||
|
||||
/* Determine if a notify callback is required. */
|
||||
if (events_set_notify != TX_NULL)
|
||||
{
|
||||
|
||||
/* Call application event flags set notification. */
|
||||
(events_set_notify)(group_ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Determine if a check for preemption is necessary. */
|
||||
if (preempt_check == TX_TRUE)
|
||||
{
|
||||
|
||||
/* Yes, one or more threads were resumed, check for preemption. */
|
||||
_tx_thread_system_preempt_check();
|
||||
}
|
||||
}
|
||||
|
||||
/* Return completion status. */
|
||||
return(TX_SUCCESS);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user