/*
 *  BSD process related system call helpers
 *
 *  Copyright (c) 2013-14 Stacey D. Son
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
#include "qemu/osdep.h"

#include <sys/param.h>
#include <sys/cpuset.h>
#include <sys/resource.h>
#include <sys/wait.h>

#include "qemu.h"
#include "qemu-bsd.h"
#include "signal-common.h"

#include "bsd-proc.h"

/*
 * resource/rusage conversion
 */
int target_to_host_resource(int code)
{
    return code;
}

rlim_t target_to_host_rlim(abi_llong target_rlim)
{
    return tswap64(target_rlim);
}

abi_llong host_to_target_rlim(rlim_t rlim)
{
    return tswap64(rlim);
}

void h2g_rusage(const struct rusage *rusage,
                struct target_freebsd_rusage *target_rusage)
{
    __put_user(rusage->ru_utime.tv_sec, &target_rusage->ru_utime.tv_sec);
    __put_user(rusage->ru_utime.tv_usec, &target_rusage->ru_utime.tv_usec);

    __put_user(rusage->ru_stime.tv_sec, &target_rusage->ru_stime.tv_sec);
    __put_user(rusage->ru_stime.tv_usec, &target_rusage->ru_stime.tv_usec);

    __put_user(rusage->ru_maxrss, &target_rusage->ru_maxrss);
    __put_user(rusage->ru_idrss, &target_rusage->ru_idrss);
    __put_user(rusage->ru_idrss, &target_rusage->ru_idrss);
    __put_user(rusage->ru_isrss, &target_rusage->ru_isrss);
    __put_user(rusage->ru_minflt, &target_rusage->ru_minflt);
    __put_user(rusage->ru_majflt, &target_rusage->ru_majflt);
    __put_user(rusage->ru_nswap, &target_rusage->ru_nswap);
    __put_user(rusage->ru_inblock, &target_rusage->ru_inblock);
    __put_user(rusage->ru_oublock, &target_rusage->ru_oublock);
    __put_user(rusage->ru_msgsnd, &target_rusage->ru_msgsnd);
    __put_user(rusage->ru_msgrcv, &target_rusage->ru_msgrcv);
    __put_user(rusage->ru_nsignals, &target_rusage->ru_nsignals);
    __put_user(rusage->ru_nvcsw, &target_rusage->ru_nvcsw);
    __put_user(rusage->ru_nivcsw, &target_rusage->ru_nivcsw);
}

abi_long host_to_target_rusage(abi_ulong target_addr,
        const struct rusage *rusage)
{
    struct target_freebsd_rusage *target_rusage;

    if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) {
        return -TARGET_EFAULT;
    }
    h2g_rusage(rusage, target_rusage);
    unlock_user_struct(target_rusage, target_addr, 1);

    return 0;
}

abi_long host_to_target_wrusage(abi_ulong target_addr,
                                const struct __wrusage *wrusage)
{
    struct target_freebsd__wrusage *target_wrusage;

    if (!lock_user_struct(VERIFY_WRITE, target_wrusage, target_addr, 0)) {
        return -TARGET_EFAULT;
    }
    h2g_rusage(&wrusage->wru_self, &target_wrusage->wru_self);
    h2g_rusage(&wrusage->wru_children, &target_wrusage->wru_children);
    unlock_user_struct(target_wrusage, target_addr, 1);

    return 0;
}

/*
 * wait status conversion.
 *
 * Map host to target signal numbers for the wait family of syscalls.
 * Assume all other status bits are the same.
 */
int host_to_target_waitstatus(int status)
{
    if (WIFSIGNALED(status)) {
        return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f);
    }
    if (WIFSTOPPED(status)) {
        return (host_to_target_signal(WSTOPSIG(status)) << 8) | (status & 0xff);
    }
    return status;
}

int bsd_get_ncpu(void)
{
    int ncpu = -1;
    cpuset_t mask;

    CPU_ZERO(&mask);

    if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(mask),
                           &mask) == 0) {
        ncpu = CPU_COUNT(&mask);
    }

    if (ncpu == -1) {
        ncpu = sysconf(_SC_NPROCESSORS_ONLN);
    }

    if (ncpu == -1) {
        gemu_log("XXX Missing bsd_get_ncpu() implementation\n");
        ncpu = 1;
    }

    return ncpu;
}

