summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-11-02 17:39:57 +0900
committerMike Blumenkrantz <zmike@osg.samsung.com>2016-11-18 11:42:38 -0500
commita27a03a9892142452766077cae77072662054952 (patch)
tree230ad084c34e97337c2ff2e8cc0164c6184e8b3d
parentad1b8f224f3dd189d6129da9c43c13a6810949c6 (diff)
cpufreq - move cpuinfo polling into thread to not block mainloop ever
on some devices asking the cpu for info like current frequency, governors etc. seems to be expensive and if done in the mainloop can block for multiple ms causing framerate hiccups, so move it to a thread...
-rw-r--r--src/modules/cpufreq/e_mod_main.c147
-rw-r--r--src/modules/cpufreq/e_mod_main.h4
2 files changed, 96 insertions, 55 deletions
diff --git a/src/modules/cpufreq/e_mod_main.c b/src/modules/cpufreq/e_mod_main.c
index 0d9d8f79a..dfc42c7b6 100644
--- a/src/modules/cpufreq/e_mod_main.c
+++ b/src/modules/cpufreq/e_mod_main.c
@@ -39,7 +39,6 @@ struct _Instance
39static void _button_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info); 39static void _button_cb_mouse_down(void *data, Evas *e, Evas_Object *obj, void *event_info);
40static void _menu_cb_post(void *data, E_Menu *m); 40static void _menu_cb_post(void *data, E_Menu *m);
41static void _cpufreq_set_frequency(int frequency); 41static void _cpufreq_set_frequency(int frequency);
42static Eina_Bool _cpufreq_cb_check(void *data);
43static Cpu_Status *_cpufreq_status_new(void); 42static Cpu_Status *_cpufreq_status_new(void);
44static void _cpufreq_status_free(Cpu_Status *s); 43static void _cpufreq_status_free(Cpu_Status *s);
45static void _cpufreq_status_check_available(Cpu_Status *s); 44static void _cpufreq_status_check_available(Cpu_Status *s);
@@ -97,9 +96,6 @@ _gc_init(E_Gadcon *gc, const char *name, const char *id, const char *style)
97 _button_cb_mouse_down, inst); 96 _button_cb_mouse_down, inst);
98 cpufreq_config->instances = 97 cpufreq_config->instances =
99 eina_list_append(cpufreq_config->instances, inst); 98 eina_list_append(cpufreq_config->instances, inst);
100 if (cpufreq_config->status) _cpufreq_status_free(cpufreq_config->status);
101 cpufreq_config->status = _cpufreq_status_new();
102 _cpufreq_cb_check(NULL);
103 _cpufreq_face_update_available(inst); 99 _cpufreq_face_update_available(inst);
104 100
105 cpufreq_config->handler = 101 cpufreq_config->handler =
@@ -591,45 +587,6 @@ _cpufreq_set_pstate(int min, int max)
591 } 587 }
592} 588}
593 589
594static Eina_Bool
595_cpufreq_cb_check(void *data EINA_UNUSED)
596{
597 Instance *inst;
598 Eina_List *l;
599 int active;
600 static Eina_Bool init_set = EINA_FALSE;
601
602 if (cpufreq_config->menu_poll) return ECORE_CALLBACK_RENEW;
603 active = cpufreq_config->status->active;
604 if (_cpufreq_status_check_current(cpufreq_config->status))
605 {
606 for (l = cpufreq_config->instances; l; l = l->next)
607 {
608 inst = l->data;
609 _cpufreq_face_update_current(inst);
610 }
611 }
612 if (active != cpufreq_config->status->active)
613 {
614 for (l = cpufreq_config->instances; l; l = l->next)
615 {
616 inst = l->data;
617 if (cpufreq_config->status->active == 0)
618 edje_object_signal_emit(inst->o_cpu, "e,state,disabled", "e");
619 else if (cpufreq_config->status->active == 1)
620 edje_object_signal_emit(inst->o_cpu, "e,state,enabled", "e");
621 }
622 }
623 if (!init_set)
624 {
625 _cpufreq_set_pstate(cpufreq_config->pstate_min - 1,
626 cpufreq_config->pstate_max - 1);
627 init_set = 1;
628 }
629
630 return ECORE_CALLBACK_RENEW;
631}
632
633static Cpu_Status * 590static Cpu_Status *
634_cpufreq_status_new(void) 591_cpufreq_status_new(void)
635{ 592{
@@ -1306,14 +1263,95 @@ _cpufreq_menu_pstate_max(void *data, E_Menu *m EINA_UNUSED, E_Menu_Item *mi EINA
1306 e_config_save_queue(); 1263 e_config_save_queue();
1307} 1264}
1308 1265
1266typedef struct _Thread_Config Thread_Config;
1267
1268struct _Thread_Config
1269{
1270 int interval;
1271};
1272
1273static void
1274_cpufreq_cb_frequency_check_main(void *data, Ecore_Thread *th)
1275{
1276 Thread_Config *thc = data;
1277 for (;;)
1278 {
1279 Cpu_Status *status;
1280
1281 if (ecore_thread_check(th)) break;
1282 status = _cpufreq_status_new();
1283 if (_cpufreq_status_check_current(status))
1284 ecore_thread_feedback(th, status);
1285 else
1286 _cpufreq_status_free(status);
1287 if (ecore_thread_check(th)) break;
1288 usleep((1000000.0 / 8.0) * (double)thc->interval);
1289 }
1290 free(thc);
1291}
1292
1293static void
1294_cpufreq_cb_frequency_check_notify(void *data EINA_UNUSED,
1295 Ecore_Thread *th EINA_UNUSED,
1296 void *msg)
1297{
1298 Cpu_Status *status = msg;
1299 Instance *inst;
1300 Eina_List *l;
1301 int active;
1302 static Eina_Bool init_set = EINA_FALSE;
1303
1304 if (!cpufreq_config)
1305 {
1306 _cpufreq_status_free(status);
1307 return;
1308 }
1309 if (cpufreq_config->status) _cpufreq_status_free(cpufreq_config->status);
1310 active = cpufreq_config->status->active;
1311 cpufreq_config->status = status;
1312 for (l = cpufreq_config->instances; l; l = l->next)
1313 {
1314 inst = l->data;
1315 _cpufreq_face_update_current(inst);
1316 }
1317 if (active != cpufreq_config->status->active)
1318 {
1319 for (l = cpufreq_config->instances; l; l = l->next)
1320 {
1321 inst = l->data;
1322 if (cpufreq_config->status->active == 0)
1323 edje_object_signal_emit(inst->o_cpu, "e,state,disabled", "e");
1324 else if (cpufreq_config->status->active == 1)
1325 edje_object_signal_emit(inst->o_cpu, "e,state,enabled", "e");
1326 }
1327 }
1328 if (!init_set)
1329 {
1330 _cpufreq_set_pstate(cpufreq_config->pstate_min - 1,
1331 cpufreq_config->pstate_max - 1);
1332 init_set = EINA_TRUE;
1333 }
1334}
1335
1309void 1336void
1310_cpufreq_poll_interval_update(void) 1337_cpufreq_poll_interval_update(void)
1311{ 1338{
1312 if (cpufreq_config->frequency_check_poller) 1339 Thread_Config *thc;
1313 ecore_poller_del(cpufreq_config->frequency_check_poller); 1340
1314 cpufreq_config->frequency_check_poller = 1341 if (cpufreq_config->frequency_check_thread)
1315 ecore_poller_add(ECORE_POLLER_CORE, cpufreq_config->poll_interval, 1342 {
1316 _cpufreq_cb_check, NULL); 1343 ecore_thread_cancel(cpufreq_config->frequency_check_thread);
1344 cpufreq_config->frequency_check_thread = NULL;
1345 }
1346 thc = malloc(sizeof(Thread_Config));
1347 if (thc)
1348 {
1349 thc->interval = cpufreq_config->poll_interval;
1350 cpufreq_config->frequency_check_thread =
1351 ecore_thread_feedback_run(_cpufreq_cb_frequency_check_main,
1352 _cpufreq_cb_frequency_check_notify,
1353 NULL, NULL, thc, EINA_TRUE);
1354 }
1317 e_config_save_queue(); 1355 e_config_save_queue();
1318} 1356}
1319 1357
@@ -1392,13 +1430,11 @@ e_modapi_init(E_Module *m)
1392 "sudo chmod u+s,a+x %s<br>"), 1430 "sudo chmod u+s,a+x %s<br>"),
1393 buf, buf); 1431 buf, buf);
1394 } 1432 }
1395
1396 cpufreq_config->frequency_check_poller =
1397 ecore_poller_add(ECORE_POLLER_CORE, cpufreq_config->poll_interval,
1398 _cpufreq_cb_check, NULL);
1399 cpufreq_config->status = _cpufreq_status_new(); 1433 cpufreq_config->status = _cpufreq_status_new();
1400 1434
1401 _cpufreq_status_check_available(cpufreq_config->status); 1435 _cpufreq_status_check_available(cpufreq_config->status);
1436 _cpufreq_poll_interval_update();
1437
1402 if ((cpufreq_config->restore_governor) && (cpufreq_config->governor)) 1438 if ((cpufreq_config->restore_governor) && (cpufreq_config->governor))
1403 { 1439 {
1404 /* If the governor is available, restore it */ 1440 /* If the governor is available, restore it */
@@ -1432,8 +1468,11 @@ e_modapi_shutdown(E_Module *m EINA_UNUSED)
1432 1468
1433 e_gadcon_provider_unregister(&_gadcon_class); 1469 e_gadcon_provider_unregister(&_gadcon_class);
1434 1470
1435 if (cpufreq_config->frequency_check_poller) 1471 if (cpufreq_config->frequency_check_thread)
1436 ecore_poller_del(cpufreq_config->frequency_check_poller); 1472 {
1473 ecore_thread_cancel(cpufreq_config->frequency_check_thread);
1474 cpufreq_config->frequency_check_thread = NULL;
1475 }
1437 if (cpufreq_config->menu) 1476 if (cpufreq_config->menu)
1438 { 1477 {
1439 e_menu_post_deactivate_callback_set(cpufreq_config->menu, NULL, NULL); 1478 e_menu_post_deactivate_callback_set(cpufreq_config->menu, NULL, NULL);
diff --git a/src/modules/cpufreq/e_mod_main.h b/src/modules/cpufreq/e_mod_main.h
index b4b7717a3..453cf5e0f 100644
--- a/src/modules/cpufreq/e_mod_main.h
+++ b/src/modules/cpufreq/e_mod_main.h
@@ -49,7 +49,7 @@ struct _Config
49 E_Menu *menu_pstate2; 49 E_Menu *menu_pstate2;
50 Cpu_Status *status; 50 Cpu_Status *status;
51 char *set_exe_path; 51 char *set_exe_path;
52 Ecore_Poller *frequency_check_poller; 52 Ecore_Thread *frequency_check_thread;
53 Ecore_Event_Handler *handler; 53 Ecore_Event_Handler *handler;
54 E_Config_Dialog *config_dialog; 54 E_Config_Dialog *config_dialog;
55}; 55};
@@ -67,6 +67,8 @@ void _cpufreq_set_pstate(int min, int max);
67 67
68extern Config *cpufreq_config; 68extern Config *cpufreq_config;
69 69
70
71
70/** 72/**
71 * @addtogroup Optional_Gadgets 73 * @addtogroup Optional_Gadgets
72 * @{ 74 * @{