Skip to content

Commit

Permalink
Implement profiler for linux. (HaxeFoundation#490)
Browse files Browse the repository at this point in the history
  • Loading branch information
Apprentice-Alchemist authored and crazyjul committed Jan 10, 2024
1 parent f3ed548 commit 1b4643a
Showing 1 changed file with 56 additions and 1 deletion.
57 changes: 56 additions & 1 deletion src/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@
#include <hl.h>
#include <hlmodule.h>

#ifdef HL_LINUX
#include <signal.h>
#include <semaphore.h>
#include <unistd.h>
#endif

#define MAX_STACK_SIZE (8 << 20)
#define MAX_STACK_COUNT 2048

Expand Down Expand Up @@ -73,6 +79,25 @@ static struct {
profile_data *first_record;
} data = {0};

#ifdef HL_LINUX
static struct
{
sem_t msg2;
sem_t msg3;
sem_t msg4;
ucontext_t context;
} shared_context;

static void sigprof_handler(int sig, siginfo_t *info, void *ucontext)
{
ucontext_t *ctx = ucontext;
shared_context.context = *ctx;
sem_post(&shared_context.msg2);
sem_wait(&shared_context.msg3);
sem_post(&shared_context.msg4);
}
#endif

static void *get_thread_stackptr( thread_handle *t, void **eip ) {
#ifdef HL_WIN_DESKTOP
CONTEXT c;
Expand All @@ -85,6 +110,14 @@ static void *get_thread_stackptr( thread_handle *t, void **eip ) {
*eip = (void*)c.Eip;
return (void*)c.Esp;
# endif
#elif defined(HL_LINUX)
# ifdef HL_64
*eip = (void*)shared_context.context.uc_mcontext.gregs[REG_RIP];
return (void*)shared_context.context.uc_mcontext.gregs[REG_RSP];
# else
*eip = (void*)shared_context.context.uc_mcontext.gregs[REG_EIP];
return (void*)shared_context.context.uc_mcontext.gregs[REG_ESP];
# endif
#else
return NULL;
#endif
Expand All @@ -110,6 +143,14 @@ static bool pause_thread( thread_handle *t, bool b ) {
ResumeThread(t->h);
return true;
}
#elif defined(HL_LINUX)
if( b ) {
tgkill(getpid(), t->tid, SIGPROF);
return sem_wait(&shared_context.msg2) == 0;
} else {
sem_post(&shared_context.msg3);
return sem_wait(&shared_context.msg4) == 0;
}
#else
return false;
#endif
Expand Down Expand Up @@ -144,6 +185,10 @@ static void read_thread_data( thread_handle *t ) {
return;
}

#ifdef HL_LINUX
int count = hl_module_capture_stack_range(t->inf->stack_top, stack, data.stackOut, MAX_STACK_COUNT);
pause_thread(t, false);
#else
int size = (int)((unsigned char*)t->inf->stack_top - (unsigned char*)stack);
if( size > MAX_STACK_SIZE-32 ) size = MAX_STACK_SIZE-32;
memcpy(data.tmpMemory + 2,stack,size);
Expand All @@ -153,6 +198,7 @@ static void read_thread_data( thread_handle *t ) {
size += sizeof(void*) * 2;

int count = hl_module_capture_stack_range((char*)data.tmpMemory+size, (void**)data.tmpMemory, data.stackOut, MAX_STACK_COUNT);
#endif
int eventId = count | 0x80000000;
double time = hl_sys_time();
record_data(&time,sizeof(double));
Expand Down Expand Up @@ -211,7 +257,7 @@ static void hl_profile_loop( void *_ ) {
static void profile_event( int code, vbyte *data, int dataLen );

void hl_profile_setup( int sample_count ) {
# if defined(HL_THREADS) && defined(HL_WIN_DESKTOP)
# if defined(HL_THREADS) && (defined(HL_WIN_DESKTOP) || defined(HL_LINUX))
hl_setup_profiler(profile_event,hl_profile_end);
if( data.sample_count ) return;
if( sample_count < 0 ) {
Expand All @@ -220,6 +266,15 @@ void hl_profile_setup( int sample_count ) {
return;
}
data.sample_count = sample_count;
# ifdef HL_LINUX
sem_init(&shared_context.msg2, 0, 0);
sem_init(&shared_context.msg3, 0, 0);
sem_init(&shared_context.msg4, 0, 0);
struct sigaction action = {0};
action.sa_sigaction = sigprof_handler;
action.sa_flags = SA_SIGINFO;
sigaction(SIGPROF, &action, NULL);
# endif
hl_thread_start(hl_profile_loop,NULL,false);
# endif
}
Expand Down

0 comments on commit 1b4643a

Please sign in to comment.