Skip to content

Commit 6650c90

Browse files
committed
Split profiling functionality into separate file.
1 parent 479a544 commit 6650c90

File tree

6 files changed

+115
-79
lines changed

6 files changed

+115
-79
lines changed

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ RUNTIME_C_SRCS := \
4545
simplevector runtime_intrinsics precompile \
4646
threading partr stackwalk gc gc-debug gc-pages gc-stacks method \
4747
jlapi signal-handling safepoint jloptions timing subtype \
48-
crc32c
48+
crc32c profile
4949
RUNTIME_SRCS := APInt-C runtime_ccall processor rtutils $(RUNTIME_C_SRCS)
5050
SRCS := $(RUNTIME_SRCS)
5151

src/profile.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include <stdlib.h>
2+
#include <stddef.h>
3+
#include <stdio.h>
4+
#include <inttypes.h>
5+
#include "julia.h"
6+
#include "julia_internal.h"
7+
#include "threading.h"
8+
#include "gc.h"
9+
10+
11+
//
12+
// Shared infrastructure
13+
//
14+
15+
// data structures
16+
volatile jl_bt_element_t *bt_data_prof = NULL;
17+
volatile size_t bt_size_max = 0;
18+
volatile size_t bt_size_cur = 0;
19+
volatile uint8_t bt_overflow = 0;
20+
/// only for sampling profiler
21+
static volatile uint64_t profile_delay_nsec = 0;
22+
23+
volatile int profile_running = 0;
24+
25+
JL_DLLEXPORT void jl_profile_clear_data(void)
26+
{
27+
bt_size_cur = 0;
28+
bt_overflow = 0;
29+
}
30+
31+
JL_DLLEXPORT int jl_profile_init(size_t maxsize, uint64_t delay_nsec)
32+
{
33+
bt_size_max = maxsize;
34+
profile_delay_nsec = delay_nsec;
35+
36+
// Free previous profile buffers, if we have any
37+
if (bt_data_prof != NULL)
38+
free((void*)bt_data_prof);
39+
40+
// Initialize new profile buffers. We assume at least 10x
41+
bt_data_prof = (jl_bt_element_t*) calloc(bt_size_max, sizeof(jl_bt_element_t));
42+
if (bt_data_prof == NULL && bt_size_max > 0)
43+
return -1;
44+
45+
jl_profile_clear_data();
46+
return 0;
47+
}
48+
49+
JL_DLLEXPORT uint8_t *jl_profile_get_data(void)
50+
{
51+
return (uint8_t*) bt_data_prof;
52+
}
53+
54+
JL_DLLEXPORT size_t jl_profile_len_data(void)
55+
{
56+
return bt_size_cur;
57+
}
58+
59+
JL_DLLEXPORT size_t jl_profile_maxlen_data(void)
60+
{
61+
return bt_size_max;
62+
}
63+
64+
JL_DLLEXPORT int jl_profile_did_overflow(void)
65+
{
66+
return bt_overflow;
67+
}
68+
69+
70+
//
71+
// Sampling profiler
72+
//
73+
74+
JL_DLLEXPORT uint64_t jl_profile_delay_nsec(void)
75+
{
76+
return profile_delay_nsec;
77+
}
78+
79+
JL_DLLEXPORT int jl_profile_is_running(void)
80+
{
81+
return profile_running;
82+
}
83+
84+
// jl_profile_start_timer and jl_profile_stop_timer defined in signal-handling.c

src/signal-handling.c

Lines changed: 12 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@ extern "C" {
1717

1818
#include <threading.h>
1919

20-
// Profiler control variables //
21-
static volatile jl_bt_element_t *bt_data_prof = NULL;
22-
static volatile size_t bt_size_max = 0;
23-
static volatile size_t bt_size_cur = 0;
24-
static volatile uint8_t bt_overflow = 0;
25-
static volatile uint64_t nsecprof = 0;
26-
static volatile int running = 0;
27-
static const uint64_t GIGA = 1000000000ULL;
20+
extern volatile jl_bt_element_t *bt_data_prof;
21+
extern volatile size_t bt_size_max;
22+
extern volatile size_t bt_size_cur;
23+
extern volatile uint8_t bt_overflow;
24+
25+
extern volatile int profile_running;
26+
27+
extern uint64_t jl_profile_delay_nsec(void);
28+
static const uint64_t GIGA = 1000000000ULL;
29+
2830
// Timers to take samples at intervals
29-
JL_DLLEXPORT void jl_profile_stop_timer(void);
30-
JL_DLLEXPORT int jl_profile_start_timer(void);
31+
void _jl_profile_stop_timer(void);
32+
int _jl_profile_start_timer(void);
3133

3234
static uint64_t jl_last_sigint_trigger = 0;
3335
static uint64_t jl_disable_sigint_time = 0;
@@ -244,60 +246,6 @@ void jl_critical_error(int sig, bt_context_t *context, jl_bt_element_t *bt_data,
244246
gc_debug_critical_error();
245247
}
246248

247-
///////////////////////
248-
// Utility functions //
249-
///////////////////////
250-
251-
JL_DLLEXPORT void jl_profile_clear_data(void)
252-
{
253-
bt_size_cur = 0;
254-
bt_overflow = 0;
255-
}
256-
257-
JL_DLLEXPORT int jl_profile_init(size_t maxsize, uint64_t delay_nsec)
258-
{
259-
bt_size_max = maxsize;
260-
nsecprof = delay_nsec;
261-
if (bt_data_prof != NULL)
262-
free((void*)bt_data_prof);
263-
bt_data_prof = (jl_bt_element_t*) calloc(maxsize, sizeof(jl_bt_element_t));
264-
if (bt_data_prof == NULL && maxsize > 0)
265-
return -1;
266-
267-
jl_profile_clear_data();
268-
return 0;
269-
}
270-
271-
JL_DLLEXPORT uint8_t *jl_profile_get_data(void)
272-
{
273-
return (uint8_t*) bt_data_prof;
274-
}
275-
276-
JL_DLLEXPORT size_t jl_profile_len_data(void)
277-
{
278-
return bt_size_cur;
279-
}
280-
281-
JL_DLLEXPORT size_t jl_profile_maxlen_data(void)
282-
{
283-
return bt_size_max;
284-
}
285-
286-
JL_DLLEXPORT uint64_t jl_profile_delay_nsec(void)
287-
{
288-
return nsecprof;
289-
}
290-
291-
JL_DLLEXPORT int jl_profile_is_running(void)
292-
{
293-
return running;
294-
}
295-
296-
JL_DLLEXPORT int jl_profile_did_overflow(void)
297-
{
298-
return bt_overflow;
299-
}
300-
301249
#ifdef __cplusplus
302250
}
303251
#endif

src/signals-mach.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ void *mach_profile_listener(void *arg)
425425

426426
unw_context_t *uc;
427427
jl_thread_suspend_and_get_state(i, &uc);
428-
if (running) {
428+
if (profile_running) {
429429
// Get the backtrace
430430
size_t bt_size_step = 0;
431431
int incomplete = 0;
@@ -512,10 +512,11 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
512512
profile_started = 1;
513513
}
514514

515+
uint64_t nsecprof = jl_profile_delay_nsec();
515516
timerprof.tv_sec = nsecprof/GIGA;
516517
timerprof.tv_nsec = nsecprof%GIGA;
517518

518-
running = 1;
519+
profile_running = 1;
519520
ret = clock_alarm(clk, TIME_RELATIVE, timerprof, profile_port);
520521
HANDLE_MACH_ERROR("clock_alarm", ret);
521522

@@ -524,5 +525,5 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
524525

525526
JL_DLLEXPORT void jl_profile_stop_timer(void)
526527
{
527-
running = 0;
528+
profile_running = 0;
528529
}

src/signals-unix.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,22 +422,23 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
422422
return -2;
423423

424424
// Start the timer
425+
uint64_t nsecprof = jl_profile_delay_nsec();
425426
itsprof.it_interval.tv_sec = nsecprof/GIGA;
426427
itsprof.it_interval.tv_nsec = nsecprof%GIGA;
427428
itsprof.it_value.tv_sec = nsecprof/GIGA;
428429
itsprof.it_value.tv_nsec = nsecprof%GIGA;
429430
if (timer_settime(timerprof, 0, &itsprof, NULL) == -1)
430431
return -3;
431432

432-
running = 1;
433+
profile_running = 1;
433434
return 0;
434435
}
435436

436437
JL_DLLEXPORT void jl_profile_stop_timer(void)
437438
{
438-
if (running)
439+
if (profile_running)
439440
timer_delete(timerprof);
440-
running = 0;
441+
profile_running = 0;
441442
}
442443

443444
#elif defined(HAVE_ITIMER)
@@ -448,25 +449,26 @@ struct itimerval timerprof;
448449

449450
JL_DLLEXPORT int jl_profile_start_timer(void)
450451
{
452+
uint64_t nsecprof = jl_profile_delay_nsec();
451453
timerprof.it_interval.tv_sec = nsecprof/GIGA;
452454
timerprof.it_interval.tv_usec = (nsecprof%GIGA)/1000;
453455
timerprof.it_value.tv_sec = nsecprof/GIGA;
454456
timerprof.it_value.tv_usec = (nsecprof%GIGA)/1000;
455457
if (setitimer(ITIMER_PROF, &timerprof, 0) == -1)
456458
return -3;
457459

458-
running = 1;
460+
profile_running = 1;
459461

460462
return 0;
461463
}
462464

463465
JL_DLLEXPORT void jl_profile_stop_timer(void)
464466
{
465-
if (running) {
467+
if (profile_running) {
466468
memset(&timerprof, 0, sizeof(timerprof));
467469
setitimer(ITIMER_PROF, &timerprof, 0);
468470
}
469-
running = 0;
471+
profile_running = 0;
470472
}
471473

472474
#else
@@ -675,7 +677,7 @@ static void *signal_listener(void *arg)
675677
}
676678

677679
// do backtrace for profiler
678-
if (profile && running) {
680+
if (profile && profile_running) {
679681
if (bt_size_cur < bt_size_max - 1) {
680682
size_t bt_size_step = 0;
681683
int incomplete = 0;

src/signals-win.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam )
329329
while (1) {
330330
assert(bt_size_cur < bt_size_max - 1);
331331

332+
uint64_t nsecprof = jl_profile_delay_nsec();
332333
DWORD timeout = nsecprof/GIGA;
333334
timeout = min(max(timeout, tc.wPeriodMin*2), tc.wPeriodMax/2);
334335
Sleep(timeout);
@@ -340,7 +341,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam )
340341
// Get the backtrace data
341342
size_t bt_size_step;
342343
int incomplete;
343-
if (running) {
344+
if (profile_running) {
344345
CONTEXT ctxThread;
345346
memset(&ctxThread, 0, sizeof(CONTEXT));
346347
ctxThread.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
@@ -361,7 +362,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam )
361362
}
362363

363364
// Save the backtrace data
364-
if (running) {
365+
if (profile_running) {
365366
if (incomplete) {
366367
bt_overflow = 1;
367368
jl_profile_stop_timer();
@@ -379,7 +380,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam )
379380

380381
JL_DLLEXPORT int jl_profile_start_timer(void)
381382
{
382-
running = 1;
383+
profile_running = 1;
383384
if (hBtThread == 0) {
384385
hBtThread = CreateThread(
385386
NULL, // default security attributes
@@ -401,7 +402,7 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
401402

402403
JL_DLLEXPORT void jl_profile_stop_timer(void)
403404
{
404-
running = 0;
405+
profile_running = 0;
405406
}
406407

407408
void jl_install_default_signal_handlers(void)

0 commit comments

Comments
 (0)