/*
 * libsysactivity
 * http://sourceforge.net/projects/libsysactivity/
 * Copyright (c) 2009-2011 Carlos Olmedo Escobar <carlos.olmedo.e@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

/**
 * \defgroup cpu CPU interface
 * @{
 */
#ifndef SA_CPU_H_
#define SA_CPU_H_

/** \struct sa_cpu cpu.h
 * This structure gathers the details about one cpu's activity.
 */
struct sa_cpu {
#ifdef SA_CPU_ID
	uint16_t id; //!< Cpu identificator. 0 is the first one.
#endif
#ifdef SA_CPU_USER
	float user; //!< Percentage of time spent on user tasks
#endif
#ifdef SA_CPU_NICE
	float nice; //!< Percentage of time spent on nice prioriced tasks
#endif
#ifdef SA_CPU_SYSTEM
	float system; //!< Percentage of time spent on system tasks
#endif
#ifdef SA_CPU_IDLE
	float idle; //!< Percentage of time with no activity
#endif
#ifdef SA_CPU_WAITING_FOR_IO
	float waiting_for_io; //!< Percentage of time spent waiting for io transferences
#endif
#ifdef SA_CPU_HARDWARE_IRQ
	float hardware_irq; //!< Percentage of time spent working on hardware irqs
#endif
#ifdef SA_CPU_SOFTWARE_IRQ
	float software_irq; //!< Percentage of time spent working on software irqs
#endif
#ifdef SA_CPU_STOLEN
	float stolen; //!< Percentage of time spent in other operating systems when running in a virtualized environment
#endif
#ifdef SA_CPU_INTR
	float intr;
#endif
};

#ifdef SA_OPEN_CPU
/**
 * Prepares the resources needed for retrieving cpu statistics. This function exists (and is needed) only when SA_OPEN_CPU is defined.
 * @return If successful 0 is returned, otherwise an error code is returned. If the operating system is not supported the return value will be ENOTSUP.
 * @see sa_close_cpu()
 */
int sa_open_cpu(void) SA_EXPORT;
#endif

#ifdef SA_CLOSE_CPU
/**
 * This function closes the resources used for retrieving cpu statistics. You should call it even when there was a previous error in another function of this API. This function exists (and is needed) only when SA_CLOSE_CPU is defined.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @see sa_open_cpu()
 */
int sa_close_cpu(void) SA_EXPORT;
#endif

/**
 * Refreshes the underlying operating system cache.
 * @return If successful 0 is returned, otherwise an error code is returned.
 * @since 0.6.0
 */
int sa_reset_cpus() SA_EXPORT;

/**
 * Gives the number of processors that you can take statistics from.
 * You don't need to call sa_reset_cpus() before this function.
 * @param number If the underlying platform does not support per-process stats this number will be 1 (even when there are many real CPUs). See the \ref matrix_cpu_sec "cpu matrix" for further information.
 * @return If successful 0 is returned, otherwise an error code is returned.
 */
int sa_count_cpus(uint16_t* number) SA_EXPORT SA_NONNULL;

/**
 * \brief Retrieves statistics from a given cpu index.
 * This data is an average calculated since last time it was retrieved. If it was never calculated before it makes an average of the entire life of the cpu.
 * sa_reset_cpus() should be called at least once before this function and everytime you need fresh values.
 * @param index The cpu index. The first index value is 0.
 * @param dst Where the statistics will be stored.
 * @return If successful 0 is returned, otherwise an error code is returned. ENODEV is returned when the requested cpu index was out of range.
 */
int sa_get_cpu(uint16_t index, struct sa_cpu* dst) SA_EXPORT SA_NONNULL;

/**
 * \brief Retrieves statistics from as many processors as possible.
 * The data of each cpu is an average calculated since last time it was retrieved. If it was never calculated before it makes an average of the entire life of the cpu.
 * sa_reset_cpus() should be called at least once before this function and everytime you need fresh values.
 * @param dst A buffer where the statistics will be stored.
 * @param dst_size The number of cpus that fits in the dst buffer. If it's not big enough dst will be filled but ENOMEM will be returned.
 * @param written The amount of cpu statistics written.
 * @return If successful 0 is returned, otherwise an error code is returned.
 */
int sa_get_cpus(struct sa_cpu* dst, uint16_t dst_size, uint16_t* written) SA_EXPORT SA_NONNULL;

/*@}*/
#endif /* SA_CPU_H_ */
