Jinoh Kang (@iamahuman) commented about dlls/ntdll/heap.c:
+}
+static inline struct block *group_get_block( struct group *group, SIZE_T block_size, UINT index ) +{
- char *first_block = (char *)&group->first_block;
- return (struct block *)(first_block + index * block_size);
+}
+/* lookup a free block using the group free_bits, the current thread must own the group */ +static inline LONG group_find_free_block( struct group *group, SIZE_T block_size, struct block **block ) +{
- ULONG i, free_bits = ReadNoFence( &group->free_bits );
- /* free_bits & ~GROUP_FLAG_FREE will never be 0 as the group is unlinked when it's fully used */
- BitScanForward( &i, free_bits & ~GROUP_FLAG_FREE );
- *block = group_get_block( group, block_size, i );
- return InterlockedAnd( &group->free_bits, ~(1 << i) ) & ~(1 << i);
Try not to use `InterlockedAnd`'s return value if you don't want it to transform to cmpxchg loop.