<commit_before>/*
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of SIGAR.
 * 
 * SIGAR is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#include <errno.h>
#include <stdio.h>

#ifndef WIN32
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/time.h>
#endif
#if defined(__OpenBSD__) || defined(__FreeBSD__)
#include <netinet/in.h>
#endif

#include "sigar.h"
#include "sigar_private.h"
#include "sigar_util.h"
#include "sigar_os.h"
#include "sigar_format.h"

SIGAR_DECLARE(int) sigar_open(sigar_t **sigar)
{
    int status = sigar_os_open(sigar);

    if (status == SIGAR_OK) {
        /* use env to revert to old behavior */
        (*sigar)->cpu_list_cores = getenv("SIGAR_CPU_LIST_SOCKETS") ? 0 : 1;
        (*sigar)->pid = 0;
        (*sigar)->ifconf_buf = NULL;
        (*sigar)->ifconf_len = 0;
        (*sigar)->log_level = -1; /* log nothing by default */
        (*sigar)->log_impl = NULL;
        (*sigar)->log_data = NULL;
        (*sigar)->ptql_re_impl = NULL;
        (*sigar)->ptql_re_data = NULL;
        (*sigar)->self_path = NULL;
        (*sigar)->fsdev = NULL;
        (*sigar)->pids = NULL;
        (*sigar)->proc_cpu = NULL;
        (*sigar)->net_listen = NULL;
        (*sigar)->net_services_tcp = NULL;
        (*sigar)->net_services_udp = NULL;
    }

    return status;
}

SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
{
    if (sigar->ifconf_buf) {
        free(sigar->ifconf_buf);
    }
    if (sigar->self_path) {
        free(sigar->self_path);
    }
    if (sigar->pids) {
        sigar_proc_list_destroy(sigar, sigar->pids);
        free(sigar->pids);
    }
    if (sigar->fsdev) {
        sigar_cache_destroy(sigar->fsdev);
    }
    if (sigar->proc_cpu) {
        sigar_cache_destroy(sigar->proc_cpu);
    }
    if (sigar->net_listen) {
        sigar_cache_destroy(sigar->net_listen);
    }
    if (sigar->net_services_tcp) {
        sigar_cache_destroy(sigar->net_services_tcp);
    }
    if (sigar->net_services_udp) {
        sigar_cache_destroy(sigar->net_services_udp);
    }

    return sigar_os_close(sigar);
}

#ifndef __linux__ /* linux has a special case */
SIGAR_DECLARE(sigar_pid_t) sigar_pid_get(sigar_t *sigar)
{
    if (!sigar->pid) {
        sigar->pid = getpid();
    }

    return sigar->pid;
}
#endif

/* XXX: add clear() function */
/* XXX: check for stale-ness using start_time */
SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
                                      sigar_proc_cpu_t *proccpu)
{
    sigar_cache_entry_t *entry;
    sigar_proc_cpu_t *prev;
    sigar_uint64_t otime, time_now = sigar_time_now_millis();
    sigar_uint64_t time_diff, total_diff;
    int status;

    if (!sigar->proc_cpu) {
        sigar->proc_cpu = sigar_cache_new(128);
    }

    entry = sigar_cache_get(sigar->proc_cpu, pid);
    if (entry->value) {
        prev = (sigar_proc_cpu_t *)entry->value;
    }
    else {
        prev = entry->value = malloc(sizeof(*prev));
        SIGAR_ZERO(prev);
    }

    time_diff = time_now - prev->last_time;
    proccpu->last_time = prev->last_time = time_now;

    if (time_diff == 0) {
        /* we were just called within < 1 second ago. */
        memcpy(proccpu, prev, sizeof(*proccpu));
        return SIGAR_OK;
    }

    otime = prev->total;

    status =
        sigar_proc_time_get(sigar, pid,
                            (sigar_proc_time_t *)proccpu);

    if (status != SIGAR_OK) {
        return status;
    }

    memcpy(prev, proccpu, sizeof(*prev));

    if (proccpu->total < otime) {
        /* XXX this should not happen */
        otime = 0;
    }

    if (otime == 0) {
        proccpu->percent = 0.0;
        /* first time called */
        return SIGAR_OK;
    }

    total_diff = proccpu->total - otime;
    proccpu->percent = total_diff / (double)time_diff;
    if (proccpu->percent > 1.0) {
        proccpu->percent = 1.0;
    }

    return SIGAR_OK;
}

SIGAR_DECLARE(int) sigar_proc_stat_get(sigar_t *sigar,
                                       sigar_proc_stat_t *procstat)
{
    int status, i;
    sigar_proc_list_t *pids;

    SIGAR_ZERO(procstat);
    procstat->threads = SIGAR_FIELD_NOTIMPL;

    if ((status = sigar_proc_list_get(sigar, NULL)) != SIGAR_OK) {
        return status;
    }

    pids = sigar->pids;
    procstat->total = pids->number;

    for (i=0; i<pids->number; i++) {
        sigar_proc_state_t state;

        status = sigar_proc_state_get(sigar, pids->data[i], &state);
        if (status != SIGAR_OK) {<commit_msg>(SIGAR-145) default to 'Irix mode' for proc_cpu.percent<commit_after>/*
 * Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
 * This file is part of SIGAR.
 * 
 * SIGAR is free software; you can redistribute it and/or modify
 * it under the terms version 2 of the GNU General Public License as
 * published by the Free Software Foundation. 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#include <errno.h>
#include <stdio.h>

#ifndef WIN32
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/time.h>
#endif
#if defined(__OpenBSD__) || defined(__FreeBSD__)
#include <netinet/in.h>
#endif

#include "sigar.h"
#include "sigar_private.h"
#include "sigar_util.h"
#include "sigar_os.h"
#include "sigar_format.h"

SIGAR_DECLARE(int) sigar_open(sigar_t **sigar)
{
    int status = sigar_os_open(sigar);

    if (status == SIGAR_OK) {
        /* use env to revert to old behavior */
        (*sigar)->cpu_list_cores = getenv("SIGAR_CPU_LIST_SOCKETS") ? 0 : 1;
        (*sigar)->pid = 0;
        (*sigar)->ifconf_buf = NULL;
        (*sigar)->ifconf_len = 0;
        (*sigar)->log_level = -1; /* log nothing by default */
        (*sigar)->log_impl = NULL;
        (*sigar)->log_data = NULL;
        (*sigar)->ptql_re_impl = NULL;
        (*sigar)->ptql_re_data = NULL;
        (*sigar)->self_path = NULL;
        (*sigar)->fsdev = NULL;
        (*sigar)->pids = NULL;
        (*sigar)->proc_cpu = NULL;
        (*sigar)->net_listen = NULL;
        (*sigar)->net_services_tcp = NULL;
        (*sigar)->net_services_udp = NULL;
    }

    return status;
}

SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
{
    if (sigar->ifconf_buf) {
        free(sigar->ifconf_buf);
    }
    if (sigar->self_path) {
        free(sigar->self_path);
    }
    if (sigar->pids) {
        sigar_proc_list_destroy(sigar, sigar->pids);
        free(sigar->pids);
    }
    if (sigar->fsdev) {
        sigar_cache_destroy(sigar->fsdev);
    }
    if (sigar->proc_cpu) {
        sigar_cache_destroy(sigar->proc_cpu);
    }
    if (sigar->net_listen) {
        sigar_cache_destroy(sigar->net_listen);
    }
    if (sigar->net_services_tcp) {
        sigar_cache_destroy(sigar->net_services_tcp);
    }
    if (sigar->net_services_udp) {
        sigar_cache_destroy(sigar->net_services_udp);
    }

    return sigar_os_close(sigar);
}

#ifndef __linux__ /* linux has a special case */
SIGAR_DECLARE(sigar_pid_t) sigar_pid_get(sigar_t *sigar)
{
    if (!sigar->pid) {
        sigar->pid = getpid();
    }

    return sigar->pid;
}
#endif

/* XXX: add clear() function */
/* XXX: check for stale-ness using start_time */
SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
                                      sigar_proc_cpu_t *proccpu)
{
    sigar_cache_entry_t *entry;
    sigar_proc_cpu_t *prev;
    sigar_uint64_t otime, time_now = sigar_time_now_millis();
    sigar_uint64_t time_diff, total_diff;
    int status;

    if (!sigar->proc_cpu) {
        sigar->proc_cpu = sigar_cache_new(128);
    }

    entry = sigar_cache_get(sigar->proc_cpu, pid);
    if (entry->value) {
        prev = (sigar_proc_cpu_t *)entry->value;
    }
    else {
        prev = entry->value = malloc(sizeof(*prev));
        SIGAR_ZERO(prev);
    }

    time_diff = time_now - prev->last_time;
    proccpu->last_time = prev->last_time = time_now;

    if (time_diff == 0) {
        /* we were just called within < 1 second ago. */
        memcpy(proccpu, prev, sizeof(*proccpu));
        return SIGAR_OK;
    }

    otime = prev->total;

    status =
        sigar_proc_time_get(sigar, pid,
                            (sigar_proc_time_t *)proccpu);

    if (status != SIGAR_OK) {
        return status;
    }

    memcpy(prev, proccpu, sizeof(*prev));

    if (proccpu->total < otime) {
        /* XXX this should not happen */
        otime = 0;
    }

    if (otime == 0) {
        proccpu->percent = 0.0;
        /* first time called */
        return SIGAR_OK;
    }

    total_diff = proccpu->total - otime;
    proccpu->percent = total_diff / (double)time_diff;

    return SIGAR_OK;
}

SIGAR_DECLARE(int) sigar_proc_stat_get(sigar_t *sigar,
                                       sigar_proc_stat_t *procstat)
{
    int status, i;
    sigar_proc_list_t *pids;

    SIGAR_ZERO(procstat);
    procstat->threads = SIGAR_FIELD_NOTIMPL;

    if ((status = sigar_proc_list_get(sigar, NULL)) != SIGAR_OK) {
        return status;
    }

    pids = sigar->pids;
    procstat->total = pids->number;

    for (i=0; i<pids->number; i++) {
        sigar_proc_state_t state;

        status = sigar_proc_state_get(sigar, pids->data[i], &state);
        if (status != SIGAR_OK) {
{'fraction_non_alphanumeric': 0.1283743842364532, 'fraction_numerical': 0.010147783251231527, 'mean_word_length': 2.607320540156361, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 130, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2425184', 'n_tokens_mistral': 3740, 'n_tokens_neox': 3585, 'n_words': 805}