MCPcopy Create free account
hub / github.com/CppCXY/EmmyLuaCodeStyle / _mi_bitmap_try_find_claim_field

Function _mi_bitmap_try_find_claim_field

3rd/mimalloc-2.0.9/src/bitmap.c:44–95  ·  view source on GitHub ↗

Try to atomically claim a sequence of `count` bits in a single field at `idx` in `bitmap`. Returns `true` on success.

Source from the content-addressed store, hash-verified

42// Try to atomically claim a sequence of `count` bits in a single
43// field at `idx` in `bitmap`. Returns `true` on success.
44inline bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx)
45{
46 mi_assert_internal(bitmap_idx != NULL);
47 mi_assert_internal(count <= MI_BITMAP_FIELD_BITS);
48 mi_assert_internal(count > 0);
49 mi_bitmap_field_t* field = &bitmap[idx];
50 size_t map = mi_atomic_load_relaxed(field);
51 if (map==MI_BITMAP_FIELD_FULL) return false; // short cut
52
53 // search for 0-bit sequence of length count
54 const size_t mask = mi_bitmap_mask_(count, 0);
55 const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count;
56
57#ifdef MI_HAVE_FAST_BITSCAN
58 size_t bitidx = mi_ctz(~map); // quickly find the first zero bit if possible
59#else
60 size_t bitidx = 0; // otherwise start at 0
61#endif
62 size_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx
63
64 // scan linearly for a free range of zero bits
65 while (bitidx <= bitidx_max) {
66 const size_t mapm = map & m;
67 if (mapm == 0) { // are the mask bits free at bitidx?
68 mi_assert_internal((m >> bitidx) == mask); // no overflow?
69 const size_t newmap = map | m;
70 mi_assert_internal((newmap^map) >> bitidx == mask);
71 if (!mi_atomic_cas_weak_acq_rel(field, &map, newmap)) { // TODO: use strong cas here?
72 // no success, another thread claimed concurrently.. keep going (with updated `map`)
73 continue;
74 }
75 else {
76 // success, we claimed the bits!
77 *bitmap_idx = mi_bitmap_index_create(idx, bitidx);
78 return true;
79 }
80 }
81 else {
82 // on to the next bit range
83#ifdef MI_HAVE_FAST_BITSCAN
84 const size_t shift = (count == 1 ? 1 : mi_bsr(mapm) - bitidx + 1);
85 mi_assert_internal(shift > 0 && shift <= count);
86#else
87 const size_t shift = 1;
88#endif
89 bitidx += shift;
90 m <<= shift;
91 }
92 }
93 // no bits found
94 return false;
95}
96
97// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success.
98// Starts at idx, and wraps around to search in all `bitmap_fields` fields.

Calls 4

mi_bitmap_mask_Function · 0.85
mi_ctzFunction · 0.85
mi_bitmap_index_createFunction · 0.85
mi_bsrFunction · 0.85

Tested by

no test coverage detected