source: rtems-docs/porting/priority_bitmap.rst @ 489740f

4.115
Last change on this file since 489740f was 489740f, checked in by Chris Johns <chrisj@…>, on 05/20/16 at 02:47:09

Set SPDX License Identifier in each source file.

  • Property mode set to 100644
File size: 7.4 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3Priority Bitmap Manipulation
4############################
5
6Introduction
7============
8
9The RTEMS chain of ready tasks is implemented as an array of FIFOs with
10each priority having its own FIFO.  This makes it very efficient to
11determine the first and last ready task at each priority.  In addition,
12blocking a task only requires appending the task to the end of the FIFO
13for its priority rather than a lengthy search down a single chain of all
14ready tasks.  This works extremely well except for one problem.  When the
15currently executing task blocks, there may be no easy way to determine
16what is the next most important ready task.  If the blocking task was the
17only ready task at its priority, then RTEMS must search all of the FIFOs
18in the ready chain to determine the highest priority with a ready task.
19
20RTEMS uses a bitmap array to efficiently solve this problem.  The state of
21each bit in the priority map bit array indicates whether or not there is a
22ready task at that priority.  The bit array can be efficiently searched to
23determine the highest priority ready task.  This family of data type and
24routines is used to maintain and search the bit map array.
25
26When manipulating the bitmap array, RTEMS internally divides the
278 bits of the task priority into "major" and "minor" components.
28The most significant 4 bits are the major component, while the least
29significant are the minor component.  The major component of a priority
30value is used to determine which 16-bit wide entry in the``_Priority_Bit_map`` array is associated with this priority.
31Each element in the ``_Priority_Bit_map`` array has a bit
32in the ``_Priority_Major_bit_map`` associated with it.
33That bit is cleared when all of the bits in a particular``_Priority_Bit_map`` array entry are zero.
34
35The minor component of a priority is used to determine
36specifically which bit in ``_Priority_Bit_map[major]``
37indicates whether or not there is a ready to execute task
38at the priority.
39
40_Priority_bit_map_Control Type
41==============================
42
43The ``_Priority_Bit_map_Control`` type is the fundamental data type of the
44priority bit map array used to determine which priorities have ready
45tasks.  This type may be either 16 or 32 bits wide although only the 16
46least significant bits will be used.  The data type is based upon what is
47the most efficient type for this CPU to manipulate.  For example, some
48CPUs have bit scan instructions that only operate on a particular size of
49data.  In this case, this type will probably be defined to work with this
50instruction.
51
52Find First Bit Routine
53======================
54
55The _CPU_Bitfield_Find_first_bit routine sets _output to the bit number of
56the first bit set in ``_value``.  ``_value`` is of CPU dependent type``Priority_bit_map_Control``.  A stub version of this routine is as follows:
57.. code:: c
58
59    #define _CPU_Bitfield_Find_first_bit( _value, _output ) \\
60    { \\
61    (_output) = 0;   /* do something to prevent warnings \*/ \\
62    }
63
64There are a number of variables in using a "find first bit" type
65instruction.
66
67# What happens when run on a value of zero?
68
69# Bits may be numbered from MSB to LSB or vice-versa.
70
71# The numbering may be zero or one based.
72
73# The "find first bit" instruction may search from MSB or LSB.
74
75RTEMS guarantees that (1) will never happen so it is not a concern.
76Cases (2),(3), (4) are handled by the macros _CPU_Priority_mask() and
77_CPU_Priority_bits_index().  These three form a set of routines which must
78logically operate together.  Bits in the ``_value`` are set and cleared based
79on masks built by CPU_Priority_mask().  The basic major and minor values
80calculated by _Priority_Major() and _Priority_Minor() are "massaged" by
81_CPU_Priority_bits_index() to properly range between the values returned
82by the "find first bit" instruction.  This makes it possible for
83_Priority_Get_highest() to calculate the major and directly index into the
84minor table.  This mapping is necessary to ensure that 0 (a high priority
85major/minor) is the first bit found.
86
87This entire "find first bit" and mapping process depends heavily on the
88manner in which a priority is broken into a major and minor components
89with the major being the 4 MSB of a priority and minor the 4 LSB.  Thus (0
90<< 4) + 0 corresponds to priority 0 - the highest priority.  And (15 <<
914) + 14 corresponds to priority 254 - the next to the lowest priority.
92
93If your CPU does not have a "find first bit" instruction, then there are
94ways to make do without it.  Here are a handful of ways to implement this
95in software:
96
97- a series of 16 bit test instructions
98
99- a "binary search using if's"
100
101- the following algorithm based upon a 16 entry lookup table.  In this pseudo-code, bit_set_table[16] has values which indicate the first bit set:
102
103  .. code:: c
104
105      _number = 0 if _value > 0x00ff
106      _value >>=8
107      _number = 8;
108      if _value > 0x0000f
109      _value >=8
110      _number += 4
111      _number += bit_set_table[ _value ]
112
113The following illustrates how the CPU_USE_GENERIC_BITFIELD_CODE macro may
114be so the port can use the generic implementation of this bitfield code.
115This can be used temporarily during the porting process to avoid writing
116these routines until the end.  This results in a functional although lower
117performance port.  This is perfectly acceptable during development and
118testing phases.
119.. code:: c
120
121    #define CPU_USE_GENERIC_BITFIELD_CODE TRUE
122    #define CPU_USE_GENERIC_BITFIELD_DATA TRUE
123
124Eventually, CPU specific implementations of these routines are usually
125written since they dramatically impact the performance of blocking
126operations.  However they may take advantage of instructions which are not
127available on all models in the CPU family.  In this case, one might find
128something like this stub example did:
129.. code:: c
130
131    #if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
132    #define _CPU_Bitfield_Find_first_bit( _value, _output ) \\
133    { \\
134    (_output) = 0;   /* do something to prevent warnings \*/ \\
135    }
136    #endif
137
138Build Bit Field Mask
139====================
140
141The _CPU_Priority_Mask routine builds the mask that corresponds to the bit
142fields searched by _CPU_Bitfield_Find_first_bit().  See the discussion of
143that routine for more details.
144
145The following is a typical implementation when the
146_CPU_Bitfield_Find_first_bit searches for the most significant bit set:
147.. code:: c
148
149    #if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
150    #define _CPU_Priority_Mask( _bit_number ) \\
151    ( 1 << (_bit_number) )
152    #endif
153
154Bit Scan Support
155================
156
157The ``_CPU_Priority_bits_index`` routine translates the bit numbers
158returned by ``_CPU_Bitfield_Find_first_bit()`` into something
159suitable for use as a major or minor component of a priority.
160The find first bit routine may number the bits in a
161way that is difficult to map into the major and minor components
162of the priority.  For example, when finding the first bit set in
163the value 0x8000, a CPU may indicate that bit 15 or 16 is set
164based on whether the least significant bit is "zero" or "one".
165Similarly, a CPU may only scan 32-bit values and consider the
166most significant bit to be bit zero or one.  In this case, this
167would be bit 16 or 17.
168
169This routine allows that unwieldy form to be converted
170into a normalized form that is easier to process and use
171as an index.
172.. code:: c
173
174    #if (CPU_USE_GENERIC_BITFIELD_CODE == FALSE)
175    #define _CPU_Priority_bits_index( _priority ) \\
176    (_priority)
177    #endif
178
179.. COMMENT: COPYRIGHT (c) 1988-2002.
180
181.. COMMENT: On-Line Applications Research Corporation (OAR).
182
183.. COMMENT: All rights reserved.
184
Note: See TracBrowser for help on using the repository browser.