This commit is contained in:
Alastair Poole 2018-06-10 14:09:44 +01:00
parent e29464aee8
commit 08e57b1f95
4 changed files with 450 additions and 54 deletions

View File

@ -66,10 +66,9 @@
# include <vm/vm_param.h>
#endif
#define CPU_STATES 5
#include "system.h"
#define MAX_BATTERIES 5
#define INVALID_TEMP -999
#define CPU_STATES 5
/* Filter requests and results */
#define RESULTS_CPU 0x01
@ -83,54 +82,6 @@
#define RESULTS_MEM_GB 0x80
#define RESULTS_CPU_CORES 0x100
typedef struct
{
float percent;
unsigned long total;
unsigned long idle;
} cpu_core_t;
typedef struct
{
unsigned long total;
unsigned long used;
unsigned long cached;
unsigned long buffered;
unsigned long shared;
unsigned long swap_total;
unsigned long swap_used;
} meminfo_t;
typedef struct
{
bool have_ac;
int battery_count;
double charge_full;
double charge_current;
uint8_t percent;
char battery_names[256];
int *bat_mibs[MAX_BATTERIES];
int ac_mibs[5];
} power_t;
typedef struct results_t results_t;
struct results_t
{
int cpu_count;
cpu_core_t **cores;
meminfo_t memory;
power_t power;
unsigned long incoming;
unsigned long outgoing;
int temperature;
};
static void
_memsize_bytes_to_kb(unsigned long *bytes)
{
@ -1157,6 +1108,49 @@ _results_cpu(cpu_core_t **cores, int cpu_count)
return total;
}
int
system_temperature_cpu_get(void)
{
int temp;
_temperature_cpu_get(&temp);
return temp;
}
void
system_power_state_get(power_t *power)
{
_power_state_get(power);
}
bool
system_network_transfer_get(unsigned long *incoming, unsigned long *outgoing)
{
unsigned long first_in = 0, first_out = 0;
unsigned long last_in = 0, last_out = 0;
#if defined(__linux__)
_linux_generic_network_status(&first_in, &first_out);
usleep(1000000);
_linux_generic_network_status(&last_in, &last_out);
#elif defined(__OpenBSD__)
_openbsd_generic_network_status(&first_in, &first_out);
usleep(1000000);
_openbsd_generic_network_status(&last_in, &last_out);
#elif defined(__MacOS__) || defined(__FreeBSD__) || defined(__DragonFly__)
_freebsd_generic_network_status(&first_in, &first_out);
usleep(1000000);
_freebsd_generic_network_status(&last_in, &last_out);
#else
return false;
#endif
*incoming = last_in - first_in;
*outgoing = last_out - first_out;
return true;
}
int
system_cpu_memory_get(double *percent_cpu, long *memory_total, long *memory_used)
{
@ -1182,3 +1176,39 @@ system_cpu_memory_get(double *percent_cpu, long *memory_total, long *memory_used
return results.cpu_count;
}
static void *_network_transfer_get_thread_cb(void *arg)
{
results_t *results = arg;
_network_transfer_get(results);
return ((void *) 0);
}
void
system_stats_all_get(results_t *results)
{
void *ret;
pthread_t tid;
int error;
memset(results, 0, sizeof(results_t));
results->cores = _cpu_cores_state_get(&results->cpu_count);
error = pthread_create(&tid, NULL, _network_transfer_get_thread_cb, results);
if (error)
_network_transfer_get(results);
_power_state_get(&results->power);
_temperature_cpu_get(&results->temperature);
if (!error)
{
ret = NULL;
pthread_join(tid, ret);
}
}

View File

@ -1,7 +1,70 @@
#ifndef __SYSTEM_H__
#define __SYSTEM_H__
#include <stdint.h>
#include <stdbool.h>
typedef struct
{
float percent;
unsigned long total;
unsigned long idle;
} cpu_core_t;
typedef struct
{
unsigned long total;
unsigned long used;
unsigned long cached;
unsigned long buffered;
unsigned long shared;
unsigned long swap_total;
unsigned long swap_used;
} meminfo_t;
typedef struct
{
bool have_ac;
int battery_count;
double charge_full;
double charge_current;
uint8_t percent;
#define MAX_BATTERIES 5
char battery_names[256];
int *bat_mibs[MAX_BATTERIES];
int ac_mibs[5];
} power_t;
typedef struct results_t results_t;
struct results_t
{
int cpu_count;
cpu_core_t **cores;
meminfo_t memory;
power_t power;
unsigned long incoming;
unsigned long outgoing;
#define INVALID_TEMP -999
int temperature;
};
void
system_stats_all_get(results_t *results);
int
system_cpu_memory_get(double *percent_cpu, long *memory_total, long *memory_used);
bool
system_network_transfer_get(unsigned long *incoming, unsigned long *outgoing);
int
system_temperature_cpu_get(void);
void
system_power_state_get(power_t *power);
#endif

303
src/ui.c
View File

@ -12,10 +12,12 @@
static Eina_Lock _lock;
static results_t *_results = NULL;
static long _memory_total = 0;
static long _memory_used = 0;
static void _disk_view_update(Ui *ui);
static void _extra_view_update(Ui *ui, results_t *results);
static void
_system_stats(void *data, Ecore_Thread *thread)
@ -61,12 +63,59 @@ _system_stats_feedback_cb(void *data, Ecore_Thread *thread, void *msg)
elm_progressbar_value_set(ui->progress_cpu, (double)sys->cpu_usage / 100);
elm_progressbar_value_set(ui->progress_mem, (double)((sys->mem_total / 100.0) * sys->mem_used) / 1000000);
_disk_view_update(ui);
if (time(NULL) % 2)
_disk_view_update(ui);
out:
free(sys);
}
static void
_extra_stats(void *data, Ecore_Thread *thread)
{
Ui *ui;
int i;
ui = data;
while (1)
{
results_t *results = malloc(sizeof(results_t));
system_stats_all_get(results);
ecore_thread_feedback(thread, results);
for (i = 0; i < ui->poll_delay * 2; i++)
{
if (ecore_thread_check(thread))
return;
usleep(500000);
}
}
}
static void
_extra_stats_feedback_cb(void *data, Ecore_Thread *thread, void *msg)
{
Ui *ui;
results_t *results;
int i;
ui = data;
results = msg;
_extra_view_update(ui, results);
for (i = 0; i < results->cpu_count; i++)
{
free(results->cores[i]);
}
free(results->cores);
free(results);
}
static int
_sort_by_pid(const void *p1, const void *p2)
{
@ -790,7 +839,6 @@ _entry_pid_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info
ui->panel_visible = EINA_TRUE;
}
static unsigned long _disk_used = 0, _disk_total = 0;
static char *
@ -854,6 +902,9 @@ _disk_view_update(Ui *ui)
char *path;
unsigned long total, used;
if (!ui->disk_visible)
return;
elm_box_clear(ui->disk_activity);
disks = disks_get();
@ -876,6 +927,182 @@ _disk_view_update(Ui *ui)
free(disks);
}
static char *
_progress_incoming_format_cb(double val)
{
char buf[1024];
double incoming;
const char *unit = "B/s";
incoming = _results->incoming;
if (incoming > 1048576)
{
incoming /= 1048576;
unit = "MB/s";
}
else if (incoming > 1024 && incoming < 1048576)
{
incoming /= 1024;
unit = "KB/s";
}
snprintf(buf, sizeof(buf), "%.2f %s", incoming, unit);
return strdup(buf);
}
static void
_progress_incoming_format_free_cb(char *str)
{
if (str)
free(str);
}
static char *
_progress_outgoing_format_cb(double val)
{
char buf[1024];
double outgoing;
const char *unit = "B/s";
outgoing = _results->outgoing;
if (outgoing > 1048576)
{
outgoing /= 1048576;
unit = "MB/s";
}
else if (outgoing > 1024 && outgoing < 1048576)
{
outgoing /= 1024;
unit = "KB/s";
}
snprintf(buf, sizeof(buf), "%.2f %s", outgoing, unit);
return strdup(buf);
}
static void
_progress_outgoing_format_free_cb(char *str)
{
if (str)
free(str);
}
static void
_extra_view_update(Ui *ui, results_t *results)
{
Evas_Object *box, *frame, *progress;
int i;
if (!ui->extra_visible)
return;
_results = results;
elm_box_clear(ui->extra_activity);
box = elm_box_add(ui->disk_activity);
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(box);
for (i = 0; i < results->cpu_count; i++)
{
frame = elm_frame_add(box);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
if (i == 0 && results->temperature != INVALID_TEMP)
elm_object_text_set(frame, eina_slstr_printf("CPU %d (%dC)", i, results->temperature));
else
elm_object_text_set(frame, eina_slstr_printf("CPU %d", i));
evas_object_show(frame);
progress = elm_progressbar_add(frame);
evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_progressbar_span_size_set(progress, 1.0);
elm_progressbar_unit_format_set(progress, "%1.2f%%");
elm_progressbar_value_set(progress, results->cores[i]->percent / 100);
evas_object_show(progress);
elm_object_content_set(frame, progress);
elm_box_pack_end(box, frame);
}
if (results->power.battery_count)
{
frame = elm_frame_add(box);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
if (results->power.have_ac)
elm_object_text_set(frame, "Battery (plugged in)");
else
elm_object_text_set(frame, "Battery");
evas_object_show(frame);
progress = elm_progressbar_add(frame);
evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_progressbar_span_size_set(progress, 1.0);
elm_progressbar_unit_format_set(progress, "%1.2f%%");
elm_progressbar_value_set(progress, results->power.percent / 100);
evas_object_show(progress);
elm_object_content_set(frame, progress);
elm_box_pack_end(box, frame);
}
frame = elm_frame_add(box);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_text_set(frame, "Network Incoming");
evas_object_show(frame);
progress = elm_progressbar_add(frame);
evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_progressbar_span_size_set(progress, 1.0);
elm_progressbar_unit_format_set(progress, "");
elm_progressbar_unit_format_function_set(progress, _progress_incoming_format_cb, _progress_incoming_format_free_cb);
if (results->incoming == 0)
elm_progressbar_value_set(progress, 0);
else
elm_progressbar_value_set(progress, 1.0);
evas_object_show(progress);
elm_object_content_set(frame, progress);
elm_box_pack_end(box, frame);
frame = elm_frame_add(box);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, 0);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_text_set(frame, "Network Outgoing");
evas_object_show(frame);
progress = elm_progressbar_add(frame);
evas_object_size_hint_align_set(progress, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(progress, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_progressbar_span_size_set(progress, 1.0);
elm_progressbar_unit_format_set(progress, "");
elm_progressbar_unit_format_function_set(progress, _progress_outgoing_format_cb, _progress_outgoing_format_free_cb);
if (results->outgoing == 0)
elm_progressbar_value_set(progress, 0);
else
elm_progressbar_value_set(progress, 1.0);
evas_object_show(progress);
elm_object_content_set(frame, progress);
elm_box_pack_end(box, frame);
elm_box_pack_end(ui->extra_activity, box);
}
static void
_ui_system_view_add(Ui *ui)
{
@ -1482,6 +1709,42 @@ _ui_disk_view_add(Ui *ui)
elm_box_pack_end(box, frame);
}
static void
_ui_extra_view_add(Ui *ui)
{
Evas_Object *parent, *box, *hbox, *frame, *scroller;
parent = ui->content;
ui->extra_view = box = elm_box_add(parent);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_table_pack(ui->content, ui->extra_view, 0, 1, 1, 1);
evas_object_hide(box);
ui->extra_activity = hbox = elm_box_add(box);
evas_object_size_hint_weight_set(hbox, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(hbox, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(hbox);
frame = elm_frame_add(box);
evas_object_size_hint_weight_set(frame, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(frame, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(frame, "Misc");
evas_object_show(frame);
scroller = elm_scroller_add(parent);
evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_OFF, ELM_SCROLLER_POLICY_ON);
evas_object_show(scroller);
elm_object_content_set(scroller, hbox);
elm_object_content_set(frame, scroller);
elm_box_pack_end(box, frame);
}
static void
_tab_system_activity_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@ -1489,9 +1752,13 @@ _tab_system_activity_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *
ui = data;
ui->extra_visible = EINA_FALSE;
ui->disk_visible = EINA_FALSE;
evas_object_show(ui->system_activity);
evas_object_show(ui->panel);
evas_object_hide(ui->disk_view);
evas_object_hide(ui->extra_view);
}
static void
@ -1500,9 +1767,30 @@ _tab_disk_activity_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *ev
Ui *ui;
ui = data;
ui->extra_visible = EINA_FALSE;
ui->disk_visible = EINA_TRUE;
evas_object_show(ui->disk_view);
evas_object_hide(ui->system_activity);
evas_object_hide(ui->panel);
evas_object_hide(ui->extra_view);
}
static void
_tab_extra_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Ui *ui;
ui = data;
ui->extra_visible = EINA_TRUE;
ui->disk_visible = EINA_FALSE;
evas_object_show(ui->extra_view);
evas_object_hide(ui->system_activity);
evas_object_hide(ui->panel);
evas_object_hide(ui->disk_view);
}
static Evas_Object *
@ -1545,6 +1833,14 @@ _ui_tabs_add(Evas_Object *parent, Ui *ui)
elm_box_pack_end(hbox, button);
evas_object_smart_callback_add(button, "clicked", _tab_disk_activity_clicked_cb, ui);
button = elm_button_add(hbox);
evas_object_size_hint_weight_set(button, 1.0, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(button, "Misc");
evas_object_show(button);
elm_box_pack_end(hbox, button);
evas_object_smart_callback_add(button, "clicked", _tab_extra_clicked_cb, ui);
elm_object_content_set(frame, hbox);
elm_table_pack(ui->content, frame, 0, 0, 1, 1);
@ -1589,6 +1885,7 @@ ui_add(Evas_Object *parent)
ui->selected_pid = -1;
ui->program_pid = getpid();
ui->panel_visible = EINA_TRUE;
ui->disk_visible = ui->extra_visible = EINA_TRUE;
memset(ui->cpu_times, 0, PID_MAX * sizeof(int64_t));
@ -1607,12 +1904,14 @@ ui_add(Evas_Object *parent)
_ui_system_view_add(ui);
_ui_process_panel_add(ui);
_ui_disk_view_add(ui);
_ui_extra_view_add(ui);
/* Start polling the data */
_disk_view_update(ui);
_process_panel_update(ui);
ecore_thread_feedback_run(_system_stats, _system_stats_feedback_cb, _thread_end_cb, _thread_error_cb, ui, EINA_FALSE);
ecore_thread_feedback_run(_extra_stats, _extra_stats_feedback_cb, _thread_end_cb, _thread_error_cb, ui, EINA_FALSE);
ecore_thread_feedback_run(_system_process_list, _system_process_list_feedback_cb, _thread_end_cb, _thread_error_cb, ui, EINA_FALSE);
}

View File

@ -50,9 +50,13 @@ typedef struct Ui
Evas_Object *disk_view;
Evas_Object *disk_activity;
Evas_Object *extra_view;
Evas_Object *extra_activity;
Evas_Object *system_activity;
Eina_Bool extra_visible;
Eina_Bool disk_visible;
Evas_Object *progress_cpu;
Evas_Object *progress_mem;