1 /* Simple and straight-forward malloc implementation (front end).
3 Copyright (C) 2020-2025 Free Software Foundation, Inc.
5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
10 This file is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18 /* Written by Bruno Haible <bruno@clisp.org>, 2020. */
20 /* ===================== Low-level functions for bitmaps ==================== */
22 /* A bitmap is represented as an array of uint32_t = 'unsigned int', each with
23 32 bits. The bit i in the word with index j therefore represents bit
24 k = 32 * j + i of the entire bit sequence. */
26 /* Initializes a bitmap. */
28 init_bitmap_all_bits_clear (size_t num_words
, uint32_t *words
)
31 for (i
= 0; i
< num_words
; i
++)
35 /* Initializes a bitmap. */
37 init_bitmap_all_bits_set (size_t num_words
, uint32_t *words
)
40 for (i
= 0; i
< num_words
; i
++)
41 words
[i
] = ~(uint32_t)0;
44 /* Returns the smallest index k >= k0 for which the bit k is set in the bitmap
45 consisting of num_words words. Returns (size_t)(-1) if there is none. */
47 find_first_bit_set (size_t num_words
, const uint32_t *words
, size_t k0
)
53 const uint32_t *ptr
= words
+ j0
;
54 /* Look at the word j0, ignoring the i0 least significant bits. */
56 size_t found
= ffs (*ptr
& (-1U << i0
));
58 return 32 * j0
+ (found
- 1);
60 /* Look at the subsequent words. */
61 const uint32_t *words_end
= words
+ num_words
;
62 while (++ptr
< words_end
)
64 size_t found
= ffs (*ptr
);
66 return 32 * (ptr
- words
) + (found
- 1);
72 /* Returns the smallest index k >= 0 for which the bit packet of c consecutive
73 bits (1 <= c <= 32) is all set in the bitmap consisting of num_words words.
74 Returns (size_t)(-1) if there is none. */
76 find_first_packet_set (size_t num_words
, const uint32_t *words
, size_t c
)
78 const uint32_t *ptr
= words
;
79 const uint32_t *words_end
= words
+ num_words
;
84 /* A simplified variant of find_first_bit_set. */
85 for (; ptr
< words_end
; ptr
++)
87 size_t found
= ffs (*ptr
);
89 return 32 * (ptr
- words
) + (found
- 1);
95 while (ptr
< words_end
)
97 uint64_t longword
= *ptr
++;
98 if (likely (ptr
< words_end
))
99 longword
|= ((uint64_t) *ptr
) << 32;
100 uint64_t combined
= longword
& (longword
>> 1);
101 size_t found
= ffsll (combined
);
103 return 32 * (ptr
- 1 - words
) + (found
- 1);
109 while (ptr
< words_end
)
111 uint64_t longword
= *ptr
++;
112 if (likely (ptr
< words_end
))
113 longword
|= ((uint64_t) *ptr
) << 32;
114 uint64_t combined
= longword
& (longword
>> 1) & (longword
>> 2);
115 size_t found
= ffsll (combined
);
117 return 32 * (ptr
- 1 - words
) + (found
- 1);
123 while (ptr
< words_end
)
125 uint64_t longword
= *ptr
++;
126 if (likely (ptr
< words_end
))
127 longword
|= ((uint64_t) *ptr
) << 32;
128 uint64_t tmp1
= longword
& (longword
>> 1);
129 uint64_t combined
= tmp1
& (tmp1
>> 2);
130 size_t found
= ffsll (combined
);
132 return 32 * (ptr
- 1 - words
) + (found
- 1);
138 while (ptr
< words_end
)
140 uint64_t longword
= *ptr
++;
141 if (likely (ptr
< words_end
))
142 longword
|= ((uint64_t) *ptr
) << 32;
143 uint64_t tmp1
= longword
& (longword
>> 1);
144 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
145 uint64_t combined
= tmp2
& (longword
>> 4);
146 size_t found
= ffsll (combined
);
148 return 32 * (ptr
- 1 - words
) + (found
- 1);
154 while (ptr
< words_end
)
156 uint64_t longword
= *ptr
++;
157 if (likely (ptr
< words_end
))
158 longword
|= ((uint64_t) *ptr
) << 32;
159 uint64_t tmp1
= longword
& (longword
>> 1);
160 uint64_t combined
= tmp1
& (tmp1
>> 2) & (tmp1
>> 4);
161 size_t found
= ffsll (combined
);
163 return 32 * (ptr
- 1 - words
) + (found
- 1);
169 while (ptr
< words_end
)
171 uint64_t longword
= *ptr
++;
172 if (likely (ptr
< words_end
))
173 longword
|= ((uint64_t) *ptr
) << 32;
174 uint64_t tmp1
= longword
& (longword
>> 1);
176 tmp1
& (tmp1
>> 2) & (tmp1
>> 4) & (longword
>> 6);
177 size_t found
= ffsll (combined
);
179 return 32 * (ptr
- 1 - words
) + (found
- 1);
185 while (ptr
< words_end
)
187 uint64_t longword
= *ptr
++;
188 if (likely (ptr
< words_end
))
189 longword
|= ((uint64_t) *ptr
) << 32;
190 uint64_t tmp1
= longword
& (longword
>> 1);
191 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
192 uint64_t combined
= tmp2
& (tmp2
>> 4);
193 size_t found
= ffsll (combined
);
195 return 32 * (ptr
- 1 - words
) + (found
- 1);
201 while (ptr
< words_end
)
203 uint64_t longword
= *ptr
++;
204 if (likely (ptr
< words_end
))
205 longword
|= ((uint64_t) *ptr
) << 32;
206 uint64_t tmp1
= longword
& (longword
>> 1);
207 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
208 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
209 uint64_t combined
= tmp3
& (longword
>> 8);
210 size_t found
= ffsll (combined
);
212 return 32 * (ptr
- 1 - words
) + (found
- 1);
218 while (ptr
< words_end
)
220 uint64_t longword
= *ptr
++;
221 if (likely (ptr
< words_end
))
222 longword
|= ((uint64_t) *ptr
) << 32;
223 uint64_t tmp1
= longword
& (longword
>> 1);
224 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
225 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
226 uint64_t combined
= tmp3
& (tmp1
>> 8);
227 size_t found
= ffsll (combined
);
229 return 32 * (ptr
- 1 - words
) + (found
- 1);
235 while (ptr
< words_end
)
237 uint64_t longword
= *ptr
++;
238 if (likely (ptr
< words_end
))
239 longword
|= ((uint64_t) *ptr
) << 32;
240 uint64_t tmp1
= longword
& (longword
>> 1);
241 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
242 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
243 uint64_t combined
= tmp3
& (tmp1
>> 8) & (longword
>> 10);
244 size_t found
= ffsll (combined
);
246 return 32 * (ptr
- 1 - words
) + (found
- 1);
252 while (ptr
< words_end
)
254 uint64_t longword
= *ptr
++;
255 if (likely (ptr
< words_end
))
256 longword
|= ((uint64_t) *ptr
) << 32;
257 uint64_t tmp1
= longword
& (longword
>> 1);
258 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
259 uint64_t combined
= tmp2
& (tmp2
>> 4) & (tmp2
>> 8);
260 size_t found
= ffsll (combined
);
262 return 32 * (ptr
- 1 - words
) + (found
- 1);
268 while (ptr
< words_end
)
270 uint64_t longword
= *ptr
++;
271 if (likely (ptr
< words_end
))
272 longword
|= ((uint64_t) *ptr
) << 32;
273 uint64_t tmp1
= longword
& (longword
>> 1);
274 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
276 tmp2
& (tmp2
>> 4) & (tmp2
>> 8) & (longword
>> 12);
277 size_t found
= ffsll (combined
);
279 return 32 * (ptr
- 1 - words
) + (found
- 1);
285 while (ptr
< words_end
)
287 uint64_t longword
= *ptr
++;
288 if (likely (ptr
< words_end
))
289 longword
|= ((uint64_t) *ptr
) << 32;
290 uint64_t tmp1
= longword
& (longword
>> 1);
291 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
292 uint64_t combined
= tmp2
& (tmp2
>> 4) & (tmp2
>> 8) & (tmp1
>> 12);
293 size_t found
= ffsll (combined
);
295 return 32 * (ptr
- 1 - words
) + (found
- 1);
301 while (ptr
< words_end
)
303 uint64_t longword
= *ptr
++;
304 if (likely (ptr
< words_end
))
305 longword
|= ((uint64_t) *ptr
) << 32;
306 /* Optimized: Use 5, not 6, '&' operations. */
307 uint64_t tmp1
= longword
& (longword
>> 1);
308 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
309 uint64_t tmp3
= tmp2
& (longword
>> 4);
310 uint64_t combined
= tmp3
& (tmp3
>> 5) & (tmp3
>> 10);
311 size_t found
= ffsll (combined
);
313 return 32 * (ptr
- 1 - words
) + (found
- 1);
319 while (ptr
< words_end
)
321 uint64_t longword
= *ptr
++;
322 if (likely (ptr
< words_end
))
323 longword
|= ((uint64_t) *ptr
) << 32;
324 uint64_t tmp1
= longword
& (longword
>> 1);
325 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
326 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
327 uint64_t combined
= tmp3
& (tmp3
>> 8);
328 size_t found
= ffsll (combined
);
330 return 32 * (ptr
- 1 - words
) + (found
- 1);
336 while (ptr
< words_end
)
338 uint64_t longword
= *ptr
++;
339 if (likely (ptr
< words_end
))
340 longword
|= ((uint64_t) *ptr
) << 32;
341 uint64_t tmp1
= longword
& (longword
>> 1);
342 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
343 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
344 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
345 uint64_t combined
= tmp4
& (longword
>> 16);
346 size_t found
= ffsll (combined
);
348 return 32 * (ptr
- 1 - words
) + (found
- 1);
354 while (ptr
< words_end
)
356 uint64_t longword
= *ptr
++;
357 if (likely (ptr
< words_end
))
358 longword
|= ((uint64_t) *ptr
) << 32;
359 uint64_t tmp1
= longword
& (longword
>> 1);
360 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
361 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
362 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
363 uint64_t combined
= tmp4
& (tmp1
>> 16);
364 size_t found
= ffsll (combined
);
366 return 32 * (ptr
- 1 - words
) + (found
- 1);
372 while (ptr
< words_end
)
374 uint64_t longword
= *ptr
++;
375 if (likely (ptr
< words_end
))
376 longword
|= ((uint64_t) *ptr
) << 32;
377 uint64_t tmp1
= longword
& (longword
>> 1);
378 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
379 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
380 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
381 uint64_t combined
= tmp4
& (tmp1
>> 16) & (longword
>> 18);
382 size_t found
= ffsll (combined
);
384 return 32 * (ptr
- 1 - words
) + (found
- 1);
390 while (ptr
< words_end
)
392 uint64_t longword
= *ptr
++;
393 if (likely (ptr
< words_end
))
394 longword
|= ((uint64_t) *ptr
) << 32;
395 uint64_t tmp1
= longword
& (longword
>> 1);
396 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
397 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
398 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
399 uint64_t combined
= tmp4
& (tmp2
>> 16);
400 size_t found
= ffsll (combined
);
402 return 32 * (ptr
- 1 - words
) + (found
- 1);
408 while (ptr
< words_end
)
410 uint64_t longword
= *ptr
++;
411 if (likely (ptr
< words_end
))
412 longword
|= ((uint64_t) *ptr
) << 32;
413 uint64_t tmp1
= longword
& (longword
>> 1);
414 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
415 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
416 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
417 uint64_t combined
= tmp4
& (tmp2
>> 16) & (longword
>> 20);
418 size_t found
= ffsll (combined
);
420 return 32 * (ptr
- 1 - words
) + (found
- 1);
426 while (ptr
< words_end
)
428 uint64_t longword
= *ptr
++;
429 if (likely (ptr
< words_end
))
430 longword
|= ((uint64_t) *ptr
) << 32;
431 uint64_t tmp1
= longword
& (longword
>> 1);
432 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
433 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
434 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
435 uint64_t combined
= tmp4
& (tmp2
>> 16) & (tmp1
>> 20);
436 size_t found
= ffsll (combined
);
438 return 32 * (ptr
- 1 - words
) + (found
- 1);
444 while (ptr
< words_end
)
446 uint64_t longword
= *ptr
++;
447 if (likely (ptr
< words_end
))
448 longword
|= ((uint64_t) *ptr
) << 32;
449 uint64_t tmp1
= longword
& (longword
>> 1);
450 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
451 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
452 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
454 tmp4
& (tmp2
>> 16) & (tmp1
>> 20) & (longword
>> 22);
455 size_t found
= ffsll (combined
);
457 return 32 * (ptr
- 1 - words
) + (found
- 1);
463 while (ptr
< words_end
)
465 uint64_t longword
= *ptr
++;
466 if (likely (ptr
< words_end
))
467 longword
|= ((uint64_t) *ptr
) << 32;
468 uint64_t tmp1
= longword
& (longword
>> 1);
469 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
470 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
471 uint64_t combined
= tmp3
& (tmp3
>> 8) & (tmp3
>> 16);
472 size_t found
= ffsll (combined
);
474 return 32 * (ptr
- 1 - words
) + (found
- 1);
480 while (ptr
< words_end
)
482 uint64_t longword
= *ptr
++;
483 if (likely (ptr
< words_end
))
484 longword
|= ((uint64_t) *ptr
) << 32;
485 uint64_t tmp1
= longword
& (longword
>> 1);
486 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
487 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
489 tmp3
& (tmp3
>> 8) & (tmp3
>> 16) & (longword
>> 24);
490 size_t found
= ffsll (combined
);
492 return 32 * (ptr
- 1 - words
) + (found
- 1);
498 while (ptr
< words_end
)
500 uint64_t longword
= *ptr
++;
501 if (likely (ptr
< words_end
))
502 longword
|= ((uint64_t) *ptr
) << 32;
503 uint64_t tmp1
= longword
& (longword
>> 1);
504 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
505 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
507 tmp3
& (tmp3
>> 8) & (tmp3
>> 16) & (tmp1
>> 24);
508 size_t found
= ffsll (combined
);
510 return 32 * (ptr
- 1 - words
) + (found
- 1);
516 while (ptr
< words_end
)
518 uint64_t longword
= *ptr
++;
519 if (likely (ptr
< words_end
))
520 longword
|= ((uint64_t) *ptr
) << 32;
521 /* Optimized: Use 6, not 7, '&' operations. */
522 uint64_t tmp1
= longword
& (longword
>> 1);
523 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
524 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
525 uint64_t tmp4
= tmp3
& (longword
>> 8);
526 uint64_t combined
= tmp4
& (tmp4
>> 9) & (tmp4
>> 18);
527 size_t found
= ffsll (combined
);
529 return 32 * (ptr
- 1 - words
) + (found
- 1);
535 while (ptr
< words_end
)
537 uint64_t longword
= *ptr
++;
538 if (likely (ptr
< words_end
))
539 longword
|= ((uint64_t) *ptr
) << 32;
540 uint64_t tmp1
= longword
& (longword
>> 1);
541 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
542 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
544 tmp3
& (tmp3
>> 8) & (tmp3
>> 16) & (tmp2
>> 24);
545 size_t found
= ffsll (combined
);
547 return 32 * (ptr
- 1 - words
) + (found
- 1);
553 while (ptr
< words_end
)
555 uint64_t longword
= *ptr
++;
556 if (likely (ptr
< words_end
))
557 longword
|= ((uint64_t) *ptr
) << 32;
558 uint64_t tmp1
= longword
& (longword
>> 1);
559 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
560 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
562 tmp3
& (tmp3
>> 8) & (tmp3
>> 16) & (tmp2
>> 24) & (longword
>> 28);
563 size_t found
= ffsll (combined
);
565 return 32 * (ptr
- 1 - words
) + (found
- 1);
571 while (ptr
< words_end
)
573 uint64_t longword
= *ptr
++;
574 if (likely (ptr
< words_end
))
575 longword
|= ((uint64_t) *ptr
) << 32;
576 /* Optimized: Use 6, not 7, '&' operations. */
577 uint64_t tmp1
= longword
& (longword
>> 1);
578 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
579 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
580 uint64_t tmp4
= tmp3
& (tmp1
>> 8);
581 uint64_t combined
= tmp4
& (tmp4
>> 10) & (tmp4
>> 20);
582 size_t found
= ffsll (combined
);
584 return 32 * (ptr
- 1 - words
) + (found
- 1);
590 while (ptr
< words_end
)
592 uint64_t longword
= *ptr
++;
593 if (likely (ptr
< words_end
))
594 longword
|= ((uint64_t) *ptr
) << 32;
595 uint64_t tmp1
= longword
& (longword
>> 1);
596 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
597 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
598 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
600 tmp4
& (tmp3
>> 16) & (tmp2
>> 24) & (tmp1
>> 28) & (longword
>> 30);
601 size_t found
= ffsll (combined
);
603 return 32 * (ptr
- 1 - words
) + (found
- 1);
609 while (ptr
< words_end
)
611 uint64_t longword
= *ptr
++;
612 if (likely (ptr
< words_end
))
613 longword
|= ((uint64_t) *ptr
) << 32;
614 uint64_t tmp1
= longword
& (longword
>> 1);
615 uint64_t tmp2
= tmp1
& (tmp1
>> 2);
616 uint64_t tmp3
= tmp2
& (tmp2
>> 4);
617 uint64_t tmp4
= tmp3
& (tmp3
>> 8);
618 uint64_t combined
= tmp4
& (tmp4
>> 16);
619 size_t found
= ffsll (combined
);
621 return 32 * (ptr
- 1 - words
) + (found
- 1);
626 /* Invalid argument. */