2 * Copyright (C) 2016 Google, Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
25 #include <sys/ptrace.h>
27 #include <sys/timerfd.h>
28 #include <sys/types.h>
31 #include "../kselftest.h"
39 if (sched_setaffinity(0, sizeof(set
), &set
) != 0) {
40 perror("sched_setaffinity() failed");
44 if (ptrace(PTRACE_TRACEME
, 0, NULL
, NULL
) != 0) {
45 perror("ptrace(PTRACE_TRACEME) failed");
49 if (raise(SIGSTOP
) != 0) {
50 perror("raise(SIGSTOP) failed");
57 bool run_test(int cpu
)
64 perror("fork() failed");
70 wpid
= waitpid(pid
, &status
, __WALL
);
72 perror("waitpid() failed");
75 if (!WIFSTOPPED(status
)) {
76 printf("child did not stop\n");
79 if (WSTOPSIG(status
) != SIGSTOP
) {
80 printf("child did not stop with SIGSTOP\n");
84 if (ptrace(PTRACE_SINGLESTEP
, pid
, NULL
, NULL
) < 0) {
86 printf("ptrace(PTRACE_SINGLESTEP) not supported on this architecture\n");
89 perror("ptrace(PTRACE_SINGLESTEP) failed");
93 wpid
= waitpid(pid
, &status
, __WALL
);
95 perror("waitpid() failed");
98 if (WIFEXITED(status
)) {
99 printf("child did not single-step\n");
102 if (!WIFSTOPPED(status
)) {
103 printf("child did not stop\n");
106 if (WSTOPSIG(status
) != SIGTRAP
) {
107 printf("child did not stop with SIGTRAP\n");
111 if (ptrace(PTRACE_CONT
, pid
, NULL
, NULL
) < 0) {
112 perror("ptrace(PTRACE_CONT) failed");
116 wpid
= waitpid(pid
, &status
, __WALL
);
118 perror("waitpid() failed");
121 if (!WIFEXITED(status
)) {
122 printf("child did not exit after PTRACE_CONT\n");
132 struct sigevent event
= {};
135 struct itimerspec spec
= {};
137 power_state_fd
= open("/sys/power/state", O_RDWR
);
138 if (power_state_fd
< 0) {
139 perror("open(\"/sys/power/state\") failed (is this test running as root?)");
143 timerfd
= timerfd_create(CLOCK_BOOTTIME_ALARM
, 0);
145 perror("timerfd_create() failed");
149 spec
.it_value
.tv_sec
= 5;
150 err
= timerfd_settime(timerfd
, 0, &spec
, NULL
);
152 perror("timerfd_settime() failed");
156 if (write(power_state_fd
, "mem", strlen("mem")) != strlen("mem")) {
157 perror("entering suspend failed");
162 close(power_state_fd
);
165 int main(int argc
, char **argv
)
168 bool do_suspend
= true;
169 bool succeeded
= true;
170 cpu_set_t available_cpus
;
174 while ((opt
= getopt(argc
, argv
, "n")) != -1) {
180 printf("Usage: %s [-n]\n", argv
[0]);
181 printf(" -n: do not trigger a suspend/resume cycle before the test\n");
189 err
= sched_getaffinity(0, sizeof(available_cpus
), &available_cpus
);
191 perror("sched_getaffinity() failed");
195 for (cpu
= 0; cpu
< CPU_SETSIZE
; cpu
++) {
198 if (!CPU_ISSET(cpu
, &available_cpus
))
201 test_success
= run_test(cpu
);
202 printf("CPU %d: ", cpu
);
207 printf("[FAILED]\n");