mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Update to TommyDS v4.0
This commit is contained in:
parent
a39fb132f8
commit
9505499e15
21 changed files with 2220 additions and 959 deletions
|
|
@ -1604,8 +1604,8 @@ void fs_allocate(struct snapraid_disk* disk, block_off_t parity_pos, struct snap
|
|||
extent = extent_alloc(parity_pos, file, file_pos, count);
|
||||
|
||||
/* insert the extent in the trees */
|
||||
parity_extent = tommy_tree_insert(&disk->fs_parity, &extent->parity_node, extent);
|
||||
file_extent = tommy_tree_insert(&disk->fs_file, &extent->file_node, extent);
|
||||
parity_extent = tommy_tree_insert_unique(&disk->fs_parity, &extent->parity_node, extent);
|
||||
file_extent = tommy_tree_insert_unique(&disk->fs_file, &extent->file_node, extent);
|
||||
|
||||
if (parity_extent != extent || file_extent != extent) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
@ -1689,8 +1689,8 @@ void fs_deallocate(struct snapraid_disk* disk, block_off_t parity_pos)
|
|||
second_extent = extent_alloc(extent->parity_pos + first_count + 1, extent->file, extent->file_pos + first_count + 1, second_count);
|
||||
|
||||
/* insert the extent in the trees */
|
||||
parity_extent = tommy_tree_insert(&disk->fs_parity, &second_extent->parity_node, second_extent);
|
||||
file_extent = tommy_tree_insert(&disk->fs_file, &second_extent->file_node, second_extent);
|
||||
parity_extent = tommy_tree_insert_unique(&disk->fs_parity, &second_extent->parity_node, second_extent);
|
||||
file_extent = tommy_tree_insert_unique(&disk->fs_file, &second_extent->file_node, second_extent);
|
||||
|
||||
if (parity_extent != second_extent || file_extent != second_extent) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
|
|||
|
|
@ -119,6 +119,23 @@ void* malloc_nofail(size_t size)
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void* realloc_nofail(void* ptr, size_t size)
|
||||
{
|
||||
/* keep zero-size requests allocated, as in malloc_nofail() */
|
||||
void* new_ptr = realloc(ptr, size ? size : 1);
|
||||
|
||||
if (!new_ptr) {
|
||||
/* LCOV_EXCL_START */
|
||||
malloc_fail(size);
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
malloc_counter_inc(size);
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
void* nalloc_nofail(size_t count, size_t size)
|
||||
{
|
||||
if (size != 0 && count > SIZE_MAX / size) {
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@ void memory_single_thread(int single_thread);
|
|||
*/
|
||||
void* malloc_nofail(size_t size);
|
||||
|
||||
/**
|
||||
* Safe realloc.
|
||||
* If no memory is available, it aborts.
|
||||
*/
|
||||
void* realloc_nofail(void* ptr, size_t size);
|
||||
|
||||
/**
|
||||
* Safe malloc with calloc calling arguments.
|
||||
* If no memory is available, it aborts.
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ static const uint64_t MUSEAIR_CONSTANT[13] = {
|
|||
do { \
|
||||
l = a; \
|
||||
h = b; \
|
||||
util_mum(&l, &h); \
|
||||
tommy_mum(&l, &h); \
|
||||
} while (0)
|
||||
|
||||
#define likely(a) tommy_likely(a)
|
||||
|
|
|
|||
|
|
@ -51,25 +51,25 @@ struct hash_test_vector {
|
|||
* Test vectors for tommy_hash32
|
||||
*/
|
||||
static struct hash32_test_vector TEST_HASH32[] = {
|
||||
{ "", 0, 0x8614384c, 0xa766795d },
|
||||
{ "a", 1, 0x12c16c36, 0xa766795d },
|
||||
{ "abc", 3, 0xc58e8af5, 0xa766795d },
|
||||
{ "message digest", 14, 0x006b32f1, 0xa766795d },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x7e6fcfe0, 0xa766795d },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, 0x8604adf8, 0xa766795d },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, 0xdeba3d3a, 0xa766795d },
|
||||
{ "\x00", 1, 0x4a7d1c33, 0xa766795d },
|
||||
{ "\x16\x27", 2, 0x8b50899b, 0xa766795d },
|
||||
{ "\xe2\x56\xb4", 3, 0x60406493, 0xa766795d },
|
||||
{ "\xc9\x4d\x9c\xda", 4, 0xa049144a, 0xa766795d },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, 0x4da2c2f1, 0xa766795d },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, 0x59de30cf, 0xa766795d },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, 0x219e149c, 0xa766795d },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, 0x25067520, 0xa766795d },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, 0xa1f368d8, 0xa766795d },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, 0x805fc63d, 0xa766795d },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, 0x7f75dd0f, 0xa766795d },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, 0xb9154382, 0xa766795d },
|
||||
{ "", 0, 0x1138f522, 0xa766795d },
|
||||
{ "a", 1, 0x3366e86d, 0xa766795d },
|
||||
{ "abc", 3, 0x7a017599, 0xa766795d },
|
||||
{ "message digest", 14, 0xd11d9402, 0xa766795d },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x9e379e7b, 0xa766795d },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, 0x429490b3, 0xa766795d },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, 0xa720287c, 0xa766795d },
|
||||
{ "\x00", 1, 0xf0afd007, 0xa766795d },
|
||||
{ "\x16\x27", 2, 0x7d78b59a, 0xa766795d },
|
||||
{ "\xe2\x56\xb4", 3, 0x1690ec86, 0xa766795d },
|
||||
{ "\xc9\x4d\x9c\xda", 4, 0xa9efc35d, 0xa766795d },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, 0xf138ecc1, 0xa766795d },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, 0xb3f64b75, 0xa766795d },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, 0x27f94e67, 0xa766795d },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, 0x3770a9f5, 0xa766795d },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, 0xd98ebad1, 0xa766795d },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, 0xe7f0bdc0, 0xa766795d },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, 0xaf9a9089, 0xa766795d },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, 0x605ceb65, 0xa766795d },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -77,29 +77,29 @@ static struct hash32_test_vector TEST_HASH32[] = {
|
|||
* Test vectors for tommy_strhash32
|
||||
*/
|
||||
struct strhash32_test_vector TEST_STRHASH32[] = {
|
||||
{ "", 0x0af1416d, 0xa766795d },
|
||||
{ "a", 0x68fa0f3f, 0xa766795d },
|
||||
{ "abc", 0xfc68ffc5, 0xa766795d },
|
||||
{ "message digest", 0x08477b63, 0xa766795d },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 0x5b9c25e5, 0xa766795d },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0x1e530ce7, 0xa766795d },
|
||||
{ "The quick brown fox jumps over the lazy dog", 0xaf93eefe, 0xa766795d },
|
||||
{ "\xff", 0xfc88801b, 0xa766795d },
|
||||
{ "\x16\x27", 0xcd7216db, 0xa766795d },
|
||||
{ "\xe2\x56\xb4", 0x05f98d02, 0xa766795d },
|
||||
{ "\xc9\x4d\x9c\xda", 0xf65206f8, 0xa766795d },
|
||||
{ "\x79\xf1\x29\x69\x5d", 0x72bd6bda, 0xa766795d },
|
||||
{ "\xff\x7e\xdf\x1e\x31\x1c", 0x57dfb9b4, 0xa766795d },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 0x499ff634, 0xa766795d },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 0xe896b7ce, 0xa766795d },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 0xfe3939f0, 0xa766795d },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 0x4351d482, 0xa766795d },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\xff\xb7\xae", 0x88e92135, 0xa766795d },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 0x01109c16, 0xa766795d },
|
||||
{ "\x87\xd8\x61\x61\x4c\x89\x17\x4e\xa1\xa4\xef\x13\xa9", 0xbcb050dc, 0xa766795d },
|
||||
{ "\xfe\xa6\x5b\xc2\xda\xe8\x95\xd4\x64\xab\x4c\x39\x58\x29", 0xbe5e1fd5, 0xa766795d },
|
||||
{ "\x94\x49\xc0\x78\xa0\x80\xda\xc7\x71\x4e\x17\x37\xa9\x7c\x40", 0x70d8c97f, 0xa766795d },
|
||||
{ "\x53\x7e\x36\xb4\x2e\xc9\xb9\xcc\x18\x3e\x9a\x5f\xfc\xb7\xb0\x61", 0x957440a9, 0xa766795d },
|
||||
{ "", 0x1138f522, 0xa766795d },
|
||||
{ "a", 0x3366e86d, 0xa766795d },
|
||||
{ "abc", 0x7a017599, 0xa766795d },
|
||||
{ "message digest", 0xd11d9402, 0xa766795d },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 0x9e379e7b, 0xa766795d },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0x429490b3, 0xa766795d },
|
||||
{ "The quick brown fox jumps over the lazy dog", 0xa720287c, 0xa766795d },
|
||||
{ "\xff", 0xa9d0ff62, 0xa766795d },
|
||||
{ "\x16\x27", 0x7d78b59a, 0xa766795d },
|
||||
{ "\xe2\x56\xb4", 0x1690ec86, 0xa766795d },
|
||||
{ "\xc9\x4d\x9c\xda", 0xa9efc35d, 0xa766795d },
|
||||
{ "\x79\xf1\x29\x69\x5d", 0xf138ecc1, 0xa766795d },
|
||||
{ "\xff\x7e\xdf\x1e\x31\x1c", 0xc9633d79, 0xa766795d },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 0x27f94e67, 0xa766795d },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 0x3770a9f5, 0xa766795d },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 0xd98ebad1, 0xa766795d },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 0xe7f0bdc0, 0xa766795d },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\xff\xb7\xae", 0x1c63af47, 0xa766795d },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 0x605ceb65, 0xa766795d },
|
||||
{ "\x87\xd8\x61\x61\x4c\x89\x17\x4e\xa1\xa4\xef\x13\xa9", 0x1a41ce84, 0xa766795d },
|
||||
{ "\xfe\xa6\x5b\xc2\xda\xe8\x95\xd4\x64\xab\x4c\x39\x58\x29", 0xae824889, 0xa766795d },
|
||||
{ "\x94\x49\xc0\x78\xa0\x80\xda\xc7\x71\x4e\x17\x37\xa9\x7c\x40", 0x879c5032, 0xa766795d },
|
||||
{ "\x53\x7e\x36\xb4\x2e\xc9\xb9\xcc\x18\x3e\x9a\x5f\xfc\xb7\xb0\x61", 0x5234d367, 0xa766795d },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -107,25 +107,25 @@ struct strhash32_test_vector TEST_STRHASH32[] = {
|
|||
* Test vectors for tommy_hash64
|
||||
*/
|
||||
static struct hash64_test_vector TEST_HASH64[] = {
|
||||
{ "", 0, 0x8614384cb5165fbfULL, 0x2f022773a766795dULL },
|
||||
{ "a", 1, 0x1a2e0298a8e94a3dULL, 0x2f022773a766795dULL },
|
||||
{ "abc", 3, 0x7555796b7a7d21ebULL, 0x2f022773a766795dULL },
|
||||
{ "message digest", 14, 0x9411a57d04b92fb4ULL, 0x2f022773a766795dULL },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, 0x3ca3f8d2b4e69832ULL, 0x2f022773a766795dULL },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, 0x6dae542ba0015a4dULL, 0x2f022773a766795dULL },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, 0xe06d8cbb3d2ea1a6ULL, 0x2f022773a766795dULL },
|
||||
{ "\x00", 1, 0x201e664fb5f2c021ULL, 0x2f022773a766795dULL },
|
||||
{ "\x16\x27", 2, 0xef42fa8032c4b775ULL, 0x2f022773a766795dULL },
|
||||
{ "\xe2\x56\xb4", 3, 0x6e6c498a6688466cULL, 0x2f022773a766795dULL },
|
||||
{ "\xc9\x4d\x9c\xda", 4, 0x5195005419905423ULL, 0x2f022773a766795dULL },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, 0x221235b48afee7c1ULL, 0x2f022773a766795dULL },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, 0x1b1f18b9266f095bULL, 0x2f022773a766795dULL },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, 0x2cbafa8e741d49caULL, 0x2f022773a766795dULL },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, 0x4677f04c06e0758dULL, 0x2f022773a766795dULL },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, 0x5afe09e8214e2163ULL, 0x2f022773a766795dULL },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, 0x115b6276d209fab6ULL, 0x2f022773a766795dULL },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, 0xd0636d2f01cf3a3eULL, 0x2f022773a766795dULL },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, 0x6d259f5fef74f93eULL, 0x2f022773a766795dULL },
|
||||
{ "", 0, 0xf64d2d2164ca4e35ULL, 0x2f022773a766795dULL },
|
||||
{ "a", 1, 0xcb0b7863fd912608ULL, 0x2f022773a766795dULL },
|
||||
{ "abc", 3, 0x023adbd4412dfbc2ULL, 0x2f022773a766795dULL },
|
||||
{ "message digest", 14, 0x8d16f620b58a030eULL, 0x2f022773a766795dULL },
|
||||
{ "abcdefghijklmnopqrstuvwxyz", 26, 0xa615ea6b87f2b63fULL, 0x2f022773a766795dULL },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62, 0xb9f145676ebdb4fcULL, 0x2f022773a766795dULL },
|
||||
{ "The quick brown fox jumps over the lazy dog", 43, 0x99b05c9548b523dcULL, 0x2f022773a766795dULL },
|
||||
{ "\x00", 1, 0x432204e0ea8617fbULL, 0x2f022773a766795dULL },
|
||||
{ "\x16\x27", 2, 0x5118c58166c6ab3eULL, 0x2f022773a766795dULL },
|
||||
{ "\xe2\x56\xb4", 3, 0x29484604a9976acbULL, 0x2f022773a766795dULL },
|
||||
{ "\xc9\x4d\x9c\xda", 4, 0xf000ac44a9f98f4aULL, 0x2f022773a766795dULL },
|
||||
{ "\x79\xf1\x29\x69\x5d", 5, 0x9603fc74ec52e5aaULL, 0x2f022773a766795dULL },
|
||||
{ "\x00\x7e\xdf\x1e\x31\x1c", 6, 0xd39f549b363c8e2bULL, 0x2f022773a766795dULL },
|
||||
{ "\x2a\x4c\xe1\xff\x9e\x6f\x53", 7, 0x1be47d9f53a2a31dULL, 0x2f022773a766795dULL },
|
||||
{ "\xba\x02\xab\x18\x30\xc5\x0e\x8a", 8, 0xe3fa24e31af8c4ebULL, 0x2f022773a766795dULL },
|
||||
{ "\xec\x4e\x7a\x72\x1e\x71\x2a\xc9\x33", 9, 0xef8c3dcec426a25dULL, 0x2f022773a766795dULL },
|
||||
{ "\xfd\xe2\x9c\x0f\x72\xb7\x08\xea\xd0\x78", 10, 0xed0be01a88bde7cbULL, 0x2f022773a766795dULL },
|
||||
{ "\x65\xc4\x8a\xb8\x80\x86\x9a\x79\x00\xb7\xae", 11, 0xf9b50d9db5dfa543ULL, 0x2f022773a766795dULL },
|
||||
{ "\x77\xe9\xd7\x80\x0e\x3f\x5c\x43\xc8\xc2\x46\x39", 12, 0x695329dad2094e8aULL, 0x2f022773a766795dULL },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -188,6 +188,13 @@ static void test_hash(void)
|
|||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
digest = tommy_hash_u32(TEST_STRHASH32[i].seed, buffer_aligned, strlen(TEST_STRHASH32[i].data));
|
||||
if (digest != TEST_STRHASH32[i].digest) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EINTERNAL, "Failed strhash32 test\n");
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; TEST_HASH64[i].data; ++i) {
|
||||
|
|
@ -456,7 +463,7 @@ static void test_tommy(void)
|
|||
tommy_arrayblkof_init(&arrayblkof, sizeof(unsigned));
|
||||
|
||||
for (i = 0; i < TOMMY_SIZE; ++i) {
|
||||
tommy_array_insert(&array, &node[i]);
|
||||
tommy_array_insert_tail(&array, &node[i]);
|
||||
tommy_arrayblkof_grow(&arrayblkof, i + 1);
|
||||
*(unsigned*)tommy_arrayblkof_ref(&arrayblkof, i) = i;
|
||||
}
|
||||
|
|
@ -584,7 +591,11 @@ static void test_tommy(void)
|
|||
tommy_tree_insert(&tree, &node[i], (void*)(uintptr_t)(i + 1));
|
||||
|
||||
/* try to insert a duplicate, count should not change */
|
||||
tommy_tree_insert(&tree, &node[TOMMY_SIZE], (void*)(uintptr_t)1);
|
||||
if (tommy_tree_insert_unique(&tree, &node[TOMMY_SIZE], (void*)(uintptr_t)1) != (void*)(uintptr_t)1) {
|
||||
/* LCOV_EXCL_START */
|
||||
goto bail;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (tommy_tree_count(&tree) != TOMMY_SIZE) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
|
|||
119
cmdline/util.c
119
cmdline/util.c
|
|
@ -7,6 +7,7 @@
|
|||
#include "util.h"
|
||||
#include "raid/cpu.h"
|
||||
#include "raid/memory.h"
|
||||
#include "tommyds/tommyhash.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/* memory */
|
||||
|
|
@ -610,112 +611,6 @@ static inline void util_write64(void* ptr, uint64_t v)
|
|||
memcpy(ptr, &v, sizeof(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* 64*64 -> 128bit multiply function.
|
||||
*
|
||||
* @param A Address of 64-bit number.
|
||||
* @param B Address of 64-bit number.
|
||||
*
|
||||
* Calculates 128-bit C = *A * *B.
|
||||
*
|
||||
* Overwrites A contents with C's low 64 bits.
|
||||
* Overwrites B contents with C's high 64 bits.
|
||||
*/
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
/**
|
||||
* This is intentionally placed before the __SIZEOF_INT128__ implementation.
|
||||
*
|
||||
* This implementation happens to generate more efficient code.
|
||||
* While this likely depends only on the compiler, as long as it remains faster,
|
||||
* we will keep it in this order.
|
||||
*/
|
||||
static inline void util_mum(uint64_t* A, uint64_t* B)
|
||||
{
|
||||
uint64_t a = *A;
|
||||
uint64_t b = *B;
|
||||
uint64_t low, high;
|
||||
|
||||
__asm__ (
|
||||
"mulq %3"
|
||||
: "=a" (low), "=d" (high)
|
||||
: "a" (a), "rm" (b)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
*A = low;
|
||||
*B = high;
|
||||
}
|
||||
#elif defined(__SIZEOF_INT128__)
|
||||
static inline void util_mum(uint64_t* A, uint64_t* B)
|
||||
{
|
||||
__uint128_t product = ((__uint128_t)*A) * ((__uint128_t)*B);
|
||||
*A = (uint64_t)product;
|
||||
*B = (uint64_t)(product >> 64);
|
||||
}
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
/**
|
||||
* This is intentionally placed after the __SIZEOF_INT128__ implementation.
|
||||
*
|
||||
* Although the code looks correct, there is a report of this
|
||||
* implementation failing the self-test on macOS (Darwin 25.4.0, arm64)
|
||||
* with Apple clang 21.0.0 (clang-2100.0.123.102).
|
||||
*
|
||||
* See: https://github.com/amadvance/snapraid/issues/43
|
||||
*
|
||||
* Note that the implementation is the same of OpenSSL:
|
||||
*
|
||||
* #elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG)
|
||||
* #if defined(__GNUC__) && __GNUC__ >= 2
|
||||
* #define BN_UMULT_HIGH(a, b) ({ \
|
||||
* register BN_ULONG ret; \
|
||||
* asm ("umulh %0,%1,%2" \
|
||||
* : "=r"(ret) \
|
||||
* : "r"(a), "r"(b)); \
|
||||
* ret; })
|
||||
* #endif
|
||||
* #endif
|
||||
*
|
||||
* See: https://github.com/openssl/openssl/blob/0463cbf185680e66a3a8960f10cd33001377d28e/crypto/bn/bn_local.h#L439
|
||||
*/
|
||||
static inline void util_mum(uint64_t* A, uint64_t* B)
|
||||
{
|
||||
uint64_t a = *A;
|
||||
uint64_t b = *B;
|
||||
uint64_t low = a * b;
|
||||
uint64_t high;
|
||||
__asm__ (
|
||||
"umulh %0, %1, %2"
|
||||
: "=r" (high)
|
||||
: "r" (a), "r" (b)
|
||||
);
|
||||
*A = low;
|
||||
*B = high;
|
||||
}
|
||||
#else
|
||||
static inline void util_mum(uint64_t* A, uint64_t* B)
|
||||
{
|
||||
uint64_t a = *A;
|
||||
uint64_t b = *B;
|
||||
|
||||
uint64_t a_lo = (uint32_t)a;
|
||||
uint64_t a_hi = a >> 32;
|
||||
uint64_t b_lo = (uint32_t)b;
|
||||
uint64_t b_hi = b >> 32;
|
||||
|
||||
uint64_t p0 = a_lo * b_lo;
|
||||
uint64_t p1 = a_lo * b_hi;
|
||||
uint64_t p2 = a_hi * b_lo;
|
||||
uint64_t p3 = a_hi * b_hi;
|
||||
|
||||
uint64_t middle = p1 + (p0 >> 32) + (uint32_t)p2;
|
||||
uint64_t low = (middle << 32) | (uint32_t)p0;
|
||||
uint64_t high = p3 + (middle >> 32) + (p2 >> 32);
|
||||
|
||||
*A = low;
|
||||
*B = high;
|
||||
}
|
||||
#endif
|
||||
|
||||
int util_selftest(void)
|
||||
{
|
||||
/* rotate left 32-bit */
|
||||
|
|
@ -748,33 +643,33 @@ int util_selftest(void)
|
|||
if (util_rotr64(0x123456789ABCDEF0ULL, 0) != 0x123456789ABCDEF0ULL) return -1;
|
||||
if (util_rotr64(0x123456789ABCDEF0ULL, 64) != 0x123456789ABCDEF0ULL) return -1;
|
||||
|
||||
/* util_mum tests */
|
||||
/* tommy_mum tests */
|
||||
uint64_t a, b;
|
||||
|
||||
/* small values */
|
||||
a = 3; b = 4;
|
||||
util_mum(&a, &b);
|
||||
tommy_mum(&a, &b);
|
||||
if (a != 12 || b != 0) return -1;
|
||||
|
||||
/* 1 * anything */
|
||||
a = 0xFFFFFFFFFFFFFFFFULL; b = 1;
|
||||
util_mum(&a, &b);
|
||||
tommy_mum(&a, &b);
|
||||
if (a != 0xFFFFFFFFFFFFFFFFULL || b != 0) return -1;
|
||||
|
||||
/* (2^32) * (2^32) = 2^64 */
|
||||
a = 1ULL << 32; b = 1ULL << 32;
|
||||
util_mum(&a, &b);
|
||||
tommy_mum(&a, &b);
|
||||
if (a != 0 || b != 1) return -1;
|
||||
|
||||
/* max uint64 * max uint64 */
|
||||
a = 0xFFFFFFFFFFFFFFFFULL; b = 0xFFFFFFFFFFFFFFFFULL;
|
||||
util_mum(&a, &b);
|
||||
tommy_mum(&a, &b);
|
||||
if (a != 1 || b != 0xFFFFFFFFFFFFFFFEULL) return -1;
|
||||
|
||||
/* larger random-ish test */
|
||||
a = 0x0123456789ABCDEFULL;
|
||||
b = 0xFEDCBA9876543210ULL;
|
||||
util_mum(&a, &b);
|
||||
tommy_mum(&a, &b);
|
||||
if (a != 0x2236D88FE5618CF0ULL || b != 0x121FA00AD77D742ULL) return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue