OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rtems-20020807/] [doc/] [porting/] [prioritybitmap.t] - Blame information for rev 1782

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.