summaryrefslogtreecommitdiff
path: root/src/lib/eina
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2018-06-25 15:16:39 -0400
committerMike Blumenkrantz <zmike@samsung.com>2018-06-25 15:17:14 -0400
commitb3b104a1e72d022e5bb7cfa87e6f01b7142ec505 (patch)
treee2a4d3d37342b29d744c02e9eca53dbb644d1a62 /src/lib/eina
parent3562878e2106cf8c578f58b11115a9ed0f94b1fc (diff)
eina/debug_cpu: rework thread usage
Summary: this changes the explicit pthread usage (and reimplementation of eina_thread_create) to just use eina function calls. it also causes the thread to start and stop when profiling is enabled and resolves some possible errors which could occur after a fork or when trying to compile under windows pthread usage: this code appears to have been 100% copied from eina_thread.c, and it isn't clear to me why existing eina_thread api was not used. this has no functional benefit, but it makes the code more readable thread lifetime: there is no need to have a thread running at all times for a feature which will be rarely used and which must be explicitly enabled by the user windows: this file previously generated a lot of compiler warnings from unused functions and variables since nothing here is available under windows. the entire file is now a giant #ifndef _WIN32 to avoid any compile warnings or unexpected runtime behavior fix T7055 Depends on D6371 Reviewers: ManMower, vtorri, devilhorns Reviewed By: ManMower Subscribers: cedric, #committers Tags: #efl Maniphest Tasks: T7055 Differential Revision: https://phab.enlightenment.org/D6372
Diffstat (limited to 'src/lib/eina')
-rw-r--r--src/lib/eina/eina_debug_cpu.c110
1 files changed, 44 insertions, 66 deletions
diff --git a/src/lib/eina/eina_debug_cpu.c b/src/lib/eina/eina_debug_cpu.c
index 2cc382d84b..b4c3cf49c4 100644
--- a/src/lib/eina/eina_debug_cpu.c
+++ b/src/lib/eina/eina_debug_cpu.c
@@ -25,21 +25,15 @@
25#include "eina_evlog.h" 25#include "eina_evlog.h"
26#include "eina_debug_private.h" 26#include "eina_debug_private.h"
27 27
28#ifdef EINA_HAVE_PTHREAD_SETNAME 28#ifndef _WIN32
29# ifndef __linux__
30# include <pthread_np.h>
31# endif
32#endif
33
34volatile int _eina_debug_sysmon_reset = 0; 29volatile int _eina_debug_sysmon_reset = 0;
35volatile int _eina_debug_sysmon_active = 0; 30volatile int _eina_debug_sysmon_active = 0;
36volatile int _eina_debug_evlog_active = 0; 31volatile int _eina_debug_evlog_active = 0;
37volatile int _eina_debug_cpu_active = 0; 32volatile int _eina_debug_cpu_active = 0;
38 33
39Eina_Lock _sysmon_lock; 34Eina_Lock _sysmon_lock;
40static Eina_Condition _exit_cond;
41 35
42static pthread_t _sysmon_thread; 36static Eina_Thread _sysmon_thread;
43 37
44// this is a DEDICATED thread tojust collect system info and to have the 38// this is a DEDICATED thread tojust collect system info and to have the
45// least impact it can on a cpu core or system. all this does right now 39// least impact it can on a cpu core or system. all this does right now
@@ -47,7 +41,7 @@ static pthread_t _sysmon_thread;
47// right now that means iterating through cpu's and getting their cpu 41// right now that means iterating through cpu's and getting their cpu
48// frequency to match up with event logs. 42// frequency to match up with event logs.
49static void * 43static void *
50_sysmon(void *_data EINA_UNUSED) 44_sysmon(void *data EINA_UNUSED, Eina_Thread thr EINA_UNUSED)
51{ 45{
52 static int cpufreqs[64] = { 0 }; 46 static int cpufreqs[64] = { 0 };
53 int i, fd, freq; 47 int i, fd, freq;
@@ -65,14 +59,7 @@ _sysmon(void *_data EINA_UNUSED)
65#endif 59#endif
66 60
67 // set a name for this thread for system debugging 61 // set a name for this thread for system debugging
68#ifdef EINA_HAVE_PTHREAD_SETNAME 62 eina_thread_name_set(eina_thread_self(), "Edbg-sys");
69# ifndef __linux__
70 pthread_set_name_np
71# else
72 pthread_setname_np
73# endif
74 (pthread_self(), "Edbg-sys");
75#endif
76 for (;;) 63 for (;;)
77 { 64 {
78 // wait on a mutex that will be locked for as long as this 65 // wait on a mutex that will be locked for as long as this
@@ -137,7 +124,7 @@ _sysmon(void *_data EINA_UNUSED)
137 } 124 }
138 for (i = 0; i < _eina_debug_thread_active_num; i++) 125 for (i = 0; i < _eina_debug_thread_active_num; i++)
139 { 126 {
140 pthread_t thread = _eina_debug_thread_active[i].thread; 127 Eina_Thread thread = _eina_debug_thread_active[i].thread;
141 // get the clock for the thread and its cpu time usage 128 // get the clock for the thread and its cpu time usage
142 pthread_getcpuclockid(thread, &cid); 129 pthread_getcpuclockid(thread, &cid);
143 clock_gettime(cid, &t); 130 clock_gettime(cid, &t);
@@ -249,7 +236,7 @@ _sysmon(void *_data EINA_UNUSED)
249 } 236 }
250 usleep(1000); // 1ms sleep 237 usleep(1000); // 1ms sleep
251 } 238 }
252 eina_condition_signal(&_exit_cond); 239 _eina_debug_cpu_active = -1;
253 eina_lock_release(&_sysmon_lock); 240 eina_lock_release(&_sysmon_lock);
254 return NULL; 241 return NULL;
255} 242}
@@ -257,30 +244,55 @@ _sysmon(void *_data EINA_UNUSED)
257static Eina_Bool 244static Eina_Bool
258_cpufreq_on_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED) 245_cpufreq_on_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
259{ 246{
247 Eina_Bool err;
260 if (!_eina_debug_evlog_active) 248 if (!_eina_debug_evlog_active)
261 { 249 {
262 _eina_debug_evlog_active = 1; 250 _eina_debug_evlog_active = 1;
263 eina_evlog_start(); 251 eina_evlog_start();
264 } 252 }
265 if (!_eina_debug_sysmon_active) 253 if (_eina_debug_sysmon_active) return EINA_TRUE;
254
255 eina_lock_take(&_sysmon_lock);
256
257 err = eina_thread_create(&_sysmon_thread, EINA_THREAD_NORMAL, -1, _sysmon, NULL);
258
259 if (!err)
266 { 260 {
267 _eina_debug_sysmon_reset = 1; 261 e_debug("EINA DEBUG ERROR: Can't create debug sysmon thread!");
268 _eina_debug_sysmon_active = 1;
269 // this is intended. taking this lock allows sysmon to run
270 eina_lock_release(&_sysmon_lock); 262 eina_lock_release(&_sysmon_lock);
263 return EINA_FALSE;
271 } 264 }
265 _eina_debug_cpu_active = 1;
266 _eina_debug_sysmon_reset = 1;
267 _eina_debug_sysmon_active = 1;
268 eina_lock_release(&_sysmon_lock);
272 return EINA_TRUE; 269 return EINA_TRUE;
273} 270}
274 271
275static Eina_Bool 272static void
276_cpufreq_off_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED) 273_stop_cpu_thread(void)
277{ 274{
278 if (_eina_debug_sysmon_active) 275 extern Eina_Bool fork_resetting;
276 eina_lock_take(&_sysmon_lock);
277 _eina_debug_cpu_active = 0;
278 eina_lock_release(&_sysmon_lock);
279 /* wait for thread to exit */
280 while (!fork_resetting)
279 { 281 {
280 // this is intended. taking this lock blocks sysmod from running 282 usleep(1000);
281 eina_lock_take(&_sysmon_lock); 283 eina_lock_take(&_sysmon_lock);
282 _eina_debug_sysmon_active = 0; 284 if (_eina_debug_cpu_active == -1) break;
285 eina_lock_release(&_sysmon_lock);
283 } 286 }
287 _eina_debug_cpu_active = 0;
288 eina_lock_release(&_sysmon_lock);
289}
290
291static Eina_Bool
292_cpufreq_off_cb(Eina_Debug_Session *session EINA_UNUSED, int cid EINA_UNUSED, void *buffer EINA_UNUSED, int size EINA_UNUSED)
293{
294 if (!_eina_debug_sysmon_active) return EINA_TRUE;
295 _stop_cpu_thread();
284 if (_eina_debug_evlog_active) 296 if (_eina_debug_evlog_active)
285 { 297 {
286 eina_evlog_stop(); 298 eina_evlog_stop();
@@ -294,41 +306,13 @@ EINA_DEBUG_OPCODES_ARRAY_DEFINE(_OPS,
294 {"CPU/Freq/off", NULL, &_cpufreq_off_cb}, 306 {"CPU/Freq/off", NULL, &_cpufreq_off_cb},
295 {NULL, NULL, NULL} 307 {NULL, NULL, NULL}
296); 308);
309#endif
297 310
298Eina_Bool 311Eina_Bool
299_eina_debug_cpu_init(void) 312_eina_debug_cpu_init(void)
300{ 313{
301#ifndef _WIN32 314#ifndef _WIN32
302 int err;
303 sigset_t oldset, newset;
304
305 eina_lock_new(&_sysmon_lock); 315 eina_lock_new(&_sysmon_lock);
306 eina_lock_take(&_sysmon_lock);
307 sigemptyset(&newset);
308 sigaddset(&newset, SIGPIPE);
309 sigaddset(&newset, SIGALRM);
310 sigaddset(&newset, SIGCHLD);
311 sigaddset(&newset, SIGUSR1);
312 sigaddset(&newset, SIGUSR2);
313 sigaddset(&newset, SIGHUP);
314 sigaddset(&newset, SIGQUIT);
315 sigaddset(&newset, SIGINT);
316 sigaddset(&newset, SIGTERM);
317#ifdef SIGPWR
318 sigaddset(&newset, SIGPWR);
319#endif
320 pthread_sigmask(SIG_BLOCK, &newset, &oldset);
321 _eina_debug_cpu_active = 1;
322 eina_condition_new(&_exit_cond, &_sysmon_lock);
323
324 err = pthread_create(&_sysmon_thread, NULL, _sysmon, NULL);
325
326 pthread_sigmask(SIG_SETMASK, &oldset, NULL);
327 if (err != 0)
328 {
329 e_debug("EINA DEBUG ERROR: Can't create debug sysmon thread!");
330 abort();
331 }
332 eina_debug_opcodes_register(NULL, _OPS(), NULL, NULL); 316 eina_debug_opcodes_register(NULL, _OPS(), NULL, NULL);
333#endif 317#endif
334 return EINA_TRUE; 318 return EINA_TRUE;
@@ -337,17 +321,11 @@ _eina_debug_cpu_init(void)
337Eina_Bool 321Eina_Bool
338_eina_debug_cpu_shutdown(void) 322_eina_debug_cpu_shutdown(void)
339{ 323{
340 extern Eina_Bool fork_resetting; 324#ifndef _WIN32
341
342 if (_eina_debug_sysmon_active) 325 if (_eina_debug_sysmon_active)
343 eina_lock_take(&_sysmon_lock); 326 _stop_cpu_thread();
344 _eina_debug_cpu_active = 0;
345 if (!fork_resetting)
346 eina_condition_wait(&_exit_cond);
347 eina_condition_free(&_exit_cond);
348 eina_lock_release(&_sysmon_lock);
349 eina_lock_free(&_sysmon_lock); 327 eina_lock_free(&_sysmon_lock);
350 _eina_debug_sysmon_reset = _eina_debug_sysmon_active = _eina_debug_evlog_active = 0; 328 _eina_debug_sysmon_reset = _eina_debug_sysmon_active = _eina_debug_evlog_active = 0;
329#endif
351 return EINA_TRUE; 330 return EINA_TRUE;
352} 331}
353