⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tx_efs.c

📁 该代码是在单片机MCU中实现多线程的嵌入式操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
                TX_RESTORE

                /* Return successful status.  */
                return(TX_SUCCESS);
            }
        }

        /* 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_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_suspension_list =  TX_NULL;
        
        /* Setup the satisfied thread pointers.  */
        satisfied_list =  TX_NULL;
        last_satisfied =  TX_NULL;

        /* Setup the suspended count.  */      
        suspended_count =  group_ptr -> tx_event_flags_suspended_count;

        /* Pickup the current event flags.  */
        current_event_flags =  group_ptr -> tx_event_flags_current;

        /* Disable preemption while we process the suspended list.  */
        _tx_thread_preempt_disable++;

        /* Loop to examine all of the suspended threads. */
        do 
        {

            /* Restore interrupts temporarily.  */
            TX_RESTORE

            /* Disable interrupts again.  */
            TX_DISABLE

            /* Determine if we need to reset the search.  */
            if (group_ptr -> tx_event_flags_reset_search)
            {

                /* Clear the reset search flag.  */
                group_ptr -> tx_event_flags_reset_search =  0;

                /* 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_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_current;

                /* Determine if we need to get out of this loop.  */
                if (!thread_ptr)
                    break;
            }

            /* Pickup this thread's suspension get option.  */
            get_option =  thread_ptr -> tx_suspend_option;

            /* Determine if this thread's get event flag request has been met.  */
            if (get_option & TX_EVENT_FLAGS_AND_MASK)
            {

                /* All flags must be present to satisfy request.  */
                if ((current_event_flags & thread_ptr -> tx_suspend_info) == 
                                                thread_ptr -> tx_suspend_info)
    
                    /* 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 (current_event_flags & thread_ptr -> tx_suspend_info)

                    /* 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;
            }
                
            /* Save next thread pointer.  */
            next_thread_ptr =  thread_ptr -> tx_suspended_next;

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

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

                /* Return the actual event flags that satisfied the request.  */
                *((ULONG *) thread_ptr -> tx_additional_suspend_info) =  current_event_flags;

                /* 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 & ~(thread_ptr -> tx_suspend_info);
            
                /* 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_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 list head pointer, if removing the head of the
                       list.  */
                    if (suspended_list == thread_ptr)
                        suspended_list =  thread_ptr -> tx_suspended_next;

                    /* Update the links of the adjacent threads.  */
                    (thread_ptr -> tx_suspended_next) -> tx_suspended_previous =  
                                                    thread_ptr -> tx_suspended_previous;
                    (thread_ptr -> tx_suspended_previous) -> tx_suspended_next =
                                                    thread_ptr -> tx_suspended_next;
                } 
                
                /* Decrement the suspension count.  */
                group_ptr -> tx_event_flags_suspended_count--;

                /* Prepare for resumption of the first thread.  */

                /* Clear cleanup routine to avoid timeout.  */
                thread_ptr -> tx_suspend_cleanup =  TX_NULL;

                /* Put return status into the thread control block.  */
                thread_ptr -> tx_suspend_status =  TX_SUCCESS;        

                /* Place this thread on the expired list.  */
                if (!satisfied_list)
                {

                    /* First thread on the satisfied list.  */
                    satisfied_list =  thread_ptr;
                    last_satisfied =  thread_ptr;
    
                    /* Setup intial next pointer.  */
                    thread_ptr -> tx_suspended_next =  TX_NULL;
                }
                else
                {

                    /* Not the first thread on the satisfied list.  */
                
                    /* Link it up at the end.  */
                    last_satisfied -> tx_suspended_next =  thread_ptr;
                    thread_ptr -> tx_suspended_next =      TX_NULL;
                    last_satisfied =                       thread_ptr;
                }
            }

            /* Copy next thread pointer to working thread ptr.  */
            thread_ptr =  next_thread_ptr;

        } while (--suspended_count);

        /* Setup the group's suspension list head again.  */
        group_ptr -> tx_event_flags_suspension_list =  suspended_list;

        /* Restore interrupts.  */
        TX_RESTORE

        /* Walk through the satisfied list, setup initial thread pointer. */
        thread_ptr =  satisfied_list;
        while(thread_ptr)
        {
    
            /* Get next pointer first.  */
            next_thread_ptr =  thread_ptr -> tx_suspended_next;

            /* Deactivate the timeout timer if necessary.  */
            if (thread_ptr -> tx_thread_timer.tx_list_head)
            {

                /* Deactivate the thread's timeout timer.  */
                _tx_timer_deactivate(&(thread_ptr -> tx_thread_timer));
            }
            else
            {

                /* Clear the remaining time to ensure timer doesn't get activated.  */
                thread_ptr -> tx_thread_timer.tx_remaining_ticks =  0;
            }

            /* Disable interrupts.  */
            TX_DISABLE

            /* Disable preemption again.  */
            _tx_thread_preempt_disable++;

            /* Restore interrupt posture.  */
            TX_RESTORE

            /* Resume the thread.  */
            _tx_thread_resume(thread_ptr);

            /* Move next thread to current.  */
            thread_ptr =  next_thread_ptr;
        }

        /* Disable interrupts.  */
        TX_DISABLE

        /* Release thread preemption disable.  */
        _tx_thread_preempt_disable--;

        /* Restore interrupts.  */
        TX_RESTORE

        /* Now determine if preemption is required.  */
		if ((_tx_thread_current_ptr != _tx_thread_execute_ptr) && (_tx_thread_system_state == 0))
		{

            /* Preemption is required, transfer control back to 
               system.  */
            _tx_thread_system_return();
        }
    }
    else
    {

        /* Determine if we need to set the reset search field.  */
        if (group_ptr -> tx_event_flags_suspended_count)
            
            /* We interrupted a search of an event flag group suspension
               list.  Make sure we reset the search.  */
            group_ptr -> tx_event_flags_reset_search++;

        /* Restore interrupts.  */
        TX_RESTORE
    }

    /* Return completion status.  */
    return(TX_SUCCESS);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -