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

📄 em.c

📁 NecluesRTX RTOS的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*                                                                      */
/************************************************************************/
void  EM_Remove_From_List(struct EM_SUSPENSION_STRUCT **ptr_head_ptr,
       struct EM_SUSPENSION_STRUCT **ptr_tail_ptr,
       struct EM_SUSPENSION_STRUCT *suspend_ptr)
{

    /*  Determine if this suspension block is still linked in.  */
    if ((suspend_ptr -> em_prev_susp != NU_NULL) || 
            (suspend_ptr -> em_next_susp != NU_NULL) ||
                                       (suspend_ptr == *ptr_head_ptr))
    {
    
        /* Check the previous pointers.  */
        if (suspend_ptr -> em_prev_susp != NU_NULL)
        {
        
           /* Link the previous suspension block to the next.  */
           (suspend_ptr -> em_prev_susp) -> em_next_susp =  
                                                suspend_ptr -> em_next_susp;
        }
        else
        {
        
            /* We are deleting the head node, adjust the head pointer.  */
            *ptr_head_ptr =   suspend_ptr -> em_next_susp;
            
            /* Adjust the head of the list.  */
            if (*ptr_head_ptr != NU_NULL)
                   (*ptr_head_ptr) -> em_prev_susp =  NU_NULL;
        }
        
        /* Check the next pointers.  */
        if (suspend_ptr -> em_next_susp != NU_NULL)
        {
        
            /* Link the next suspension block to the previous.  */
            (suspend_ptr -> em_next_susp) -> em_prev_susp =
                                                 suspend_ptr -> em_prev_susp;
        }
        else
        {
        
            /* We are deleting the tail node, adjust the tail pointer.  */
            *ptr_tail_ptr =  suspend_ptr -> em_prev_susp;

            /* Adjust the tail of the list.  */
            if (*ptr_tail_ptr != NU_NULL)
               (*ptr_tail_ptr) -> em_next_susp =  NU_NULL;
        }
  
        /* Reset the pointers of the removed suspension block.  */        
        suspend_ptr -> em_next_susp =    NU_NULL;
        suspend_ptr -> em_prev_susp =    NU_NULL;
    }           
}                                           /* end  EM_Remove_From_List */



/************************************************************************/
/*                                                                      */
/*  FUNCTION                                "EM_Set_Events"             */
/*                                                                      */
/*                                                                      */
/*  DESCRIPTION                                                         */
/*                                                                      */
/*      This function sets event flags of the specified event group     */
/*      and checks to see if there are any suspended tasks that are     */
/*      now able to proceceed.                                          */
/*                                                                      */
/*  AUTHOR                                                              */
/*                                                                      */
/*      William E. Lamie,  Accelerated Technology                       */
/*                                                                      */
/*  CALLED FROM                                                         */
/*                                                                      */
/*      Service routines that set event flags                           */
/*                                                                      */
/*  ROUTINES CALLED                                                     */
/*                                                                      */
/*      EM_Remove_From_List                 Lift task suspension        */
/*      SKP_Ready_Task                      Place the task on ready lst */
/*      SKD_Leave_Task                      Leave the task if necessary */
/*                                                                      */
/*  INPUTS                                                              */
/*                                                                      */
/*      event_group_id                      Event group identification  */
/*      event_operation                     How to apply the events     */
/*      event_flags                         New event flags             */
/*                                                                      */
/*  OUTPUTS                                                             */
/*                                                                      */
/*      return(status)                                                  */
/*                                                                      */
/************************************************************************/
signed int  EM_Set_Events(signed int event_group_id,
             signed int event_operation, unsigned int event_flags)
{

struct EM_EVENT_CONTROL_STRUCT  
                  *ECB_ptr;                 /* Pointer to ECB entry     */
struct EM_SUSPENSION_STRUCT
                  *suspend_ptr;             /* Suspension pointer       */
unsigned int       compare;                 /* Event compare field      */
unsigned int       consume;                 /* Event consume bits       */
unsigned int       lift;                    /* Lift suspension flag     */
signed int         context_switch =  0;     /* Context switch counter   */
    
    /* Point to the event group control block.  */
    ECB_ptr =  &EM_ECB_List[event_group_id];
    
    /* Initialize the events to consume to 0.  */
    consume =  0;

    /* Apply the new event flags to this group.  */
    if (event_operation == NU_EVENT_AND)
    
        /* And the new events with the current groups events.  */
        ECB_ptr -> em_event_flags =  ECB_ptr -> em_event_flags & event_flags;
    else
    
        /* Or the new events with the current group events.  */
        ECB_ptr -> em_event_flags =  ECB_ptr -> em_event_flags | event_flags;

    
    /* Walk through the list of suspended tasks to see if any can be 
       resumed.  */
    suspend_ptr =  ECB_ptr -> em_wait_head;
    
    while (suspend_ptr != NU_NULL)
    {
    
        /* Initialize the lift suspension flag to false.  */
        lift =  NU_FALSE;
    
        /* Determine if the suspened task can be resumed, i.e. see if the
           appropriate events have taken place.  */
        if ((suspend_ptr -> em_operation == NU_EVENT_AND) ||
            (suspend_ptr -> em_operation == NU_EVENT_AND_CONSUME))
        {
        
            /* Need all of the bits in the request set in the event group
               to lift suspension.  */
            compare =  ECB_ptr -> em_event_flags & suspend_ptr -> em_flags;
            
            /* If compare is equal to the value suspended on, lift the 
               suspension.  */
            if (compare == suspend_ptr -> em_flags)
            {
                /* Set lift suspension flag.  */
                lift =  NU_TRUE;
                
                /* Determine if the original request specified a consume.  */
                if (suspend_ptr -> em_operation == NU_EVENT_AND_CONSUME)
                
                    /* Or in the events of this request into the consume
                       accumulator.  */
                    consume =  consume | suspend_ptr -> em_flags;
            }
        }
        else
        {
        
            /* Need just one of the bits in the request to lift suspension. */
            compare =  ECB_ptr -> em_event_flags & suspend_ptr -> em_flags;
            
            /* If compare has any bits set, at least one of the bits in the
               request has been set.  */
            if (compare)
            {
                /* Set lift suspension flag.  */
                lift =  NU_TRUE;

                /* Determine if the original request specified a consume.  */
                if (suspend_ptr -> em_operation == NU_EVENT_OR_CONSUME)
                
                    /* Or in the events of this request into the consume
                       accumulator.  */
                    consume =  consume | suspend_ptr -> em_flags;
            }
        }
            
        /* Lift the suspension, if necessary.  */
        if (lift)
        {
                
            /* Put the contents of the event flag group in the designated
               place.  */
            *(suspend_ptr -> em_flags_value) =  ECB_ptr -> em_event_flags;

            /* Show that the request completed successfully.  */
            *(suspend_ptr -> em_return_addr) =  NU_SUCCESS;

            /* Lift the suspension on the task that was waiting 
               for the resource.  At the end of this loop the context 
               switch variable is greater than 0 if a context switch is 
               called for.  */
            context_switch =  context_switch + 
                              SKP_Ready_Task(suspend_ptr -> em_task_id);

            /* Remove the suspend pointer from the suspend list.  */
            EM_Remove_From_List(&(EM_ECB_List[event_group_id].em_wait_head),
                                &(EM_ECB_List[event_group_id].em_wait_tail), 
                                suspend_ptr);

            /* Point to the next suspension block.  This was updated by the
               previous call.  */
            suspend_ptr =  ECB_ptr -> em_wait_head;
        }
        else        
        
            /* Just get the next suspension pointer.  */
            suspend_ptr =  suspend_ptr -> em_next_susp;
    }

    /* Apply the consume bits into the event flag.  */
    ECB_ptr -> em_event_flags =  ECB_ptr -> em_event_flags & ~consume;
    
    /* Determine if a context switch is required.  */
    if (context_switch)
    {
                
        /* Leave this task temporarily.  */
        SKD_Leave_Task();
    }
    
    /* Return the status to the caller.  */
    return(NU_SUCCESS);
}                                           /* end of EM_Set_Events     */



⌨️ 快捷键说明

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