Ticket #13546: wait4.patch

File wait4.patch, 7.5 KB (added by korli, 7 years ago)

wait4 patch

  • headers/private/kernel/team.h

    diff --git a/headers/private/kernel/team.h b/headers/private/kernel/team.h
    index 2fb555e..e376409 100644
    a b thread_id _user_load_image(const char* const* flatArgs, size_t flatArgsSize,  
    6969status_t _user_wait_for_team(team_id id, status_t *_returnCode);
    7070void _user_exit_team(status_t returnValue);
    7171status_t _user_kill_team(thread_id thread);
    72 pid_t _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* info);
     72pid_t _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* info,
     73            team_usage_info* usageInfo);
    7374status_t _user_exec(const char *path, const char* const* flatArgs,
    7475            size_t flatArgsSize, int32 argCount, int32 envCount, mode_t umask);
    7576thread_id _user_fork(void);
  • headers/private/kernel/thread_types.h

    diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h
    index e90e258..720a221 100644
    a b struct job_control_entry : DoublyLinkedListLinkImpl<job_control_entry> {  
    116116    status_t            status;
    117117    uint16              reason;     // reason for the team's demise, one of the
    118118                                    // CLD_* values defined in <signal.h>
     119    bigtime_t           user_time;
     120    bigtime_t           kernel_time;
    119121
    120122    job_control_entry();
    121123    ~job_control_entry();
  • headers/private/system/syscalls.h

    diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h
    index 35fe2a1..9d5e8f2 100644
    a b extern status_t _kern_kill_team(team_id team);  
    141141extern team_id      _kern_get_current_team();
    142142extern status_t     _kern_wait_for_team(team_id team, status_t *_returnCode);
    143143extern pid_t        _kern_wait_for_child(thread_id child, uint32 flags,
    144                         siginfo_t* info);
     144                        siginfo_t* info, team_usage_info* usageInfo);
    145145extern status_t     _kern_exec(const char *path, const char* const* flatArgs,
    146146                        size_t flatArgsSize, int32 argCount, int32 envCount,
    147147                        mode_t umask);
  • src/libs/bsd/wait.c

    diff --git a/src/libs/bsd/wait.c b/src/libs/bsd/wait.c
    index 368d8dd..57fc328 100644
    a b  
    1212#include <sys/wait.h>
    1313
    1414
     15extern pid_t _waitpid(pid_t pid, int* _status, int options,
     16        team_usage_info *usage_info);
     17
     18
    1519pid_t
    1620wait3(int *status, int options, struct rusage *rusage)
    1721{
    wait3(int *status, int options, struct rusage *rusage)  
    2226pid_t
    2327wait4(pid_t pid, int *status, int options, struct rusage *rusage)
    2428{
    25     pid_t waitPid = waitpid(pid, status, options);
    26     if (waitPid != -1) {
    27         team_usage_info info;
    28        
    29         // Obtain info for the process that changed state.
    30         if (get_team_usage_info(waitPid, RUSAGE_SELF, &info) != B_OK)
    31             return -1;
    32        
     29    team_usage_info info;
     30    pid_t waitPid = _waitpid(pid, status, options,
     31        rusage != NULL ? &info : NULL);
     32    if (waitPid != -1 && rusage != NULL) {
    3333        rusage->ru_utime.tv_sec = info.user_time / 1000000;
    3434        rusage->ru_utime.tv_usec = info.user_time % 1000000;
    3535
  • src/system/kernel/team.cpp

    diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp
    index 1b364fe..5a78c08 100644
    a b job_control_entry::InitDeadState()  
    23692369        reason = team->exit.reason;
    23702370        signal = team->exit.signal;
    23712371        signaling_user = team->exit.signaling_user;
     2372        user_time = team->dead_threads_user_time
     2373            + team->dead_children.user_time;
     2374        kernel_time = team->dead_threads_kernel_time
     2375            + team->dead_children.kernel_time;
    23722376
    23732377        team = NULL;
    23742378    }
    job_control_entry::operator=(const job_control_entry& other)  
    23872391    group_id = other.group_id;
    23882392    status = other.status;
    23892393    reason = other.reason;
     2394    user_time = other.user_time;
     2395    kernel_time = other.kernel_time;
    23902396
    23912397    return *this;
    23922398}
    job_control_entry::operator=(const job_control_entry& other)  
    23952401/*! This is the kernel backend for waitid().
    23962402*/
    23972403static thread_id
    2398 wait_for_child(pid_t child, uint32 flags, siginfo_t& _info)
     2404wait_for_child(pid_t child, uint32 flags, siginfo_t& _info,
     2405    team_usage_info& _usage_info)
    23992406{
    24002407    Thread* thread = thread_get_current_thread();
    24012408    Team* team = thread->team;
    wait_for_child(pid_t child, uint32 flags, siginfo_t& _info)  
    25332540            _info.si_code = foundEntry.reason;
    25342541            _info.si_status = foundEntry.reason == CLD_EXITED
    25352542                ? foundEntry.status : foundEntry.signal;
     2543            _usage_info.user_time = foundEntry.user_time;
     2544            _usage_info.kernel_time = foundEntry.kernel_time;
    25362545            break;
    25372546        case JOB_CONTROL_STATE_STOPPED:
    25382547            _info.si_code = CLD_STOPPED;
    _user_fork(void)  
    39153924
    39163925
    39173926pid_t
    3918 _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* userInfo)
     3927_user_wait_for_child(thread_id child, uint32 flags, siginfo_t* userInfo,
     3928    team_usage_info* usageInfo)
    39193929{
    39203930    if (userInfo != NULL && !IS_USER_ADDRESS(userInfo))
    39213931        return B_BAD_ADDRESS;
     3932    if (usageInfo != NULL && !IS_USER_ADDRESS(usageInfo))
     3933        return B_BAD_ADDRESS;
    39223934
    39233935    siginfo_t info;
    3924     pid_t foundChild = wait_for_child(child, flags, info);
     3936    team_usage_info usage_info;
     3937    pid_t foundChild = wait_for_child(child, flags, info, usage_info);
    39253938    if (foundChild < 0)
    39263939        return syscall_restart_handle_post(foundChild);
    39273940
    39283941    // copy info back to userland
    39293942    if (userInfo != NULL && user_memcpy(userInfo, &info, sizeof(info)) != B_OK)
    39303943        return B_BAD_ADDRESS;
     3944    // copy usage_info back to userland
     3945    if (usageInfo != NULL && user_memcpy(usageInfo, &usage_info,
     3946        sizeof(usage_info)) != B_OK) {
     3947        return B_BAD_ADDRESS;
     3948    }
    39313949
    39323950    return foundChild;
    39333951}
  • src/system/libroot/posix/sys/wait.cpp

    diff --git a/src/system/libroot/posix/sys/wait.cpp b/src/system/libroot/posix/sys/wait.cpp
    index 1c785c9..d410a48 100644
    a b wait(int* _status)  
    2323    return waitpid(-1, _status, 0);
    2424}
    2525
    26 
    27 pid_t
    28 waitpid(pid_t pid, int* _status, int options)
     26extern "C" pid_t
     27_waitpid(pid_t pid, int* _status, int options, team_usage_info *usage_info)
    2928{
    3029    // wait
    3130    siginfo_t info;
    32     pid_t child = _kern_wait_for_child(pid, options, &info);
     31    pid_t child = _kern_wait_for_child(pid, options, &info, usage_info);
    3332
    3433    pthread_testcancel();
    3534
    waitpid(pid_t pid, int* _status, int options)  
    8483}
    8584
    8685
     86pid_t
     87waitpid(pid_t pid, int* _status, int options)
     88{
     89    return _waitpid(pid, _status, options, NULL);
     90}
     91
     92
    8793int
    8894waitid(idtype_t idType, id_t id, siginfo_t* info, int options)
    8995{
    waitid(idtype_t idType, id_t id, siginfo_t* info, int options)  
    111117            RETURN_AND_SET_ERRNO_TEST_CANCEL(EINVAL);
    112118    }
    113119
    114     pid_t child = _kern_wait_for_child(id, options, info);
     120    pid_t child = _kern_wait_for_child(id, options, info, NULL);
    115121    if (child >= 0 || child == B_WOULD_BLOCK)
    116122        return 0;
    117123
  • src/tests/libs/bsd/wait4_test.cpp

    diff --git a/src/tests/libs/bsd/wait4_test.cpp b/src/tests/libs/bsd/wait4_test.cpp
    index e5d761d..46f2615 100644
    a b  
    55
    66
    77#include <errno.h>
     8#include <inttypes.h>
    89#include <stdio.h>
    910#include <string.h>
    1011#include <sys/resource.h>
    main(int argc, char** argv)  
    5556    struct rusage usage;
    5657    pid_t pid;
    5758    do {
     59        memset(&usage, 0, sizeof(usage));
    5860        int childStatus = -1;
    5961        pid = wait4(-1, &childStatus, 0, &usage);
    60         printf("wait4() returned %ld (%s), child status %d\n",
    61             pid, strerror(errno), childStatus);
     62        printf("wait4() returned %" PRId32 " (%s), child status %" PRId32
     63            ", kernel: %ld.%06" PRId32 " user: %ld.%06" PRId32 "\n",
     64            pid, strerror(errno), childStatus, usage.ru_stime.tv_sec,
     65            usage.ru_stime.tv_usec, usage.ru_utime.tv_sec,
     66            usage.ru_utime.tv_usec);
    6267    } while (pid >= 0);
    6368
    6469    return 0;