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");