Sourceware Bugzilla – Attachment 8322 Details for
Bug 15630
Fix use of cpu_set_t with sched_getaffinity when booted on a system with more than 1024 possible cpus.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Test case which reflects the truncation assumption (does not currently work)
tst-affinity.c (text/plain), 5.72 KB, created by
Florian Weimer
on 2015-05-18 19:14:54 UTC
(
hide
)
Description:
Test case which reflects the truncation assumption (does not currently work)
Filename:
MIME Type:
Creator:
Florian Weimer
Created:
2015-05-18 19:14:54 UTC
Size:
5.72 KB
patch
obsolete
>/* Copyright (C) 2015 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 > <http://www.gnu.org/licenses/>. */ > >#include <errno.h> >#include <limits.h> >#include <sched.h> >#include <stdbool.h> >#include <stdio.h> > >static int >find_max_cpu (void) >{ > /* We need to start at 64 because otherwise, CPU_ALLOC > over-allocates, and and we do not see all bits returned by the > kernel. */ > for (int num_cpus = 64; num_cpus <= INT_MAX / 2; num_cpus *= 2) > { > cpu_set_t *set = CPU_ALLOC (num_cpus); > size_t size = CPU_ALLOC_SIZE (num_cpus); > printf ("allocating set for %d CPUs, size %zu\n", num_cpus, size); > > if (set == NULL) > { > printf ("CPU_ALLOC(%d) failed\n", num_cpus); > return -1; > } > if (sched_getaffinity (0, size, set) == 0) > { > for (int i = num_cpus - 1; i >= 0; --i) > { > if (CPU_ISSET_S (i, size, set)) > { > CPU_FREE (set); > return i; > } > } > printf ("Could not find active CPU in set of size %d\n", num_cpus); > CPU_FREE (set); > return -1; > } > if (errno != EINVAL) > { > printf ("sched_getaffinity for %d CPUs: %m\n", num_cpus); > return -1; > } > CPU_FREE (set); > } > puts ("Cannot find maximum CPU number"); > return -1; >} > >static int >find_flippable_cpu (const cpu_set_t *set, size_t size) >{ > if (CPU_COUNT_S (size, set) < 2) > return -1; > > int i; > for (i = 0; !CPU_ISSET_S (i, size, set); ++i) > ; > return i; >} > >static bool >test_size (size_t size) >{ > cpu_set_t *set = CPU_ALLOC (size); > cpu_set_t *set2 = CPU_ALLOC (size); > cpu_set_t *active_cpu_set = CPU_ALLOC (size); > int active_cpu; > > if (set == NULL || set2 == NULL || active_cpu_set == NULL) > { > printf ("size %zu: CPU_ALLOC failed\n", size); > return false; > } > size = CPU_ALLOC_SIZE (size); > > if (sched_getaffinity (0, size, set) < 0) > { > printf ("size %zu: sched_getaffinity: %m\n", size); > return false; > } > active_cpu = find_flippable_cpu (set, size); > if (active_cpu < 0) > { > printf ("size %zu: not enough CPUs to test affinity\n", size); > return true; > } > if (sched_setaffinity (0, size, set) < 0) > { > printf ("size %zu: sched_setaffinity: %m\n", size); > return true; > } > > CPU_ZERO_S (size, active_cpu_set); > CPU_SET_S (active_cpu, size, active_cpu_set); > if (sched_setaffinity (0, size, active_cpu_set) < 0) > { > printf ("size %zu: sched_setaffinity (2): %m\n", size); > return false; > } > if (sched_getaffinity (0, size, set2) < 0) > { > printf ("size %zu: sched_getaffinity (2): %m\n", size); > return false; > } > if (!CPU_EQUAL_S(size, active_cpu_set, set2)) > { > printf ("size %zu: CPU sets do not match\n", size); > return false; > } > if (sched_setaffinity (0, size, set) < 0) > { > printf ("size %zu: sched_setaffinity (3): %m\n", size); > return false; > } > if (sched_getaffinity (0, size, set2) < 0) > { > printf ("size %zu: sched_getaffinity (3): %m\n", size); > return false; > } > if (!CPU_EQUAL_S(size, set, set2)) > { > printf ("size %zu: CPU sets do not match (2)\n", size); > return false; > } > > CPU_FREE (set); > CPU_FREE (set2); > CPU_FREE (active_cpu_set); > > return true; >} > >static bool >shrink_set (int max_cpu, bool *shrunk) >{ > cpu_set_t *set = CPU_ALLOC (max_cpu + 1); > size_t size = CPU_ALLOC_SIZE (max_cpu + 1); > > if (set == NULL) > { > printf ("CPU_ALLOC(%d) failed\n", max_cpu); > return false; > } > > if (sched_getaffinity (0, size, set) < 0) > { > printf ("sched_getaffinity: %m\n"); > CPU_FREE (set); > return false; > } > > *shrunk = CPU_ISSET_S (0, size, set) && CPU_ISSET_S (0, size, set); > if (!*shrunk) > { > printf ("Cannot shrink CPU set size because CPUs 0 and 1 are missing\n"); > CPU_FREE (set); > return true; > } > CPU_ZERO_S (size, set); > CPU_SET_S (0, size, set); > CPU_SET_S (1, size, set); > if (sched_setaffinity (0, size, set) < 0) > { > printf ("sched_setaffinity: %m\n"); > CPU_FREE (set); > return false; > } > max_cpu = find_max_cpu (); > if (max_cpu != 1) > { > printf ("Set shrinking unsuccessful, maximum CPU still %d\n", max_cpu); > CPU_FREE (set); > return false; > } > > CPU_FREE (set); > return true; >} > >static int >do_test (void) >{ > printf ("__NCPUBITS: %d\nsizeof (__cpu_mask): %zu\n", > (int)__NCPUBITS, sizeof (__cpu_mask)); > > cpu_set_t set; > if (sched_getaffinity (0, sizeof (set), &set) < 0) > { > if (errno == ENOSYS) > { > puts ("sched_getaffinity not supported"); > return 0; > } > printf ("sched_getaffinity: %m\n"); > return 1; > } > > int max_cpu = find_max_cpu (); > printf ("Detected maximum CPU number: %d\n", max_cpu); > if (max_cpu < 0) > return 1; > > if (max_cpu <= 1024 && !test_size (1024)) > return 1; > if (max_cpu <= 2 && !test_size (2)) > return 1; > if (max_cpu <= 1024 * 1024 && !test_size (1024 * 1024)) > return 1; > > bool shrunk; > if (!shrink_set (max_cpu, &shrunk)) > return 1; > if (shrunk) > { > if (!(test_size (1024) && test_size (2) && test_size (1024 * 1024))) > return 1; > } > > return 0; >} > >#define TEST_FUNCTION do_test () >#include "../test-skeleton.c"
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 15630
: 8322