Make stats module handle only system-wide statistics.
Change-Id: If9b391e7a635ec3185a3459a25ed49c758721f98
config-deserializer.c
appinfo-provider.c
report-json-serializer.c
- stats.c
+ sys-stats.c
clock.c
ipc.c
process.c
struct process *proc = _proc_scanner_find_process_in_history(scanner, pid);
if (!proc) {
- process_init(pid, &proc_new);
+ process_init_process(pid, &proc_new);
proc = &proc_new;
}
#include <string.h>
#include <stdlib.h>
+#include <unistd.h>
#include "process.h"
+#include "clock.h"
+#include "sys-stats.h"
#include "err-check.h"
#include "procfs.h"
#include "appinfo-provider.h"
+static struct sys_stats sys;
+static int pagesize;
+static float timescale;
+
int process_get_memory_usage(struct process *proc, int *usage)
{
ON_NULL_RETURN_VAL(proc, -1);
ticks = info.stime + info.utime;
proc->frame_ticks_used = ticks - proc->total_ticks_used;
proc->total_ticks_used = ticks;
- proc->memory_used = info.rss * stats_get_page_size() / 1024;
+ proc->memory_used = info.rss * pagesize / 1024;
+ float now = clock_monotonic_get();
+ proc->frame_time_inverted = 1.0f / (now - proc->update_time);
+ proc->update_time = now;
return 0;
}
-void process_init(int pid, struct process *proc)
+void process_init_process(int pid, struct process *proc)
{
memset(proc, 0x0, sizeof(struct process));
proc->pid = pid;
src->appid = NULL;
src->exe = NULL;
}
+
+int process_get_cpu_usage_percentage(struct process *proc, float *usage)
+{
+ ON_NULL_RETURN_VAL(proc, -1);
+ ON_NULL_RETURN_VAL(usage, -1);
+
+ *usage = (float)proc->frame_ticks_used * proc->frame_time_inverted * timescale;
+ return 0;
+}
+
+int process_get_memory_usage_percentage(struct process *proc, float *usage)
+{
+ ON_NULL_RETURN_VAL(proc, -1);
+ ON_NULL_RETURN_VAL(usage, -1);
+
+ *usage = (float)proc->memory_used / sys.total_memory;
+ return 0;
+}
+
+int process_init()
+{
+ if (sys_stats_update(&sys) != 0) {
+ ERR("stats_update_system_stats failed.");
+ return -1;
+ }
+ timescale = 1.0f / (float)sysconf(_SC_CLK_TCK);
+ pagesize = getpagesize();
+ return 0;
+}
#ifndef __PROCESS_H
#define __PROCESS_H
-#include <stdbool.h>
-
-#include "stats.h"
-
/**
* @brief The process structure.
*
unsigned long long total_ticks_used;
unsigned long long frame_ticks_used;
int memory_used;
+ float update_time;
+ float frame_time_inverted;
};
/**
+ * @brief Initialize process module.
+ */
+int process_init();
+
+/**
* @brief Gets last read process memory usage
*
* @param[in]: proc process
*
* @return 0 on success, other value on error.
*/
-void process_init(int pid, struct process *proc);
+void process_init_process(int pid, struct process *proc);
/**
* @brief Shutdown process structure
*/
void process_move(struct process *dst, struct process *src);
+/**
+ * @brief Gets average CPU usage percentage since last update.
+ *
+ * @param[in]: proc process
+ * @param[out]: usage the cpu usage percentage
+ *
+ * @return 0 on success, other value on error.
+ */
+int process_get_cpu_usage_percentage(struct process *proc, float *usage);
+
+/**
+ * @brief Gets average memory usage percentage on last update.
+ *
+ * @param[in]: proc process
+ * @param[out]: usage the memory usage percentage
+ *
+ * @return 0 on success, other value on error.
+ */
+int process_get_memory_usage_percentage(struct process *dst, float *usage);
+
#endif
#include "log.h"
#include "err-check.h"
#include "appinfo-provider.h"
-#include "stats.h"
+#include "sys-stats.h"
#include "clock.h"
#include "proc-scanner.h"
+#include "process.h"
struct report_generator_system {
/** system cpu usage statistics */
- struct stats_system previous;
+ struct sys_stats stats;
};
struct report_generator_process
{
/** process pid */
int pid;
- /** process cpu usage statistics */
- struct stats_process previous;
+ /** process statistics */
+ struct process proc;
+ /** update time */
+ float proc_update_time;
};
struct report_generator_app
struct report_generator_top
{
- struct stats_system sys_stats;
+ struct sys_stats sys_stats;
proc_scanner_t *scanner;
report_generator_top_type_e type;
int limit;
};
struct report_generator_top_closure {
- struct stats_system sys_stats;
+ struct sys_stats sys_stats;
int current_index;
int max_index;
struct process_usage_report *usage_report;
if (!ret)
return NULL;
- if (stats_update_system_stats(&ret->previous) != 0) {
+ if (sys_stats_update(&ret->stats) != 0) {
ERR("stats_update_system_stats failed");
free(ret);
return NULL;
if (!ret)
return NULL;
- if (stats_update_process_stats(pid, &ret->previous) != 0) {
- ERR("stats_update_process_stats failed.");
+ process_init(pid, &ret->proc);
+
+ if (process_update(&ret->proc) != 0) {
+ ERR("process_update failed.");
free(ret);
return NULL;
};
+ ret->proc_update_time = clock_monotonic_get();
ret->pid = pid;
return ret;
ON_NULL_RETURN_VAL(report, -1);
float usage;
- struct stats_system current;
- if (stats_update_system_stats(¤t) != 0) {
+ if (sys_stats_update(&generator->stats) != 0) {
ERR("stats_update_system_stats failed.");
return -1;
}
- if (stats_get_system_cpu_usage_average(&generator->previous, ¤t, &usage))
+ if (sys_stats_get_cpu_usage_percentage(&generator->stats, &usage))
{
ERR("stats_get_system_cpu_usage_average failed");
return -1;
report->usage = usage;
report->time = clock_realtime_get();
- generator->previous = current;
-
return 0;
}
float usage;
- if (stats_update_system_stats(&generator->previous) != 0) {
+ if (sys_stats_update(&generator->stats) != 0) {
ERR("stats_update_system_stats failed.");
return -1;
}
- if (stats_get_system_memory_usage(&generator->previous, &usage) != 0) {
+ if (sys_stats_get_memory_usage_percentage(&generator->stats, &usage) != 0) {
ERR("stats_get_system_memory_usage failed.");
return -1;
}
ON_NULL_RETURN_VAL(generator, -1);
ON_NULL_RETURN_VAL(report, -1);
- struct stats_process current = {0,};
float usage;
- if (stats_update_process_stats(generator->pid, ¤t) != 0) {
- ERR("stats_update_process_stats failed.");
+ if (process_update(&generator->proc) != 0) {
+ ERR("process_update failed.");
return -1;
}
- if (stats_get_process_cpu_usage_average(&generator->previous, ¤t, &usage) ) {
- ERR("stats_update_process_stats failed.");
+ if (process_get_cpu_usage_percentage(&generator->proc, &usage) != 0) {
+ ERR("process_get_cpu_usage_percentage failed.");
return -1;
}
report->pid = generator->pid;
report->usage = usage;
- generator->previous = current;
-
return 0;
}
float usage;
- if (stats_get_process_memory_usage(generator->pid, &usage) != 0) {
- ERR("stats_get_process_memory_usage failed.");
+ if (process_get_memory_usage_percentage(&generator->proc, &usage) != 0) {
+ ERR("process_get_memory_usage_percentage failed.");
return -1;
}
float a1, a5, a15;
- if (stats_get_load_averages(&a1, &a5, &a15) != 0) {
+ if (sys_stats_get_load_averages(&a1, &a5, &a15) != 0) {
ERR("stats_get_load_averages failed.");
return -1;
}
report_generator_free_top_generator(gen);
return NULL;
}
- if (stats_update_system_stats(&gen->sys_stats) != 0) {
+ if (sys_stats_update(&gen->sys_stats) != 0) {
report_generator_free_top_generator(gen);
return NULL;
}
struct report_generator_top_closure *closure = data;
struct process_usage_report report = {0,};
const char *appid;
- unsigned long long ticks = 0;
if (closure->current_index >= closure->max_index)
return false;
- if (process_get_cpu_usage(proc, &ticks) != 0) {
+ if (process_get_cpu_usage_percentage(proc, &report.usage) != 0) {
report.usage = NAN;
- } else {
- report.usage = stats_get_cpu_usage_percentage(ticks, closure->sys_stats.frame_time_inverted);
}
appid = process_get_appid(proc);
struct report_generator_top_closure closure = {0,};
- if (stats_update_system_stats(&generator->sys_stats) != 0) {
+ if (sys_stats_update(&generator->sys_stats) != 0) {
return -1;
}
struct report_generator_top_closure closure = {0,};
- if (stats_update_system_stats(&generator->sys_stats) != 0) {
+ if (sys_stats_update(&generator->sys_stats) != 0) {
return -1;
}
+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <unistd.h>
-
-#include "stats.h"
-#include "procfs.h"
-#include "err-check.h"
-#include "clock.h"
-
-static int ncpus;
-static float timescale;
-
-int stats_get_system_cpu_usage_average(struct stats_system *previous, struct stats_system *current, float *usage)
-{
- struct stats_system diff;
-
- diff.busy_ticks = current->busy_ticks > previous->busy_ticks ? current->busy_ticks - previous->busy_ticks : 0;
-
- diff.total_ticks = current->total_ticks > previous->total_ticks ? current->total_ticks - previous->total_ticks : 0;
-
- if (diff.total_ticks == 0) {
- *usage = 0;
- } else {
- *usage = (float)diff.busy_ticks / diff.total_ticks;
- }
-
- return 0;
-}
-
-int stats_update_system_stats(struct stats_system *sys)
-{
- ON_NULL_RETURN_VAL(sys, -1);
-
- struct procfs_stat cpu_info;
- struct procfs_meminfo mem_info;
-
- if (procfs_read_stat(&cpu_info) != 0) {
- return -1;
- }
-
- if (procfs_read_meminfo(&mem_info) != 0) {
- ERR("procfs_read_meminfo failed.");
- return -1;
- }
-
- sys->busy_ticks = cpu_info.user + cpu_info.system + cpu_info.nice + cpu_info.irq + cpu_info.softirq;
- sys->total_ticks = cpu_info.user + cpu_info.system + cpu_info.nice + cpu_info.irq + cpu_info.softirq + cpu_info.idle + cpu_info.iowait;
- sys->memory_used = mem_info.used;
- sys->total_memory = mem_info.total;
-
- float now = clock_monotonic_get();
- sys->frame_time_inverted = 1.0f / (now - sys->update_time);
- sys->update_time = now;
-
- return 0;
-}
-
-int stats_get_system_memory_usage(struct stats_system *sys, float *usage)
-{
- ON_NULL_RETURN_VAL(usage, -1);
-
- *usage = (float)sys->memory_used / sys->total_memory;
-
- return 0;
-}
-
-int stats_update_process_stats(int pid, struct stats_process *stats)
-{
- ON_TRUE_RETURN_VAL(pid < 0, -1);
- ON_NULL_RETURN_VAL(stats, -1);
-
- struct procfs_process_stat proc_info;
- struct procfs_stat sys_info;
-
- if (procfs_read_process_stat(pid, &proc_info) != 0) {
- ERR("procfs_read_process_stat failed.");
- return -1;
- }
-
- if (procfs_read_stat(&sys_info) != 0) {
- ERR("procfs_read_stat failed.");
- return -1;
- }
-
- stats->process_ticks = proc_info.stime + proc_info.utime;
- stats->system_ticks = sys_info.user + sys_info.system + sys_info.nice + sys_info.idle;
-
- return 0;
-}
-
-int stats_get_process_cpu_usage_average(struct stats_process *previous, struct stats_process *current, float *usage)
-{
- struct stats_process diff;
-
- diff.process_ticks = current->process_ticks > previous->process_ticks ? current->process_ticks - previous->process_ticks: 0;
- diff.system_ticks = current->system_ticks > previous->system_ticks ? current->system_ticks - previous->system_ticks : 0;
-
- if (diff.system_ticks == 0)
- *usage = 0;
- else
- *usage = (float)diff.process_ticks / diff.system_ticks * ncpus;
-
- return 0;
-}
-
-int stats_get_process_memory_usage(int pid, float *usage)
-{
- ON_TRUE_RETURN_VAL(pid < 0, -1);
- ON_NULL_RETURN_VAL(usage, -1);
-
- struct procfs_process_smaps mem_info;
- struct procfs_meminfo sys_meminfo;
-
- if (procfs_read_process_smaps(pid, &mem_info) != 0) {
- ERR("procfs_read_process_smaps failed.");
- return -1;
- }
-
- if (procfs_read_meminfo(&sys_meminfo) != 0) {
- ERR("procfs_read_meminfo failed.");
- return -1;
- }
-
- *usage = sys_meminfo.total > 0 ? (float)mem_info.rss / sys_meminfo.total : 0;
-
- return 0;
-}
-
-int stats_get_load_averages(float *a1, float *a5, float *a15)
-{
- struct procfs_loadavg info;
-
- if (procfs_read_loadavg(&info) != 0) {
- ERR("procfs_read_loadavg failed.");
- return -1;
- }
-
- if (a1) *a1 = info.one_min_avg;
- if (a5) *a5 = info.five_min_avg;
- if (a15) *a15 = info.fifteen_min_avg;
-
- return 0;
-}
-
-float stats_get_cpu_usage_percentage(unsigned long long ticks_delta, float ticks_time_inverted)
-{
- return (float)ticks_delta * ticks_time_inverted * timescale;
-}
-
-int stats_init()
-{
- if (procfs_read_cpu_possible(&ncpus) != 0) {
- ERR("procfs_read_cpu_possible failed.");
- return -1;
- }
- timescale = 1.0f / (float)sysconf(_SC_CLK_TCK);
- return 0;
-}
-
-int stats_get_page_size()
-{
- return getpagesize();
-}
+++ /dev/null
-/*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
- *
- * Licensed under the Flora License, Version 1.1 (the License);
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://floralicense.org/license/
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _STATS_H_
-#define _STATS_H_
-
-#include <time.h>
-
-/**
- * @brief System's statistics snapshot
- */
-struct stats_system
-{
- unsigned long long busy_ticks;
- unsigned long long total_ticks;
- unsigned long long memory_used;
- unsigned long long total_memory;
- float update_time;
- float frame_time_inverted;
-};
-
-/**
- * @brief Process's statistics snapshot
- */
-struct stats_process
-{
- unsigned long long system_ticks;
- unsigned long long process_ticks;
-};
-
-/**
- * @brief Initializes stats module.
- *
- * @return: 0 on success, other value on error.
- *
- * @note function should be called before any other function call from this
- * module.
- */
-int stats_init();
-
-/**
- * @brief Calculates average cpu usage between two stats snapshots.
- *
- * @param[in] previous the stats snapshots taken before current
- * @param[in] current the stats snapshots taken after previous
- * @param[out] usage the cpu usage as percent.
- *
- * @return: 0 on success, other value on error
- */
-int stats_get_system_cpu_usage_average(struct stats_system *previous, struct stats_system *current, float *usage);
-
-/**
- * @brief Takes system statistics snapshot.
- *
- * @param[out] stats System's statistics snapshot.
- *
- * @return: 0 on success, other value on error
- */
-int stats_update_system_stats(struct stats_system *stats);
-
-/**
- * @brief Calculates system memory usage.
- *
- * @param[out] usage the memory usage as percent.
- *
- * @return: 0 on success, other value on error
- */
-int stats_get_system_memory_usage(struct stats_system *stats, float *usage);
-
-/**
- * @brief Takes process statistics snapshot.
- *
- * @param[in] pid the process id.
- * @param[out] stats process statistcs.
- *
- * @return: 0 on success, other value on error
- */
-int stats_update_process_stats(int pid, struct stats_process *stats);
-
-/**
- * @brief Calculates average process cpu usage between two stats snapshots.
- *
- * @param[in] previous the stats snapshots taken before current
- * @param[in] current the stats snapshots taken after previous
- * @param[out] usage the cpu usage as percent. It may be greater then 100% in
- * case of multithreaded applications.
- *
- * @note in case when process has 2 threads which runs tight loop, the function
- * will report 200% usage.
- *
- * @return: 0 on success, other value on error
- */
-int stats_get_process_cpu_usage_average(struct stats_process *previous, struct stats_process *current, float *usage);
-
-/**
- * @brief Calculates process memory usage.
- *
- * @param[in] pid the process id.
- * @param[out] usage process memory usage.
- *
- * @return: 0 on success, other value on error
- */
-int stats_get_process_memory_usage(int pid, float *usage);
-
-/**
- * @brief Gets system load averages stats.
- *
- * @param[out] a1 one minute average.
- * @param[out] a5 five minute average.
- * @param[out] a15 fifteen minute average.
- *
- * @return: 0 on success, other value on error
- */
-int stats_get_load_averages(float *a1, float *a5, float *a15);
-
-/**
- * @brief Gets CPU usage percentage
- *
- * @param[in] ticks_delta the amount of clock ticks
- * @param[in] ticks_time_inverted the time of ticks_delete inverted ^-1
- *
- * @return: CPU usage perecentage
- *
- * @note in case when process has 2 threads which runs tight loop, the function
- * will report 200% usage (2.0f).
- */
-float stats_get_cpu_usage_percentage(unsigned long long ticks_delta, float ticks_time_inverted);
-
-/**
- * @brief Get system's page size in bytes.
- *
- * @return page size
- */
-int stats_get_page_size();
-
-#endif
-
-
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+
+#include "sys-stats.h"
+#include "procfs.h"
+#include "err-check.h"
+#include "clock.h"
+
+int sys_stats_get_cpu_usage_percentage(struct sys_stats *stats, float *usage)
+{
+ ON_NULL_RETURN_VAL(stats, -1);
+ ON_NULL_RETURN_VAL(usage, -1);
+
+ if (stats->total_ticks_delta == 0) {
+ *usage = 0;
+ } else {
+ *usage = (float)stats->busy_ticks_delta / stats->total_ticks_delta;
+ }
+
+ return 0;
+}
+
+int sys_stats_update(struct sys_stats *sys)
+{
+ ON_NULL_RETURN_VAL(sys, -1);
+
+ struct procfs_stat cpu_info;
+ struct procfs_meminfo mem_info;
+ unsigned long long ticks;
+
+ if (procfs_read_stat(&cpu_info) != 0) {
+ ERR("procfs_read_stat failed.");
+ return -1;
+ }
+
+ if (procfs_read_meminfo(&mem_info) != 0) {
+ ERR("procfs_read_meminfo failed.");
+ return -1;
+ }
+
+ ticks = cpu_info.user + cpu_info.system + cpu_info.nice + cpu_info.irq + cpu_info.softirq;
+ sys->busy_ticks_delta = ticks > sys->busy_ticks ? ticks - sys->busy_ticks : 0;
+ sys->busy_ticks = ticks;
+
+ ticks = cpu_info.user + cpu_info.system + cpu_info.nice + cpu_info.irq +
+ cpu_info.softirq + cpu_info.idle + cpu_info.iowait;
+ sys->total_ticks_delta = ticks > sys->total_ticks ? ticks - sys->total_ticks : 0;
+ sys->total_ticks = ticks;
+
+ sys->memory_used = mem_info.used;
+ sys->total_memory = mem_info.total;
+
+ return 0;
+}
+
+int sys_stats_get_memory_usage_percentage(struct sys_stats *sys, float *usage)
+{
+ ON_NULL_RETURN_VAL(sys, -1);
+ ON_NULL_RETURN_VAL(usage, -1);
+
+ *usage = (float)sys->memory_used / sys->total_memory;
+
+ return 0;
+}
+
+int sys_stats_get_load_averages(float *a1, float *a5, float *a15)
+{
+ struct procfs_loadavg info;
+
+ if (procfs_read_loadavg(&info) != 0) {
+ ERR("procfs_read_loadavg failed.");
+ return -1;
+ }
+
+ if (a1) *a1 = info.one_min_avg;
+ if (a5) *a5 = info.five_min_avg;
+ if (a15) *a15 = info.fifteen_min_avg;
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SYS_STATS_H_
+#define _SYS_STATS_H_
+
+/**
+ * @brief System's statistics snapshot
+ */
+struct sys_stats
+{
+ unsigned long long busy_ticks;
+ unsigned long long busy_ticks_delta;
+ unsigned long long total_ticks;
+ unsigned long long total_ticks_delta;
+ unsigned long long memory_used;
+ unsigned long long total_memory;
+};
+
+/**
+ * @brief Calculates average cpu usage between two stats snapshots.
+ *
+ * @param[in] stats the stats snapshots
+ * @param[out] usage the cpu usage as percent.
+ *
+ * @return: 0 on success, other value on error
+ */
+int sys_stats_get_cpu_usage_percentage(struct sys_stats *stats, float *usage);
+
+/**
+ * @brief Takes system statistics snapshot.
+ *
+ * @param[out] stats System's statistics snapshot.
+ *
+ * @return: 0 on success, other value on error
+ */
+int sys_stats_update(struct sys_stats *stats);
+
+/**
+ * @brief Calculates system memory usage.
+ *
+ * @param[out] usage the memory usage as percent.
+ *
+ * @return: 0 on success, other value on error
+ */
+int sys_stats_get_memory_usage_percentage(struct sys_stats *stats, float *usage);
+
+/**
+ * @brief Gets system load averages stats.
+ *
+ * @param[out] a1 one minute average.
+ * @param[out] a5 five minute average.
+ * @param[out] a15 fifteen minute average.
+ *
+ * @return: 0 on success, other value on error
+ */
+int sys_stats_get_load_averages(float *a1, float *a5, float *a15);
+
+#endif
#include "log.h"
#include "scheduler.h"
#include "task-worker.h"
-#include "stats.h"
+#include "process.h"
#include "ipc.h"
static gboolean sigint_handler(gpointer user_data);
app_provider_init();
ipc_init(argv[1], task_counter);
- if (stats_init() != 0)
+ if (process_init() != 0)
{
- ERR("Stats module initialization failed");
+ ERR("Process module initialization failed");
g_free(data.current_config);
ipc_shutdown();
app_provider_shutdown();
g_main_loop_quit(data.main_loop);
return TRUE;
-}
\ No newline at end of file
+}