/* Test that CPU_* macros comply with their specifications.
Copyright (C) 2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
. */
#include
#include
#include
#include
#include
static int
do_test (void)
{
cpu_set_t *cpusetp_A = NULL;
cpu_set_t *cpusetp_B = NULL;
cpu_set_t *cpusetp_C = NULL;
size_t setsz __attribute__ ((unused)) = GET_SIZE();
TEST_VERIFY (CPU_ALLOC_SIZE (-1) == 0);
TEST_VERIFY (CPU_ALLOC_SIZE (0) == 0);
TEST_VERIFY (CPU_ALLOC_SIZE (1) == sizeof (__cpu_mask));
TEST_VERIFY (CPU_ALLOC_SIZE (INT_MAX) > 0);
PREPARE_CPU_SET_TO_FAULT_BEFORE(cpusetp_A);
PREPARE_CPU_SET_TO_FAULT(cpusetp_B);
PREPARE_CPU_SET(cpusetp_C);
/* Bad actor access, negative CPU number */
LOCAL_CPU_SET (-1, setsz, cpusetp_A);
TEST_VERIFY (!LOCAL_CPU_ISSET (-1, setsz, cpusetp_A));
/* Bad actor access, above CPU number */
LOCAL_CPU_SET (LOCAL_NUM_CPUS, setsz, cpusetp_B);
TEST_VERIFY (!LOCAL_CPU_ISSET (LOCAL_NUM_CPUS, setsz, cpusetp_B));
LOCAL_CPU_ZERO (setsz, cpusetp_A);
LOCAL_CPU_ZERO (setsz, cpusetp_B);
LOCAL_CPU_ZERO (setsz, cpusetp_C);
for (int cpu = 0; cpu < LOCAL_NUM_CPUS; cpu += 2)
{
/* Set A = 0x55..55 */
LOCAL_CPU_SET (cpu, setsz, cpusetp_A);
TEST_VERIFY (LOCAL_CPU_ISSET (cpu, setsz, cpusetp_A));
}
for (int cpu = 1; cpu < LOCAL_NUM_CPUS; cpu += 2)
{
/* Set B = 0xAA..AA */
LOCAL_CPU_SET (cpu, setsz, cpusetp_B);
TEST_VERIFY (LOCAL_CPU_ISSET (cpu, setsz, cpusetp_B));
}
/* Ensure CPU_COUNT matches expected count */
TEST_VERIFY (LOCAL_CPU_COUNT (setsz, cpusetp_A) == LOCAL_CPU_COUNT (setsz, cpusetp_B));
TEST_VERIFY (LOCAL_CPU_COUNT (setsz, cpusetp_A) == LOCAL_NUM_CPUS / 2);
LOCAL_CPU_AND (setsz, cpusetp_C, cpusetp_A, cpusetp_B);
for (int cpu = 0; cpu < LOCAL_NUM_CPUS; cpu++)
{
/* A setsz, B == 0 */
TEST_VERIFY (!LOCAL_CPU_ISSET (cpu, setsz, cpusetp_C));
}
LOCAL_CPU_OR (setsz, cpusetp_C, cpusetp_A, cpusetp_B);
for (int cpu = 0; cpu < LOCAL_NUM_CPUS; cpu++)
{
/* A | B == 0xFF..FF */
TEST_VERIFY (LOCAL_CPU_ISSET (cpu, setsz, cpusetp_C));
}
/* Check that CPU_ZERO actually does something */
TEST_VERIFY (LOCAL_CPU_COUNT (setsz, cpusetp_C) == LOCAL_NUM_CPUS);
LOCAL_CPU_ZERO (setsz, cpusetp_C);
TEST_VERIFY (LOCAL_CPU_COUNT (setsz, cpusetp_C) == 0);
LOCAL_CPU_XOR (setsz, cpusetp_C, cpusetp_A, cpusetp_A);
for (int cpu = 0; cpu < LOCAL_NUM_CPUS; cpu++)
{
/* A ^ A == 0 */
TEST_VERIFY (!LOCAL_CPU_ISSET (cpu, setsz, cpusetp_C));
}
LOCAL_CPU_XOR (setsz, cpusetp_C, cpusetp_A, cpusetp_B);
for (int cpu = 0; cpu < LOCAL_NUM_CPUS; cpu++)
{
/* C = A ^ B == 0xFF..FF */
TEST_VERIFY (LOCAL_CPU_ISSET (cpu, setsz, cpusetp_C));
}
for (int cpu = 1; cpu < LOCAL_NUM_CPUS; cpu += 2)
{
/* C = 0x55..55 */
LOCAL_CPU_CLR (cpu, setsz, cpusetp_C);
TEST_VERIFY (!LOCAL_CPU_ISSET (cpu, setsz, cpusetp_C));
}
TEST_VERIFY (LOCAL_CPU_EQUAL (setsz, cpusetp_A, cpusetp_C));
CLEAN_CPU_SET(cpusetp_C);
CLEAN_CPU_SET_TO_FAULT(cpusetp_B);
CLEAN_CPU_SET_TO_FAULT_BEFORE(cpusetp_A);
return 0;
}
#include