1 /* Test for sched_getaffinity and sched_setaffinity, PID version.
2 Copyright (C) 2015-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 /* Function definitions for the benefit of tst-skeleton-affinity.c.
20 This variant forks a child process which then invokes
21 sched_getaffinity and sched_setaffinity on the parent PID. */
33 write_fully (int fd
, const void *buffer
, size_t length
)
35 const void *end
= buffer
+ length
;
38 ssize_t bytes_written
= TEMP_FAILURE_RETRY
39 (write (fd
, buffer
, end
- buffer
));
40 if (bytes_written
< 0)
42 if (bytes_written
== 0)
47 buffer
+= bytes_written
;
53 read_fully (int fd
, void *buffer
, size_t length
)
55 const void *start
= buffer
;
56 const void *end
= buffer
+ length
;
59 ssize_t bytes_read
= TEMP_FAILURE_RETRY
60 (read (fd
, buffer
, end
- buffer
));
64 return buffer
- start
;
71 process_child_response (int *pipes
, pid_t child
,
72 cpu_set_t
*set
, size_t size
)
77 ssize_t bytes_read
= read_fully
78 (pipes
[0], &value_from_child
, sizeof (value_from_child
));
81 printf ("error: read from child: %m\n");
84 if (bytes_read
!= sizeof (value_from_child
))
86 printf ("error: not enough bytes from child: %zd\n", bytes_read
);
89 if (value_from_child
== 0)
91 bytes_read
= read_fully (pipes
[0], set
, size
);
94 printf ("error: read: %m\n");
97 if (bytes_read
!= size
)
99 printf ("error: not enough bytes from child: %zd\n", bytes_read
);
105 if (waitpid (child
, &status
, 0) < 0)
107 printf ("error: waitpid: %m\n");
110 if (!(WIFEXITED (status
) && WEXITSTATUS (status
) == 0))
112 printf ("error: invalid status from : %m\n");
118 if (value_from_child
!= 0)
120 errno
= value_from_child
;
127 getaffinity (size_t size
, cpu_set_t
*set
)
130 if (pipe (pipes
) < 0)
132 printf ("error: pipe: %m\n");
139 printf ("error: fork: %m\n");
145 int ret
= sched_getaffinity (getppid (), size
, set
);
148 if (write_fully (pipes
[1], &ret
, sizeof (ret
)) < 0
149 || write_fully (pipes
[1], set
, size
) < 0
150 || (ret
== 0 && write_fully (pipes
[1], set
, size
) < 0))
152 printf ("error: write: %m\n");
159 return process_child_response (pipes
, ret
, set
, size
);
163 setaffinity (size_t size
, const cpu_set_t
*set
)
166 if (pipe (pipes
) < 0)
168 printf ("error: pipe: %m\n");
175 printf ("error: fork: %m\n");
181 int ret
= sched_setaffinity (getppid (), size
, set
);
182 if (write_fully (pipes
[1], &ret
, sizeof (ret
)) < 0)
184 printf ("error: write: %m\n");
190 /* Parent. There is no affinity mask to read from the child, so the
192 return process_child_response (pipes
, ret
, NULL
, 0);
196 static bool early_test (struct conf
*unused
)
201 #include "tst-skeleton-affinity.c"