Jinoh Kang (@iamahuman) commented about dlls/ntdll/heap.c:
+{
- const char *blocks = (char *)(group + 1);
- block->base_offset = ((char *)block - blocks) / block_size;
+}
+static inline struct block *group_get_block( struct group *group, SIZE_T block_size, UINT index ) +{
- char *blocks = (char *)(group + 1);
- return (struct block *)(blocks + 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 ) +{ +#if defined(__GNUC__) && ((__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)))
- int i = __builtin_ffs( group->free_bits ) - 1;
Technically, this constitutes a data race since we're accessing a shared variable (concurrent access from `heap_free_block_lfh`) without volatile semantics. You should at least mark it volatile and load it to a local variable explicitly.