1//===-- Unittests for control group ---------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "src/__support/HashTable/bitmask.h"
10
11#include "src/stdlib/rand.h"
12#include "test/UnitTest/Test.h"
13#include <stdint.h>
14
15namespace LIBC_NAMESPACE {
16namespace internal {
17
18struct ByteArray {
19 alignas(Group) uint8_t data[sizeof(Group) + 1]{};
20};
21
22TEST(LlvmLibcHashTableBitMaskTest, Match) {
23 // Any pair of targets have bit differences not only at the lowest bit.
24 // No False positive.
25 uint8_t targets[4] = {0x00, 0x11, 0xFF, 0x0F};
26 size_t count[4] = {0, 0, 0, 0};
27 size_t appearance[4][sizeof(Group)];
28 ByteArray array{};
29
30 union {
31 uintptr_t random;
32 int data[sizeof(uintptr_t) / sizeof(int)];
33 };
34
35 for (int &i : data)
36 i = rand();
37
38 for (size_t i = 0; i < sizeof(Group); ++i) {
39 size_t choice = random % 4;
40 random /= 4;
41 array.data[i] = targets[choice];
42 appearance[choice][count[choice]++] = i;
43 }
44
45 for (size_t t = 0; t < sizeof(targets); ++t) {
46 auto bitmask = Group::load(addr: array.data).match_byte(byte: targets[t]);
47 for (size_t i = 0; i < count[t]; ++i) {
48 size_t iterated = 0;
49 for (size_t position : bitmask) {
50 ASSERT_EQ(appearance[t][iterated], position);
51 iterated++;
52 }
53 ASSERT_EQ(count[t], iterated);
54 }
55 }
56}
57
58TEST(LlvmLibcHashTableBitMaskTest, MaskAvailable) {
59 uint8_t values[3] = {0x00, 0x0F, 0x80};
60
61 for (size_t i = 0; i < sizeof(Group); ++i) {
62 ByteArray array{};
63
64 union {
65 uintptr_t random;
66 int data[sizeof(uintptr_t) / sizeof(int)];
67 };
68
69 for (int &j : data)
70 j = rand();
71
72 ASSERT_FALSE(Group::load(array.data).mask_available().any_bit_set());
73
74 array.data[i] = 0x80;
75 for (size_t j = 0; j < sizeof(Group); ++j) {
76 if (i == j)
77 continue;
78 size_t sample_space = 2 + (j > i);
79 size_t choice = random % sample_space;
80 random /= sizeof(values);
81 array.data[j] = values[choice];
82 }
83
84 auto mask = Group::load(addr: array.data).mask_available();
85 ASSERT_TRUE(mask.any_bit_set());
86 ASSERT_EQ(mask.lowest_set_bit_nonzero(), i);
87 }
88}
89} // namespace internal
90} // namespace LIBC_NAMESPACE
91

source code of libc/test/src/__support/HashTable/group_test.cpp