- CPU utilization, as some tools like pcup may not be actively maintained or may not be accurate on modern systems.
- The top, mpstat, sar, and htop commands are commonly used to monitor CPU usage on Linux systems.
- So I have updated to check again the /proc/stat periodically after new timer creation considering performance
Change-Id: If76612dec2ed201abe617bbf4c7fd192a979f2f0
Name: mused
Summary: A multimedia daemon
-Version: 0.3.161
+Version: 0.3.162
Release: 0
Group: System/Libraries
License: Apache-2.0
#define MS_DBUS_INTERFACE "org.freedesktop.DBus"
#define MS_DBUS_PATH "/org/freedesktop/DBus"
+typedef struct ms_cpu_jiffies {
+ unsigned long long user;
+ unsigned long long nice;
+ unsigned long long system;
+ unsigned long long idle;
+ guint id;
+ int counter;
+ int usage;
+} ms_cpu_jiffies_t;
+
typedef struct ms_system {
GDBusConnection *connection;
GHashTable *platform_info_table;
GMutex lock;
int muse_poweroff_id;
int muse_rm_id;
+ ms_cpu_jiffies_t st;
} ms_system_t;
void ms_system_init(ms_system_t *system);
+void ms_system_stat_attach(ms_system_t *system);
+void ms_system_stat_detach(ms_system_t *system);
void ms_system_deinit(ms_system_t *system);
gboolean ms_system_get_gdbus(GDBusConnection **connection);
void ms_system_subscribe_external_event(ms_system_t *system);
static void _ms_wait_event(void);
static void _ms_diag_init(void);
static void _ms_diag_deinit(void);
-static gboolean _ms_idle_cb(gpointer user_data);
+static gboolean _ms_idle_cb(gpointer data);
static int _ms_open_lockfile(void);
static void _ms_wait_event(void)
muse_module_h candidate_m = NULL;
intptr_t module_addr = 0;
GQueue *instance_queue = NULL;
+ ms_system_t *system = NULL;
ms_connection_t *connection = NULL;
char time_buf[MUSE_MSG_TIME_LEN];
muse_return_val_if_fail(muse_server, FALSE);
+ system = muse_server->system;
+ muse_return_val_if_fail(system, FALSE);
+
+ ms_system_stat_detach(system);
+
connection = muse_server->connection;
muse_return_val_if_fail(connection, FALSE);
d->msg_aq = NULL;
}
-static gboolean _ms_idle_cb(gpointer user_data)
+static gboolean _ms_idle_cb(gpointer data)
{
struct timespec tv;
char time_buf[MUSE_MSG_TIME_LEN];
int used_pss, memory_threshold, cpu_usage, cpu_threshold;
char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
ms_connection_t *connection = NULL;
+ ms_system_t *system = NULL;
muse_return_if_fail(muse_server);
connection = muse_server->connection;
muse_return_if_fail(connection);
+ system = muse_server->system;
+ muse_return_if_fail(system);
+
ms_connection_lock(connection);
if (g_queue_is_empty(connection->instance_q) && ms_is_server_ready()) {
memory_threshold = ms_config_get_memory_threshold();
cpu_threshold = ms_config_get_cpu_threshold();
- if (used_pss >= memory_threshold || cpu_usage >= cpu_threshold) {
+ if (used_pss >= memory_threshold) {
ms_log_process_info(muse_server->pid);
- snprintf(err_msg, sizeof(err_msg), "[Memory Leak] %d >= %d (KByte) [CPU] %d >= %d %%",
- used_pss, memory_threshold, cpu_usage, cpu_threshold);
+ snprintf(err_msg, sizeof(err_msg), "[Memory Leak] %d >= %d (KByte)", used_pss, memory_threshold);
LOGE("%s", err_msg);
ms_connection_unlock(connection);
ms_terminate(SIGTERM);
}
+ if (cpu_usage > cpu_threshold)
+ ms_system_stat_attach(system);
+
muse_core_remove_all_fd_table();
} else {
LOGI("skip cpu memory check due to instance queue length : %d", g_queue_get_length(connection->instance_q));
#define MUSE_STORAGE_EXTERNAL_FEATURE "http://tizen.org/feature/storage.external"
+#define MUSE_STAT_CHECK_COUNT 3
+#define MUSE_STAT_TIMER_PERIOD 1
+
enum muse_poweroff_type {
MUSE_POWER_OFF_NONE = 0,
MUSE_POWER_OFF_POPUP,
const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data);
#endif
+static void _ms_system_stat_reset_cb(gpointer user_data);
+static gboolean _ms_system_cpu_usage_cb(gpointer user_data);
+
#ifdef MUSE_USE_POWER_OFF_STATE_CHANGE
static int _ms_system_subscribe_poweroff_state_change(ms_system_t *system)
{
}
#endif
+static void _ms_system_stat_reset_cb(gpointer user_data)
+{
+ ms_system_t *system = (ms_system_t *)user_data;
+
+ muse_return_if_fail(system);
+
+ LOGI("memset stat id %u", system->st.id);
+ memset(&system->st, 0, sizeof(ms_cpu_jiffies_t));
+}
+
+static gboolean _ms_system_cpu_usage_cb(gpointer user_data)
+{
+ FILE *fp;
+ char buf[MUSE_MSG_LEN_MAX];
+ char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
+ unsigned long long u, n, s, i;
+ ms_system_t *system = (ms_system_t *)user_data;
+ int cpu_threshold = ms_config_get_cpu_threshold();
+
+ fp = fopen("/proc/stat", "r");
+ if (!fp)
+ return G_SOURCE_REMOVE;
+ fgets(buf, sizeof(buf), fp);
+ fclose(fp);
+
+ sscanf(buf, "cpu %llu %llu %llu %llu", &u, &n, &s, &i);
+
+ u -= system->st.user;
+ n -= system->st.nice;
+ s -= system->st.system;
+ i -= system->st.idle;
+
+ system->st.user += u;
+ system->st.nice += n;
+ system->st.system += s;
+ system->st.idle += i;
+
+ system->st.usage = (int)100 * (u + n + s) / (u + n + s + i);
+ LOGD("[#%d] cpu usage %d %%", system->st.counter, system->st.usage);
+
+ if (system->st.usage < cpu_threshold)
+ return G_SOURCE_REMOVE;
+
+ system->st.counter++;
+
+ if (system->st.counter >= MUSE_STAT_CHECK_COUNT) {
+ ms_log_process_info(ms_get_instance()->pid);
+
+ snprintf(err_msg, sizeof(err_msg), "[CPU BUSY] %d >= %d %%", system->st.usage, cpu_threshold);
+
+ LOGE("%s", err_msg);
+ ms_terminate(SIGTERM);
+ return G_SOURCE_REMOVE;
+ }
+
+ return G_SOURCE_CONTINUE;
+}
+
void ms_system_init(ms_system_t *system)
{
GError *error = NULL;
LOGD("Leave");
}
+void ms_system_stat_attach(ms_system_t *system)
+{
+ muse_return_if_fail(system);
+ muse_return_if_fail(system->st.id == 0);
+
+ system->st.id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT,
+ MUSE_STAT_TIMER_PERIOD,
+ _ms_system_cpu_usage_cb,
+ (gpointer)system,
+ _ms_system_stat_reset_cb);
+
+ LOGI("add stat id %u", system->st.id);
+}
+
+void ms_system_stat_detach(ms_system_t *system)
+{
+ muse_return_if_fail(system);
+
+ LOGI("remove stat id %u", system->st.id);
+
+ if (system->st.id == 0)
+ return;
+
+ if (!g_source_remove(system->st.id))
+ LOGE("Failed to remove %u", system->st.id);
+}
+
void ms_system_deinit(ms_system_t *system)
{
muse_return_if_fail(system);