summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-11-29 16:05:27 -0700
committerAndreas Kling <kling@serenityos.org>2020-11-30 13:17:02 +0100
commit046d6855f5e8a5039b319a47c3018a16d4c2f960 (patch)
tree9021179989bea74ec7d14a4c30d77eb2b2609f23 /Userland
parent6a620562cc7298c2f591a06817ff560c9ef1deac (diff)
downloadserenity-046d6855f5e8a5039b319a47c3018a16d4c2f960.zip
Kernel: Move block condition evaluation out of the Scheduler
This makes the Scheduler a lot leaner by not having to evaluate block conditions every time it is invoked. Instead evaluate them as the states change, and unblock threads at that point. This also implements some more waitid/waitpid/wait features and behavior. For example, WUNTRACED and WNOWAIT are now supported. And wait will now not return EINTR when SIGCHLD is delivered at the same time.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/strace.cpp39
1 files changed, 7 insertions, 32 deletions
diff --git a/Userland/strace.cpp b/Userland/strace.cpp
index 6922218bb7..00bd6fbeec 100644
--- a/Userland/strace.cpp
+++ b/Userland/strace.cpp
@@ -53,7 +53,6 @@ static void handle_sigint(int)
int main(int argc, char** argv)
{
Vector<const char*> child_argv;
- bool spawned_new_process = false;
Core::ArgsParser parser;
parser.add_option(g_pid, "Trace the given PID", "pid", 'p', "pid");
@@ -61,6 +60,7 @@ int main(int argc, char** argv)
parser.parse(argc, argv);
+ int status;
if (g_pid == -1) {
if (child_argv.is_empty()) {
fprintf(stderr, "strace: Expected either a pid or some arguments\n");
@@ -68,7 +68,6 @@ int main(int argc, char** argv)
}
child_argv.append(nullptr);
- spawned_new_process = true;
int pid = fork();
if (pid < 0) {
perror("fork");
@@ -89,7 +88,7 @@ int main(int argc, char** argv)
}
g_pid = pid;
- if (waitpid(pid, nullptr, WSTOPPED) != pid) {
+ if (waitpid(pid, &status, WSTOPPED | WEXITED) != pid || !WIFSTOPPED(status)) {
perror("waitpid");
return 1;
}
@@ -104,66 +103,42 @@ int main(int argc, char** argv)
perror("attach");
return 1;
}
-
- if (waitpid(g_pid, nullptr, WSTOPPED) != g_pid) {
+ if (waitpid(g_pid, &status, WSTOPPED | WEXITED) != g_pid || !WIFSTOPPED(status)) {
perror("waitpid");
return 1;
}
- if (spawned_new_process) {
-
- if (ptrace(PT_CONTINUE, g_pid, 0, 0) < 0) {
- perror("continue");
- return 1;
- }
- if (waitpid(g_pid, nullptr, WSTOPPED) != g_pid) {
- perror("wait_pid");
- return 1;
- }
- }
-
for (;;) {
if (ptrace(PT_SYSCALL, g_pid, 0, 0) == -1) {
- if (errno == ESRCH)
- return 0;
perror("syscall");
return 1;
}
- if (waitpid(g_pid, nullptr, WSTOPPED) != g_pid) {
+ if (waitpid(g_pid, &status, WSTOPPED | WEXITED) != g_pid || !WIFSTOPPED(status)) {
perror("wait_pid");
return 1;
}
-
PtraceRegisters regs = {};
if (ptrace(PT_GETREGS, g_pid, &regs, 0) == -1) {
perror("getregs");
return 1;
}
-
u32 syscall_index = regs.eax;
u32 arg1 = regs.edx;
u32 arg2 = regs.ecx;
u32 arg3 = regs.ebx;
- // skip syscall exit
if (ptrace(PT_SYSCALL, g_pid, 0, 0) == -1) {
- if (errno == ESRCH)
- return 0;
perror("syscall");
return 1;
}
- if (waitpid(g_pid, nullptr, WSTOPPED) != g_pid) {
+ if (waitpid(g_pid, &status, WSTOPPED | WEXITED) != g_pid || !WIFSTOPPED(status)) {
perror("wait_pid");
return 1;
}
if (ptrace(PT_GETREGS, g_pid, &regs, 0) == -1) {
- if (errno == ESRCH && syscall_index == SC_exit) {
- regs.eax = 0;
- } else {
- perror("getregs");
- return 1;
- }
+ perror("getregs");
+ return 1;
}
u32 res = regs.eax;