(root)/
strace-6.5/
tests/
sched_xetaffinity.c
       1  /*
       2   * Check decoding of sched_getaffinity and sched_setaffinity syscalls.
       3   *
       4   * Copyright (c) 2016-2018 Dmitry V. Levin <ldv@strace.io>
       5   * Copyright (c) 2016-2023 The strace developers.
       6   * All rights reserved.
       7   *
       8   * SPDX-License-Identifier: GPL-2.0-or-later
       9   */
      10  
      11  #include "tests.h"
      12  #include "scno.h"
      13  #include "pidns.h"
      14  #include <sched.h>
      15  
      16  #if defined CPU_ISSET_S && defined CPU_ZERO_S && defined CPU_SET_S
      17  
      18  # include <assert.h>
      19  # include <errno.h>
      20  # include <stdio.h>
      21  # include <unistd.h>
      22  
      23  static const char *errstr;
      24  
      25  static int
      26  getaffinity(unsigned long pid, unsigned long size, void *set)
      27  {
      28  	int rc = syscall(__NR_sched_getaffinity, pid, size, set);
      29  	errstr = sprintrc(rc);
      30  	return rc;
      31  }
      32  
      33  static int
      34  setaffinity(unsigned long pid, unsigned long size, void *set)
      35  {
      36  	int rc = syscall(__NR_sched_setaffinity, pid, size, set);
      37  	errstr = sprintrc(rc);
      38  	return rc;
      39  }
      40  
      41  int
      42  main(void)
      43  {
      44  	PIDNS_TEST_INIT;
      45  
      46  	unsigned int cpuset_size = 1;
      47  	const pid_t pid = getpid();
      48  	const char *pid_str = pidns_pid2str(PT_TGID);
      49  
      50  	while (cpuset_size) {
      51  		assert(getaffinity(pid, cpuset_size, NULL) == -1);
      52  		if (EFAULT == errno)
      53  			break;
      54  		if (EINVAL != errno)
      55  			perror_msg_and_skip("sched_getaffinity");
      56  		pidns_print_leader();
      57  		printf("sched_getaffinity(%d%s, %u, NULL) = %s\n",
      58  		       pid, pid_str, cpuset_size, errstr);
      59  		cpuset_size <<= 1;
      60  	}
      61  	assert(cpuset_size);
      62  	pidns_print_leader();
      63  	printf("sched_getaffinity(%d%s, %u, NULL) = %s\n",
      64  	       pid, pid_str, cpuset_size, errstr);
      65  
      66  	cpu_set_t *cpuset = tail_alloc(cpuset_size);
      67  	getaffinity(pid, cpuset_size, cpuset + 1);
      68  	pidns_print_leader();
      69  	printf("sched_getaffinity(%d%s, %u, %p) = %s\n",
      70  	       pid, pid_str, cpuset_size, cpuset + 1, errstr);
      71  
      72  	int ret_size = getaffinity(pid, cpuset_size, cpuset);
      73  	if (ret_size < 0)
      74  		perror_msg_and_fail("sched_getaffinity(%d, %u, %p) = %s\n",
      75  				    pid, (unsigned) cpuset_size, cpuset, errstr);
      76  	assert(ret_size <= (int) cpuset_size);
      77  
      78  	pidns_print_leader();
      79  	printf("sched_getaffinity(%d%s, %u, [", pid, pid_str, cpuset_size);
      80  	const char *sep;
      81  	unsigned int i, cpu;
      82  	unsigned int first_cpu = -1U;
      83  	unsigned int first_crop_cpu = -1U;
      84  	for (i = 0, cpu = 0, sep = ""; i < (unsigned) ret_size * 8; ++i) {
      85  		if (CPU_ISSET_S(i, (unsigned) ret_size, cpuset)) {
      86  			printf("%s%u", sep, i);
      87  			sep = " ";
      88  			cpu = i;
      89  			if (first_cpu == -1U)
      90  				first_cpu = i;
      91  			if (first_crop_cpu == -1U && i >= 8)
      92  				first_crop_cpu = i;
      93  		}
      94  	}
      95  	printf("]) = %s\n", errstr);
      96  
      97  	long rc = setaffinity(pid, 0, ((char *) cpuset) + cpuset_size);
      98  	pidns_print_leader();
      99  	printf("sched_setaffinity(%d%s, 0, []) = %s\n",
     100  	       pid, pid_str, sprintrc(rc));
     101  
     102  	rc = setaffinity(pid, 1, ((char *) cpuset) + cpuset_size);
     103  	pidns_print_leader();
     104  	printf("sched_setaffinity(%d%s, 1, %p) = %s\n",
     105  	       pid, pid_str, ((char *) cpuset) + cpuset_size, sprintrc(rc));
     106  
     107  	static const uint8_t first_oob = BE_LE(SIZEOF_LONG == 4 ? 39 : 7, 56);
     108  	const unsigned int crop_size = 8;
     109  	cpu_set_t *crop_cpuset = tail_alloc(crop_size);
     110  	if (first_crop_cpu != -1U && first_crop_cpu < 56) {
     111  		CPU_ZERO_S(crop_size, crop_cpuset);
     112  		CPU_SET_S(first_crop_cpu, crop_size, crop_cpuset);
     113  		CPU_SET_S(first_oob, crop_size, crop_cpuset);
     114  		if (setaffinity(pid, crop_size - 1, crop_cpuset))
     115  			perror_msg_and_skip("sched_setaffinity()");
     116  		pidns_print_leader();
     117  		printf("sched_setaffinity(%d%s, 7, [%u]) = 0\n",
     118  		       pid, pid_str, first_crop_cpu);
     119  	}
     120  
     121  	CPU_ZERO_S(cpuset_size, cpuset);
     122  	CPU_SET_S(cpu, cpuset_size, cpuset);
     123  	if (setaffinity(pid, cpuset_size, cpuset))
     124  		perror_msg_and_skip("sched_setaffinity");
     125  	pidns_print_leader();
     126  	printf("sched_setaffinity(%d%s, %u, [%u]) = 0\n",
     127  	       pid, pid_str, cpuset_size, cpu);
     128  
     129  	const unsigned int big_size = cpuset_size < 128 ? 128 : cpuset_size * 2;
     130  	cpuset = tail_alloc(big_size);
     131  	ret_size = getaffinity(pid, big_size, cpuset);
     132  	if (ret_size < 0)
     133  		perror_msg_and_fail("sched_getaffinity(%d, %u, %p) = %s\n",
     134  				    pid, big_size, cpuset, errstr);
     135  	assert(ret_size <= (int) big_size);
     136  	pidns_print_leader();
     137  	printf("sched_getaffinity(%d%s, %u, [", pid, pid_str, big_size);
     138  	for (i = 0, sep = ""; i < (unsigned) ret_size * 8; ++i) {
     139  		if (CPU_ISSET_S(i, (unsigned) ret_size, cpuset)) {
     140  			printf("%s%u", sep, i);
     141  			sep = " ";
     142  		}
     143  	}
     144  	printf("]) = %s\n", errstr);
     145  
     146  	pidns_print_leader();
     147  	puts("+++ exited with 0 +++");
     148  	return 0;
     149  }
     150  
     151  #else
     152  
     153  SKIP_MAIN_UNDEFINED("CPU_ISSET_S && CPU_ZERO_S && CPU_SET_S")
     154  
     155  #endif