summaryrefslogblamecommitdiffstats
path: root/cpukit/score/include/rtems/score/prioritybitmapimpl.h
blob: de90ef77ae595327f4787e4b31f38bbf33e5f586 (plain) (tree)
1
2
3
4
5
6
7



                                                                         
  

                                                                     







                                                           
                                         

   



                                         
                                 
 

                   


                  

   
                            
   
        
 






                                                                  
                                            































                                                                               
                                                                       
          
                                                                       






























                                                                              

   
                                                           

   
                                                              


                               
                                                      


   
                                                           

   
                                                              


                               
                                                      


                                             
 
   

                                                                    
   
 
                                                             


                       
                                                        
 
 
   
                                               
   
 
                                                                    


                 
                                        

 
   


                                                                    
   
 








                                                      





                                                       

   
                                        


                                                 

                                            

 

                                                      

 
                                                    

                                            

 


                                                        

 


                                                                    
 

                              
 







                                                      




                                               


                                                     
 
                                     

 
                                                                   


                                             

 


                              



                                          
                                                                           

                                 
                                   
                                                                                
                                                                         

                                 
                                   
                                                                                
                                                                         

 
         
 



                  

                         
/**
 * @file
 *
 * @brief Inlined Routines in the Priority Handler Bit Map Implementation
 *
 * This file contains the static inline implementation of all inlined
 * routines in the Priority Handler bit map implementation
 */

/*
 *  COPYRIGHT (c) 1989-2010.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 */

#ifndef _RTEMS_SCORE_PRIORITYBITMAPIMPL_H
#define _RTEMS_SCORE_PRIORITYBITMAPIMPL_H

#include <rtems/score/prioritybitmap.h>
#include <rtems/score/priority.h>

#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @addtogroup ScorePriority
 */
/**@{**/

#if ( CPU_USE_GENERIC_BITFIELD_DATA == TRUE )

/**
 *  This table is used by the generic bitfield routines to perform
 *  a highly optimized bit scan without the use of special CPU
 *  instructions.
 */
extern const unsigned char __log2table[256];

#endif

/**
 *  @brief Gets the @a _bit_number of the first bit set in the specified value.
 *
 *  This routine returns the @a _bit_number of the first bit set
 *  in the specified value.  The correspondence between @a _bit_number
 *  and actual bit position is processor dependent.  The search for
 *  the first bit set may run from most to least significant bit
 *  or vice-versa.
 *
 *  @param[in] _value is the value to bit scan.
 *  @param[in] _bit_number is the position of the first bit set.
 *
 *  @note This routine is used when the executing thread is removed
 *  from the ready state and, as a result, its performance has a
 *  significant impact on the performance of the executive as a whole.
 *
 *  @note This routine must be a macro because if a CPU specific version
 *  is used it will most likely use inline assembly.
 */
#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
#define _Bitfield_Find_first_bit( _value, _bit_number ) \
        _CPU_Bitfield_Find_first_bit( _value, _bit_number )
#else
#define _Bitfield_Find_first_bit( _value, _bit_number ) \
  { \
    register uint32_t   __value = (uint32_t) (_value); \
    register const unsigned char *__p = __log2table; \
    \
    if ( __value < 0x100 ) \
      (_bit_number) = (Priority_bit_map_Word)( __p[ __value ] + 8 );  \
    else \
      (_bit_number) = (Priority_bit_map_Word)( __p[ __value >> 8 ] ); \
  }
#endif

#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
/**
 *  This method returns the priority bit mask for the specified major
 *  or minor bit number.
 *
 *  @param[in] _bit_number is the bit number for which we need a mask
 *
 *  @retval the priority bit mask
 *
 *  @note This may simply be a pass through to a CPU dependent implementation.
 */
#define _Priority_Mask( _bit_number ) \
  _CPU_Priority_Mask( _bit_number )
#endif

#if ( CPU_USE_GENERIC_BITFIELD_CODE == FALSE )
/**
 *  This method returns the bit index position for the specified priority.
 *
 *  @param[in] _priority is the priority for which we need the index.
 *
 *  @retval This method returns the array index into the priority bit map.
 *
 *  @note This may simply be a pass through to a CPU dependent implementation.
 */
#define _Priority_Bits_index( _priority ) \
  _CPU_Priority_bits_index( _priority )
#endif

/**
 * This function returns the major portion of the_priority.
 */

RTEMS_INLINE_ROUTINE Priority_bit_map_Word   _Priority_Major (
  Priority_Control the_priority
)
{
  return (Priority_bit_map_Word)( the_priority / 16 );
}

/**
 * This function returns the minor portion of the_priority.
 */

RTEMS_INLINE_ROUTINE Priority_bit_map_Word   _Priority_Minor (
  Priority_Control the_priority
)
{
  return (Priority_bit_map_Word)( the_priority % 16 );
}

#if ( CPU_USE_GENERIC_BITFIELD_CODE == TRUE )

/**
 * This function returns the mask associated with the major or minor
 * number passed to it.
 */

RTEMS_INLINE_ROUTINE Priority_bit_map_Word   _Priority_Mask (
  uint32_t   bit_number
)
{
  return (Priority_bit_map_Word)(0x8000u >> bit_number);
}

/**
 * This function returns the mask bit inverted.
 */

RTEMS_INLINE_ROUTINE Priority_bit_map_Word   _Priority_Mask_invert (
  uint32_t   mask
)
{
  return (Priority_bit_map_Word)(~mask);
}

/**
 * This function translates the bit numbers returned by the bit scan
 * of a priority bit field into something suitable for use as
 * a major or minor component of a priority.
 */

RTEMS_INLINE_ROUTINE uint32_t   _Priority_Bits_index (
  uint32_t   bit_number
)
{
  return bit_number;
}

#endif

RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize(
  Priority_bit_map_Control *bit_map
)
{
  memset( bit_map, 0, sizeof( *bit_map ) );
}

/**
 * Priority Queue implemented by bit map
 */

RTEMS_INLINE_ROUTINE void _Priority_bit_map_Add (
  Priority_bit_map_Control     *bit_map,
  Priority_bit_map_Information *bit_map_info
)
{
  *bit_map_info->minor |= bit_map_info->ready_minor;
  bit_map->major_bit_map |= bit_map_info->ready_major;
}

RTEMS_INLINE_ROUTINE void _Priority_bit_map_Remove (
  Priority_bit_map_Control     *bit_map,
  Priority_bit_map_Information *bit_map_info
)
{
  *bit_map_info->minor &= bit_map_info->block_minor;
  if ( *bit_map_info->minor == 0 )
    bit_map->major_bit_map &= bit_map_info->block_major;
}

RTEMS_INLINE_ROUTINE Priority_Control _Priority_bit_map_Get_highest(
  const Priority_bit_map_Control *bit_map
)
{
  Priority_bit_map_Word minor;
  Priority_bit_map_Word major;

  /* Avoid problems with some inline ASM statements */
  Priority_bit_map_Word tmp;

  tmp = bit_map->major_bit_map;
  _Bitfield_Find_first_bit( tmp, major );

  tmp = bit_map->bit_map[ major ];
  _Bitfield_Find_first_bit( tmp, minor );

  return (_Priority_Bits_index( major ) << 4) +
          _Priority_Bits_index( minor );
}

RTEMS_INLINE_ROUTINE bool _Priority_bit_map_Is_empty(
  const Priority_bit_map_Control *bit_map
)
{
  return bit_map->major_bit_map == 0;
}

RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information(
  Priority_bit_map_Control     *bit_map,
  Priority_bit_map_Information *bit_map_info,
  Priority_Control              new_priority
)
{
  Priority_bit_map_Word major;
  Priority_bit_map_Word minor;
  Priority_bit_map_Word mask;

  major = _Priority_Major( new_priority );
  minor = _Priority_Minor( new_priority );

  bit_map_info->minor = &bit_map->bit_map[ _Priority_Bits_index( major ) ];

  mask = _Priority_Mask( major );
  bit_map_info->ready_major = mask;
  /* Add _Priority_Mask_invert to non-generic bitfield then change this code. */
  bit_map_info->block_major = (Priority_bit_map_Word)(~((uint32_t)mask));

  mask = _Priority_Mask( minor );
  bit_map_info->ready_minor = mask;
  /* Add _Priority_Mask_invert to non-generic bitfield then change this code. */
  bit_map_info->block_minor = (Priority_bit_map_Word)(~((uint32_t)mask));
}

/** @} */

#ifdef __cplusplus
}
#endif

#endif
/* end of include file */