@@ -137,30 +137,19 @@ static void tail_mask_set(atomic_t *tail_mask, size_t num_bits, size_t off)
137
137
138
138
/* If bit mask exceeds a single word then tail may spill to the adjacent word. */
139
139
size_t idx = tail_off / 32 ;
140
+ atomic_t * t_mask = & tail_mask [idx ];
140
141
141
142
tail_off = tail_off - 32 * idx ;
142
- if ((tail_off + tail_bits ) <= 32 ) {
143
- /* Tail mask fits in a single word. */
144
- atomic_or (& tail_mask [idx ], BIT_MASK (tail_bits ) << tail_off );
145
- return ;
146
- }
147
-
148
- /* Tail spilled. Remainder is set in the next word. Since number of tail_masks
149
- * match number of words in bitarray we don't need to check if we are exceeding
150
- * the array boundary.
151
- */
152
- atomic_or (& tail_mask [idx ], BIT_MASK (32 - tail_off ) << tail_off );
143
+ while (tail_bits > 0 ) {
144
+ uint32_t rem_bits = MIN (32 - tail_off , tail_bits );
145
+ uint32_t bits = MIN (tail_bits , rem_bits );
146
+ uint32_t mask = bits == 32 ? UINT32_MAX : (BIT_MASK (bits ) << tail_off );
153
147
154
-
155
- size_t rem_tail = tail_bits - (32 - tail_off );
156
- atomic_t * mask = & tail_mask [idx + 1 ];
157
-
158
- while (rem_tail >= 32 ) {
159
- atomic_or (mask , UINT32_MAX );
160
- mask ++ ;
161
- rem_tail -= 32 ;
148
+ atomic_or (t_mask , mask );
149
+ t_mask ++ ;
150
+ tail_off = 0 ;
151
+ tail_bits -= bits ;
162
152
}
163
- atomic_or (mask , BIT_MASK (rem_tail ));
164
153
}
165
154
166
155
/* Function determines how many chunks were used for the allocated buffer. It is
@@ -189,33 +178,37 @@ static uint32_t num_bits_get(atomic_t *tail_mask, size_t off)
189
178
return num_bits ;
190
179
}
191
180
192
- /* In multiword bit array we need to check if tail is spilling over to the next word. */
193
- size_t idx = off / 32 ;
194
- size_t w_off = off - 32 * idx ;
195
- atomic_t * t_mask = & tail_mask [idx ];
181
+ size_t tail_off = off + 1 ;
182
+ size_t idx = tail_off / 32 ;
196
183
197
- mask = (* t_mask | BIT (w_off )) >> w_off ;
198
- num_bits = (~mask == 0 ) ? 32 : __builtin_ctz (~mask );
199
- if (num_bits == 1 ) {
200
- return num_bits ;
184
+ tail_off = tail_off % 32 ;
185
+ if ((tail_mask [idx ] & BIT (tail_off )) == 0 ) {
186
+ return 1 ;
201
187
}
202
188
203
- mask = BIT_MASK (num_bits - 1 ) << (w_off + 1 );
204
- atomic_and (t_mask , ~mask );
205
- if (((w_off + num_bits ) == 32 ) && (idx < (HEAP_NUM_WORDS - 1 ))) {
206
- size_t tmp_bits ;
189
+ atomic_t * t_mask = & tail_mask [idx ];
190
+ num_bits = 1 ;
207
191
208
- /* If we are at the end of the one mask we need to check the beginning of the
209
- * next one as there might be remaining part of the tail.
210
- */
211
- do {
212
- t_mask ++ ;
213
- tmp_bits = (* t_mask == UINT32_MAX ) ? 32 : __builtin_ctz (~(* t_mask ));
214
- mask = (tmp_bits == 32 ) ? UINT32_MAX : BIT_MASK (tmp_bits );
192
+ do {
193
+ uint32_t mask = (uint32_t )* t_mask >> tail_off ;
194
+ uint32_t bits = (mask == UINT32_MAX ) ? 32 : __builtin_ctz (~mask );
195
+
196
+ num_bits += bits ;
197
+ if (mask == UINT32_MAX ) {
198
+
199
+ atomic_set (t_mask , 0 );
200
+ } else {
201
+ mask = BIT_MASK (bits ) << tail_off ;
215
202
atomic_and (t_mask , ~mask );
216
- num_bits += tmp_bits ;
217
- } while ((tmp_bits == 32 ) && (t_mask != & tail_mask [HEAP_NUM_WORDS - 1 ]));
218
- }
203
+ }
204
+
205
+ if ((bits + tail_off ) < 32 ) {
206
+ return num_bits ;
207
+ }
208
+
209
+ tail_off = 0 ;
210
+ t_mask ++ ;
211
+ } while (t_mask != & tail_mask [HEAP_NUM_WORDS ]);
219
212
220
213
return num_bits ;
221
214
}
0 commit comments