aboutsummaryrefslogtreecommitdiff
path: root/dataservices/datatop/src/datatop.c
diff options
context:
space:
mode:
authorLuca Stefani <luca020400@lineageos.org>2017-08-24 22:24:29 +0200
committerdd3boh <dade.garberi@gmail.com>2017-09-17 14:13:47 +0200
commit66c36e2cb752b01a8c7fbe45e32ccc1681fb9d4b (patch)
treeabb6d0f255601442e21e1caea3ccb5c6a7b077d4 /dataservices/datatop/src/datatop.c
parent7d3687801d2c4b503807698e34a5a3dd881bfce4 (diff)
msm8996-common: Import marlin dataservices
Change-Id: I9d2e47585ac93bbdf28e275e9ec0c669b9f8be3e Signed-off-by: Marco Zanin (B--B) <mrczn.bb@gmail.com>
Diffstat (limited to 'dataservices/datatop/src/datatop.c')
-rw-r--r--dataservices/datatop/src/datatop.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/dataservices/datatop/src/datatop.c b/dataservices/datatop/src/datatop.c
new file mode 100644
index 0000000..f079c30
--- /dev/null
+++ b/dataservices/datatop/src/datatop.c
@@ -0,0 +1,283 @@
+/************************************************************************
+Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+************************************************************************/
+
+/**
+* @file datatop.c
+* @brief Executes commands for application.
+*
+* Contains the main() function where program executes. Calls appropriate
+* methods based on user's CLI commands. Executes parsing function to
+* determine necessary output and handles errors which may arise during the
+* parse. Initiliazes files for data collection. Will call functions designed
+* to poll and print the data in understandable format.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include "datatop_interface.h"
+#include "datatop_linked_list.h"
+#include "datatop_opt.h"
+#include "datatop_fileops.h"
+#include "datatop_polling.h"
+#include "datatop_gen_poll.h"
+
+struct dtop_linked_list *first_dpg_list;
+struct cli_opts usr_cl_opts;
+
+/**
+ * @brief Prints the datapoint names and values to the terminal.
+ *
+ * @param dpg_list A pointer to the first node of a linked list which
+ * contains all data_point_gatherer structs to print.
+ */
+void dtop_print_terminal(struct dtop_linked_list *dpg_list)
+{
+ struct dtop_linked_list *curr_ptr = dpg_list;
+ struct dtop_data_point_gatherer *dpset;
+
+ while (curr_ptr) {
+ dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
+ dtop_print_dpg(dpset);
+ curr_ptr = curr_ptr->next_ptr;
+ }
+}
+
+/**
+ * @brief Polls the data periodically and prints to file specified by the user.
+ *
+ * Polls the data as often as specified by the user in their CLI arguments
+ * and outputs the data to a file also specified in CLI arguments. Then prints
+ * a snapshot of delta(dp_value) to the terminal.
+ *
+ * @param dpg_list A pointer to the first node of a linked list which contains
+ * all data_point_gatherer structs to poll and print.
+ * @param fw A pointer to the file which will be printed to.
+ * @return FILE_ERROR - Writing to file was unsuccessful.
+ * @return FILE_SUCCESS - Writing to file was successful.
+ */
+int dtop_poll_periodically(struct dtop_linked_list *dpg_list, FILE *fw)
+{
+ struct timeval tv, timeout;
+ fd_set rfds;
+ time_t curtime, endtime;
+ int inp, quit = 0;
+ struct dtop_linked_list *curr_ptr = dpg_list;
+ struct dtop_data_point_gatherer *dpset;
+ struct timeval ftime, itime, polltime;
+
+ gettimeofday(&tv, NULL);
+ curtime = tv.tv_sec;
+ endtime = tv.tv_sec + usr_cl_opts.poll_time;
+
+ /* print all of our datapoint names as column headers in csv format */
+ if (fprintf(fw, "\"Time\",") < 0)
+ return FILE_ERROR;
+
+ while (curr_ptr) {
+ dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
+ if (dtop_print_dpg_names_csv(dpset, fw) == FILE_ERROR)
+ return FILE_ERROR;
+ curr_ptr = curr_ptr->next_ptr;
+ }
+ if (fprintf(fw, "\n") < 0)
+ return FILE_ERROR;
+
+ dtop_print_interactive_opts();
+ gettimeofday(&itime, NULL);
+ /* periodically poll the datapoints and print in csv format */
+ while (curtime < endtime
+ || usr_cl_opts.poll_time == POLL_NOT_SPECIFIED) {
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+ timeout.tv_sec = usr_cl_opts.poll_per;
+ timeout.tv_usec = 0;
+ //ftime is right before timeout calculations for most acurate calculations
+ gettimeofday(&ftime, NULL);
+ timersub(&ftime, &itime, &polltime);
+ timersub(&timeout,&polltime, &timeout);
+ inp = select(1, &rfds, NULL, NULL, &timeout);
+ gettimeofday(&itime, NULL);
+ if (inp) {
+ char s[4];
+ scanf("%s", s);
+ if (strcmp(s, "quit") == 0
+ || strcmp(s, "q") == 0) {
+ quit = QUIT;
+ break;
+ }
+ if (strcmp(s, "i") == 0) {
+ dtop_print_snapshot_diff(first_dpg_list);
+ dtop_reset_dp_initial_values(first_dpg_list);
+ }
+ if (strcmp(s, "l") == 0)
+ dtop_print_snapshot_diff(first_dpg_list);
+ }
+ gettimeofday(&tv, NULL);
+ curtime = tv.tv_sec;
+ dtop_poll(dpg_list);
+ printf("Polled at %ld.%06ld\n", tv.tv_sec, tv.tv_usec);
+ if (dtop_print_time_at_poll(fw) == FILE_ERROR)
+ return FILE_ERROR;
+ if (dtop_write_pollingdata_csv(dpg_list, fw) == FILE_ERROR)
+ return FILE_ERROR;
+ }
+
+ if (quit != QUIT)
+ dtop_print_snapshot_diff(dpg_list);
+ return FILE_SUCCESS;
+}
+
+static void dtop_set_niceness(int niceness)
+{
+ int pid, rc;
+ pid = getpid();
+ printf("Requesting nice %d\n", niceness);
+ rc = setpriority(PRIO_PROCESS, pid, niceness);
+ if (rc != 0)
+ fprintf(stderr, "Error setting priority [%d]\n", errno);
+
+ rc = getpriority(PRIO_PROCESS, pid);
+ printf("Running with nice %d.\n", rc);
+}
+
+int main(int argc, char **argv)
+{
+ int parse_status;
+ printf("DataTop - Version %s\n", VERSION);
+ printf("(c)2014-2015 Linux Foundation\n");
+
+ dtop_load_default_options(&usr_cl_opts);
+
+ parse_status = dtop_parse_cli_opts(&usr_cl_opts, argc, argv);
+ switch (parse_status) {
+ case PARSE_SUCCESS:
+ dtop_set_niceness(usr_cl_opts.priority);
+ break;
+
+ case PARSE_FORCE_EXIT:
+ exit(EXIT_SUCCESS);
+ break;
+
+ case PARSE_FAILURE:
+ default:
+ printf("Failed to parse command line arguments.\n");
+ exit(EXIT_FAILURE);
+ break;
+ }
+
+ dtop_dual_line_init("/proc/net/netstat");
+ dtop_dual_line_init("/proc/net/snmp");
+ dtop_single_line_init("/proc/net/snmp6");
+ dtop_gen_init("/proc/sys/net/");
+ dtop_gen_init("/sys/module/rmnet_data/parameters/");
+ dtop_gen_init("/sys/class/net/rmnet_mhi0/statistics/");
+ dtop_gen_init("/sys/class/net/usb_rmnet0/statistics/");
+ dtop_gen_init("/sys/class/net/rmnet_ipa0/statistics/");
+ dtop_meminfo_init();
+ dtop_dev_init();
+ dtop_stat_init();
+ dtop_cpu_stats_init();
+ dtop_gen_init("/sys/kernel/debug/clk/bimc_clk/");
+ dtop_gen_init("/sys/kernel/debug/clk/snoc_clk/");
+ dtop_gen_init("/sys/kernel/debug/clk/pnoc_clk/");
+
+ if (usr_cl_opts.print_cl == OPT_CHOSE) {
+ dtop_poll(first_dpg_list);
+ dtop_print_terminal(first_dpg_list);
+ }
+
+ if (usr_cl_opts.print_csv == OPT_CHOSE) {
+ FILE *to_file = NULL;
+ if ((dtop_open_writing_file(usr_cl_opts.file_name,
+ &to_file)) == VALID) {
+ printf("\nData being polled for %ld seconds.\n",
+ usr_cl_opts.poll_time);
+ if (dtop_poll_periodically(first_dpg_list, to_file)
+ == FILE_ERROR) {
+ fprintf(stderr, "err=%d: %s\n", errno,
+ strerror(errno));
+ dtop_close_file(to_file);
+ deconstruct_dpgs(first_dpg_list);
+ dtop_rem_linked_list(first_dpg_list);
+ exit(EXIT_FAILURE);
+ }
+ dtop_close_file(to_file);
+ } else {
+ printf("File Can Not Be Opened\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (usr_cl_opts.snapshot_file) {
+ if (dtop_print_system_snapshot(usr_cl_opts.snapshot_file)
+ == FILE_ERROR) {
+ fprintf(stderr, "err=%d: %s\n", errno,
+ strerror(errno));
+ deconstruct_dpgs(first_dpg_list);
+ dtop_rem_linked_list(first_dpg_list);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (usr_cl_opts.print_cl == OPT_NOT_CHOSE &&
+ usr_cl_opts.print_csv == OPT_NOT_CHOSE) {
+ if ((!usr_cl_opts.snapshot_file)
+ || usr_cl_opts.poll_time_selected == POLL_TIME_SELECTED) {
+ printf("\nData will now be polled for %ld seconds.\n",
+ usr_cl_opts.poll_time);
+ dtop_poll(first_dpg_list);
+ sleep(usr_cl_opts.poll_time);
+ dtop_poll(first_dpg_list);
+ dtop_print_snapshot_diff(first_dpg_list);
+ }
+ }
+
+ deconstruct_dpgs(first_dpg_list);
+ dtop_rem_linked_list(first_dpg_list);
+ return 0;
+}
+
+/**
+ * @brief Adds each dpg as a node to a linked list.
+ *
+ * Called when a dpg is initialized.
+ *
+ * @param dpg A pointer to a data_point_gatherer struct which is to be added to the linked list.
+ */
+void dtop_register(struct dtop_data_point_gatherer *dpg)
+{
+ if (dpg)
+ first_dpg_list = dtop_add_linked_list(dpg, first_dpg_list);
+}