1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-07 17:17:44 +03:00

Merge pull request #24216 from poettering/ispowerof2

add ISPOWEROF2() macro and use it
This commit is contained in:
Luca Boccassi 2022-08-05 16:38:58 +01:00 committed by GitHub
commit ecb991621a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 13 deletions

View File

@ -200,6 +200,19 @@
MIN(_c, z); \
})
/* Returns true if the passed integer is a positive power of two */
#define CONST_ISPOWEROF2(x) \
((x) > 0 && ((x) & ((x) - 1)) == 0)
#define ISPOWEROF2(x) \
__builtin_choose_expr( \
__builtin_constant_p(x), \
CONST_ISPOWEROF2(x), \
({ \
const typeof(x) _x = (x); \
CONST_ISPOWEROF2(_x); \
}))
#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
#define __LESS_BY(aq, a, bq, b) \
({ \
@ -314,16 +327,7 @@
})
static inline size_t ALIGN_TO(size_t l, size_t ali) {
/* Check that alignment is exponent of 2 */
#if SIZE_MAX == UINT_MAX
assert(__builtin_popcount(ali) == 1);
#elif SIZE_MAX == ULONG_MAX
assert(__builtin_popcountl(ali) == 1);
#elif SIZE_MAX == ULLONG_MAX
assert(__builtin_popcountll(ali) == 1);
#else
#error "Unexpected size_t"
#endif
assert(ISPOWEROF2(ali));
if (l > SIZE_MAX - (ali - 1))
return SIZE_MAX; /* indicate overflow */
@ -344,7 +348,7 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
__builtin_choose_expr( \
__builtin_constant_p(l) && \
__builtin_constant_p(ali) && \
__builtin_popcountll(ali) == 1 && /* is power of 2? */ \
CONST_ISPOWEROF2(ali) && \
(l <= SIZE_MAX - (ali - 1)), /* overflow? */ \
((l) + (ali) - 1) & ~((ali) - 1), \
VOID_0)

View File

@ -1629,8 +1629,8 @@ static int context_load_partition_table(
secsz = fdisk_get_sector_size(c);
/* Insist on a power of two, and that it's a multiple of 512, i.e. the traditional sector size. */
if (secsz < 512 || secsz != 1UL << log2u64(secsz))
return log_error_errno(errno, "Sector size %lu is not a power of two larger than 512? Refusing.", secsz);
if (secsz < 512 || !ISPOWEROF2(secsz))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Sector size %lu is not a power of two larger than 512? Refusing.", secsz);
/* Use at least 4K, and ensure it's a multiple of the sector size, regardless if that is smaller or
* larger */

View File

@ -465,4 +465,60 @@ TEST(PTR_SUB1) {
assert_se(!p);
}
TEST(ISPOWEROF2) {
uint64_t u;
int64_t i;
/* First, test constant expressions */
assert_se(!ISPOWEROF2(-2));
assert_se(!ISPOWEROF2(-1));
assert_se(!ISPOWEROF2(0));
assert_se(ISPOWEROF2(1));
assert_se(ISPOWEROF2(2));
assert_se(!ISPOWEROF2(3));
assert_se(ISPOWEROF2(4));
assert_se(!ISPOWEROF2(5));
assert_se(!ISPOWEROF2(6));
assert_se(!ISPOWEROF2(7));
assert_se(ISPOWEROF2(8));
assert_se(!ISPOWEROF2(9));
assert_se(!ISPOWEROF2(1022));
assert_se(ISPOWEROF2(1024));
assert_se(!ISPOWEROF2(1025));
assert_se(!ISPOWEROF2(UINT64_C(0xffffffff)));
assert_se(ISPOWEROF2(UINT64_C(0x100000000)));
assert_se(!ISPOWEROF2(UINT64_C(0x100000001)));
/* Then, test dynamic expressions, and if they are side-effect free */
i = -2;
assert_se(!ISPOWEROF2(i++));
assert_se(i == -1);
assert_se(!ISPOWEROF2(i++));
assert_se(i == 0);
assert_se(!ISPOWEROF2(i++));
assert_se(i == 1);
assert_se(ISPOWEROF2(i++));
assert_se(i == 2);
assert_se(ISPOWEROF2(i++));
assert_se(i == 3);
assert_se(!ISPOWEROF2(i++));
assert_se(i == 4);
assert_se(ISPOWEROF2(i++));
assert_se(i == 5);
assert_se(!ISPOWEROF2(i));
u = 0;
assert_se(!ISPOWEROF2(u++));
assert_se(u == 1);
assert_se(ISPOWEROF2(u++));
assert_se(u == 2);
assert_se(ISPOWEROF2(u++));
assert_se(u == 3);
assert_se(!ISPOWEROF2(u++));
assert_se(u == 4);
assert_se(ISPOWEROF2(u++));
assert_se(u == 5);
assert_se(!ISPOWEROF2(u));
}
DEFINE_TEST_MAIN(LOG_INFO);