[haiku-commits] haiku: hrev51470 - src/system/kernel src/libs/bsd src/tests/libs/bsd src/system/libroot/posix/sys headers/private/kernel

  • From: jerome.duval@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 10 Oct 2017 17:27:14 +0200 (CEST)

hrev51470 adds 1 changeset to branch 'master'
old head: c80ec6a9fed93e318d8bb141dfdffc4181d72e42
new head: a295d3f46e2f9d779c65bf9fcaeae794bc5cf276
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=a295d3f46e2f+%5Ec80ec6a9fed9

----------------------------------------------------------------------------

a295d3f46e2f: wait4(): retrieve dead team entries usage information.
  
  * This adds a parameter to the wait_for_child syscall. I extended the test 
case
  to show the actual retrieved information.
  * fix #13546

                                   [ Jérôme Duval <jerome.duval@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev51470
Commit:      a295d3f46e2f9d779c65bf9fcaeae794bc5cf276
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a295d3f46e2f
Author:      Jérôme Duval <jerome.duval@xxxxxxxxx>
Date:        Tue Oct 10 15:20:46 2017 UTC

Ticket:      https://dev.haiku-os.org/ticket/13546

----------------------------------------------------------------------------

7 files changed, 52 insertions(+), 20 deletions(-)
headers/private/kernel/team.h         |  3 ++-
headers/private/kernel/thread_types.h |  2 ++
headers/private/system/syscalls.h     |  2 +-
src/libs/bsd/wait.c                   | 16 ++++++++--------
src/system/kernel/team.cpp            | 24 +++++++++++++++++++++---
src/system/libroot/posix/sys/wait.cpp | 16 +++++++++++-----
src/tests/libs/bsd/wait4_test.cpp     |  9 +++++++--

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/team.h b/headers/private/kernel/team.h
index 2fb555e..e376409 100644
--- a/headers/private/kernel/team.h
+++ b/headers/private/kernel/team.h
@@ -69,7 +69,8 @@ thread_id _user_load_image(const char* const* flatArgs, 
size_t flatArgsSize,
 status_t _user_wait_for_team(team_id id, status_t *_returnCode);
 void _user_exit_team(status_t returnValue);
 status_t _user_kill_team(thread_id thread);
-pid_t _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* info);
+pid_t _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* info,
+                       team_usage_info* usageInfo);
 status_t _user_exec(const char *path, const char* const* flatArgs,
                        size_t flatArgsSize, int32 argCount, int32 envCount, 
mode_t umask);
 thread_id _user_fork(void);
diff --git a/headers/private/kernel/thread_types.h 
b/headers/private/kernel/thread_types.h
index e90e258..720a221 100644
--- a/headers/private/kernel/thread_types.h
+++ b/headers/private/kernel/thread_types.h
@@ -116,6 +116,8 @@ struct job_control_entry : 
DoublyLinkedListLinkImpl<job_control_entry> {
        status_t                        status;
        uint16                          reason;         // reason for the 
team's demise, one of the
                                                                        // 
CLD_* values defined in <signal.h>
+       bigtime_t                       user_time;
+       bigtime_t                       kernel_time;
 
        job_control_entry();
        ~job_control_entry();
diff --git a/headers/private/system/syscalls.h 
b/headers/private/system/syscalls.h
index 35fe2a1..9d5e8f2 100644
--- a/headers/private/system/syscalls.h
+++ b/headers/private/system/syscalls.h
@@ -141,7 +141,7 @@ extern status_t             _kern_kill_team(team_id team);
 extern team_id         _kern_get_current_team();
 extern status_t                _kern_wait_for_team(team_id team, status_t 
*_returnCode);
 extern pid_t           _kern_wait_for_child(thread_id child, uint32 flags,
-                                               siginfo_t* info);
+                                               siginfo_t* info, 
team_usage_info* usageInfo);
 extern status_t                _kern_exec(const char *path, const char* const* 
flatArgs,
                                                size_t flatArgsSize, int32 
argCount, int32 envCount,
                                                mode_t umask);
diff --git a/src/libs/bsd/wait.c b/src/libs/bsd/wait.c
index 368d8dd..57fc328 100644
--- a/src/libs/bsd/wait.c
+++ b/src/libs/bsd/wait.c
@@ -12,6 +12,10 @@
 #include <sys/wait.h>
 
 
+extern pid_t _waitpid(pid_t pid, int* _status, int options,
+               team_usage_info *usage_info);
+
+
 pid_t
 wait3(int *status, int options, struct rusage *rusage)
 {
@@ -22,14 +26,10 @@ wait3(int *status, int options, struct rusage *rusage)
 pid_t
 wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 {
-       pid_t waitPid = waitpid(pid, status, options);
-       if (waitPid != -1) {
-               team_usage_info info;
-               
-               // Obtain info for the process that changed state.
-               if (get_team_usage_info(waitPid, RUSAGE_SELF, &info) != B_OK)
-                       return -1;
-               
+       team_usage_info info;
+       pid_t waitPid = _waitpid(pid, status, options,
+               rusage != NULL ? &info : NULL);
+       if (waitPid != -1 && rusage != NULL) {
                rusage->ru_utime.tv_sec = info.user_time / 1000000;
                rusage->ru_utime.tv_usec = info.user_time % 1000000;
 
diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp
index 1b364fe..5a78c08 100644
--- a/src/system/kernel/team.cpp
+++ b/src/system/kernel/team.cpp
@@ -2369,6 +2369,10 @@ job_control_entry::InitDeadState()
                reason = team->exit.reason;
                signal = team->exit.signal;
                signaling_user = team->exit.signaling_user;
+               user_time = team->dead_threads_user_time
+                       + team->dead_children.user_time;
+               kernel_time = team->dead_threads_kernel_time
+                       + team->dead_children.kernel_time;
 
                team = NULL;
        }
@@ -2387,6 +2391,8 @@ job_control_entry::operator=(const job_control_entry& 
other)
        group_id = other.group_id;
        status = other.status;
        reason = other.reason;
+       user_time = other.user_time;
+       kernel_time = other.kernel_time;
 
        return *this;
 }
@@ -2395,7 +2401,8 @@ job_control_entry::operator=(const job_control_entry& 
other)
 /*! This is the kernel backend for waitid().
 */
 static thread_id
-wait_for_child(pid_t child, uint32 flags, siginfo_t& _info)
+wait_for_child(pid_t child, uint32 flags, siginfo_t& _info,
+       team_usage_info& _usage_info)
 {
        Thread* thread = thread_get_current_thread();
        Team* team = thread->team;
@@ -2533,6 +2540,8 @@ wait_for_child(pid_t child, uint32 flags, siginfo_t& 
_info)
                        _info.si_code = foundEntry.reason;
                        _info.si_status = foundEntry.reason == CLD_EXITED
                                ? foundEntry.status : foundEntry.signal;
+                       _usage_info.user_time = foundEntry.user_time;
+                       _usage_info.kernel_time = foundEntry.kernel_time;
                        break;
                case JOB_CONTROL_STATE_STOPPED:
                        _info.si_code = CLD_STOPPED;
@@ -3915,19 +3924,28 @@ _user_fork(void)
 
 
 pid_t
-_user_wait_for_child(thread_id child, uint32 flags, siginfo_t* userInfo)
+_user_wait_for_child(thread_id child, uint32 flags, siginfo_t* userInfo,
+       team_usage_info* usageInfo)
 {
        if (userInfo != NULL && !IS_USER_ADDRESS(userInfo))
                return B_BAD_ADDRESS;
+       if (usageInfo != NULL && !IS_USER_ADDRESS(usageInfo))
+               return B_BAD_ADDRESS;
 
        siginfo_t info;
-       pid_t foundChild = wait_for_child(child, flags, info);
+       team_usage_info usage_info;
+       pid_t foundChild = wait_for_child(child, flags, info, usage_info);
        if (foundChild < 0)
                return syscall_restart_handle_post(foundChild);
 
        // copy info back to userland
        if (userInfo != NULL && user_memcpy(userInfo, &info, sizeof(info)) != 
B_OK)
                return B_BAD_ADDRESS;
+       // copy usage_info back to userland
+       if (usageInfo != NULL && user_memcpy(usageInfo, &usage_info,
+               sizeof(usage_info)) != B_OK) {
+               return B_BAD_ADDRESS;
+       }
 
        return foundChild;
 }
diff --git a/src/system/libroot/posix/sys/wait.cpp 
b/src/system/libroot/posix/sys/wait.cpp
index 1c785c9..d410a48 100644
--- a/src/system/libroot/posix/sys/wait.cpp
+++ b/src/system/libroot/posix/sys/wait.cpp
@@ -23,13 +23,12 @@ wait(int* _status)
        return waitpid(-1, _status, 0);
 }
 
-
-pid_t
-waitpid(pid_t pid, int* _status, int options)
+extern "C" pid_t
+_waitpid(pid_t pid, int* _status, int options, team_usage_info *usage_info)
 {
        // wait
        siginfo_t info;
-       pid_t child = _kern_wait_for_child(pid, options, &info);
+       pid_t child = _kern_wait_for_child(pid, options, &info, usage_info);
 
        pthread_testcancel();
 
@@ -84,6 +83,13 @@ waitpid(pid_t pid, int* _status, int options)
 }
 
 
+pid_t
+waitpid(pid_t pid, int* _status, int options)
+{
+       return _waitpid(pid, _status, options, NULL);
+}
+
+
 int
 waitid(idtype_t idType, id_t id, siginfo_t* info, int options)
 {
@@ -111,7 +117,7 @@ waitid(idtype_t idType, id_t id, siginfo_t* info, int 
options)
                        RETURN_AND_SET_ERRNO_TEST_CANCEL(EINVAL);
        }
 
-       pid_t child = _kern_wait_for_child(id, options, info);
+       pid_t child = _kern_wait_for_child(id, options, info, NULL);
        if (child >= 0 || child == B_WOULD_BLOCK)
                return 0;
 
diff --git a/src/tests/libs/bsd/wait4_test.cpp 
b/src/tests/libs/bsd/wait4_test.cpp
index e5d761d..46f2615 100644
--- a/src/tests/libs/bsd/wait4_test.cpp
+++ b/src/tests/libs/bsd/wait4_test.cpp
@@ -5,6 +5,7 @@
 
 
 #include <errno.h>
+#include <inttypes.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/resource.h> 
@@ -55,10 +56,14 @@ main(int argc, char** argv)
        struct rusage usage;
        pid_t pid;
        do {
+               memset(&usage, 0, sizeof(usage));
                int childStatus = -1;
                pid = wait4(-1, &childStatus, 0, &usage);
-               printf("wait4() returned %ld (%s), child status %d\n",
-                       pid, strerror(errno), childStatus);
+               printf("wait4() returned %" PRId32 " (%s), child status %" 
PRId32
+                       ", kernel: %ld.%06" PRId32 " user: %ld.%06" PRId32 "\n",
+                       pid, strerror(errno), childStatus, 
usage.ru_stime.tv_sec,
+                       usage.ru_stime.tv_usec, usage.ru_utime.tv_sec,
+                       usage.ru_utime.tv_usec);
        } while (pid >= 0);
 
        return 0;


Other related posts:

  • » [haiku-commits] haiku: hrev51470 - src/system/kernel src/libs/bsd src/tests/libs/bsd src/system/libroot/posix/sys headers/private/kernel - jerome . duval