From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id 2147A6ECE8; Wed, 20 Apr 2022 15:59:13 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org 2147A6ECE8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1650459553; bh=Y45QxC2YfKPG9XIwOPkmX/+NZ6s44mfaNo0J/qgktMc=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=XCHTUCpFB/1l3YvsCZJmKuK9+Uo8jyQC6DF8QFQMCrPytOZOaysatujyo8M7Xfgao FloW9//NrsQ5vrKiwXl9nVcCZJysrHikTAZNyN/W+PUf7woB0NlTexcfxOwg8qUb53 11o8M/DY+CYWywQzu6k9Oyh7QQQ9VgLzvUlnVu58= Received: from mail-lf1-f42.google.com (mail-lf1-f42.google.com [209.85.167.42]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id CE0936ECE8 for ; Wed, 20 Apr 2022 15:58:13 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org CE0936ECE8 Received: by mail-lf1-f42.google.com with SMTP id b21so2841389lfb.5 for ; Wed, 20 Apr 2022 05:58:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0wNS7eJ0mwNTTAGPpCFzmUZ2EFApPiVexrDGL/9n3F4=; b=hW6jwOpvzJhFVcyMwanGqcrLNEcwmZiHiX6ypiTfQ9aX2fJJWknkLnXhvko3QCLITH r50Xq6OPWTXqEWcH9/Gu5xULSUx+UN1IxyK9kw4lkepTobYqRTl1NSi/TVBqtjZ9MDb2 KuXOeiZIzbcJ/wWJr3Vr5DkjMcUbqwLMfq0gNGiRjMlVXYuOxl0K220DjUZIma+yCvdp +A4RcWMEGLfwFtPEoH+rLkxVftwS28h3EzWE2xxxOTdvJExLcd74ubbRkMPFTBRPXXcJ zfixZRR8Yd828pL7fVSeMO163tH7WBbXksZHje/3OZxYkOsMVm7auR4JhhRL1P5iJVQk XEsw== X-Gm-Message-State: AOAM531H7ilYURKgxl9EGhav4ukfwr8mkomtFwQm06n6yBHIuytBYBkI vUKTSUcNAv9thdnf8XkLbucNQQRVGI23jA== X-Google-Smtp-Source: ABdhPJyYQFy65eXiCsZe8ZMT388HnucMQF5SGiym3l/eYdpRM7MB6iZLQ01EqDf3rKHzE3X8EJK+dg== X-Received: by 2002:a05:6512:110d:b0:471:c104:d76d with SMTP id l13-20020a056512110d00b00471c104d76dmr1426959lfg.329.1650459492991; Wed, 20 Apr 2022 05:58:12 -0700 (PDT) Received: from localhost.localdomain ([93.175.28.57]) by smtp.gmail.com with ESMTPSA id o3-20020a198c03000000b00448b7b1780csm1824076lfd.63.2022.04.20.05.58.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Apr 2022 05:58:12 -0700 (PDT) X-Google-Original-From: Maxim Kokryashkin To: tarantool-patches@dev.tarantool.org, imun@tarantool.org, skaplun@tarantool.org Date: Wed, 20 Apr 2022 15:57:58 +0300 Message-Id: X-Mailer: git-send-email 2.35.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH luajit v5 2/7] core: separate the profiling timer from lj_profile X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Maxim Kokryashkin via Tarantool-patches Reply-To: Maxim Kokryashkin Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Mikhail Shishatskiy This patch makes timer machinery in lj_profile self-reliant by introducing lj_profile_timer structure and start/stop interface for it. This timer is useful for other sampling profiling features. Part of tarantool/tarantool#781 --- src/CMakeLists.txt | 1 + src/Makefile.dep.original | 35 ++++---- src/Makefile.original | 2 +- src/lj_profile.c | 176 +++----------------------------------- src/lj_profile_timer.c | 133 ++++++++++++++++++++++++++++ src/lj_profile_timer.h | 83 ++++++++++++++++++ src/ljamalg.c | 1 + 7 files changed, 250 insertions(+), 181 deletions(-) create mode 100644 src/lj_profile_timer.c create mode 100644 src/lj_profile_timer.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 809aac68..c92d78cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -69,6 +69,7 @@ make_source_list(SOURCES_PROFILER SOURCES lj_memprof.c lj_profile.c + lj_profile_timer.c ) # Lua standard library + extensions by LuaJIT. diff --git a/src/Makefile.dep.original b/src/Makefile.dep.original index faa44a0b..fc0fb5d2 100644 --- a/src/Makefile.dep.original +++ b/src/Makefile.dep.original @@ -178,7 +178,10 @@ lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_vm.h lj_vmevent.h lj_profile.o: lj_profile.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_buf.h lj_gc.h lj_str.h lj_frame.h lj_bc.h lj_debug.h lj_dispatch.h \ - lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h luajit.h + lj_jit.h lj_ir.h lj_trace.h lj_traceerr.h lj_profile.h \ + lj_profile_timer.h luajit.h +lj_profile_timer.o: lj_profile_timer.c lj_profile_timer.h lj_def.h lua.h \ + luaconf.h lj_arch.h lj_record.o: lj_record.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_frame.h lj_bc.h \ lj_ctype.h lj_gc.h lj_ff.h lj_ffdef.h lj_debug.h lj_ir.h lj_jit.h \ @@ -221,21 +224,23 @@ ljamalg.o: ljamalg.c lua.h luaconf.h lauxlib.h lj_gc.c lj_obj.h lj_def.h \ lj_func.h lj_udata.h lj_meta.h lj_state.h lj_frame.h lj_bc.h lj_ctype.h \ lj_cdata.h lj_trace.h lj_jit.h lj_ir.h lj_dispatch.h lj_traceerr.h \ lj_vm.h lj_err.c lj_debug.h lj_ff.h lj_ffdef.h lj_strfmt.h lj_char.c \ - lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_wbuf.c lj_wbuf.h lj_utils.h \ - lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h lj_lib.h \ - lj_debug.c lj_state.c lj_lex.h lj_alloc.h luajit.h lj_dispatch.c \ - lj_ccallback.h lj_profile.h lj_memprof.h lj_vmevent.c lj_vmevent.h \ + lj_char.h lj_bc.c lj_bcdef.h lj_obj.c lj_buf.c lj_wbuf.c lj_wbuf.h \ + lj_utils.h lj_str.c lj_tab.c lj_func.c lj_udata.c lj_meta.c lj_strscan.h \ + lj_lib.h lj_debug.c lj_state.c lj_lex.h lj_alloc.h luajit.h lj_memprof.h \ + lj_dispatch.c lj_ccallback.h lj_profile.h lj_vmevent.c lj_vmevent.h \ lj_vmmath.c lj_strscan.c lj_strfmt.c lj_strfmt_num.c lj_api.c lj_mapi.c \ - lmisclib.h lj_profile.c lj_memprof.c lj_lex.c lualib.h lj_parse.h lj_parse.c \ - lj_bcread.c lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c \ - lj_cconv.h lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h \ - lj_target_*.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h \ - lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h lj_iropt.h lj_opt_mem.c \ - lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c lj_opt_loop.c \ - lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c lj_snap.c lj_record.c \ - lj_record.h lj_ffrecord.h lj_crecord.c lj_crecord.h lj_ffrecord.c lj_recdef.h \ - lj_asm.c lj_asm.h lj_emit_*.h lj_asm_*.h lj_trace.c lj_gdbjit.h lj_gdbjit.c \ - lj_alloc.c lj_utils_leb128.c lib_aux.c lib_base.c lj_libdef.h lib_math.c \ + lmisclib.h lj_profile.c lj_profile_timer.h lj_profile_timer.c \ + lj_memprof.c lj_lex.c lualib.h lj_parse.h lj_parse.c lj_bcread.c \ + lj_bcdump.h lj_bcwrite.c lj_load.c lj_ctype.c lj_cdata.c lj_cconv.h \ + lj_cconv.c lj_ccall.c lj_ccall.h lj_ccallback.c lj_target.h \ + lj_target_x86.h lj_mcode.h lj_carith.c lj_carith.h lj_clib.c lj_clib.h \ + lj_cparse.c lj_cparse.h lj_lib.c lj_ir.c lj_ircall.h lj_iropt.h \ + lj_opt_mem.c lj_opt_fold.c lj_folddef.h lj_opt_narrow.c lj_opt_dce.c \ + lj_opt_loop.c lj_snap.h lj_opt_split.c lj_opt_sink.c lj_mcode.c \ + lj_snap.c lj_record.c lj_record.h lj_ffrecord.h lj_crecord.c \ + lj_crecord.h lj_ffrecord.c lj_recdef.h lj_asm.c lj_asm.h lj_emit_x86.h \ + lj_asm_x86.h lj_trace.c lj_gdbjit.h lj_gdbjit.c lj_alloc.c \ + lj_utils_leb128.c lib_aux.c lib_base.c lj_libdef.h lib_math.c \ lib_string.c lib_table.c lib_io.c lib_os.c lib_package.c lib_debug.c \ lib_bit.c lib_jit.c lib_ffi.c lib_misc.c lib_init.c luajit.o: luajit.c lua.h luaconf.h lauxlib.h lualib.h luajit.h lj_arch.h diff --git a/src/Makefile.original b/src/Makefile.original index 031f0778..fe37caa7 100644 --- a/src/Makefile.original +++ b/src/Makefile.original @@ -490,7 +490,7 @@ LJLIB_C= $(LJLIB_O:.o=.c) LJCORE_O= lj_gc.o lj_err.o lj_char.o lj_bc.o lj_obj.o lj_buf.o lj_wbuf.o \ lj_str.o lj_tab.o lj_func.o lj_udata.o lj_meta.o lj_debug.o \ lj_state.o lj_dispatch.o lj_vmevent.o lj_vmmath.o lj_strscan.o \ - lj_strfmt.o lj_strfmt_num.o lj_api.o lj_mapi.o lj_profile.o \ + lj_strfmt.o lj_strfmt_num.o lj_api.o lj_mapi.o lj_profile.o lj_profile_timer.o \ lj_memprof.o lj_lex.o lj_parse.o lj_bcread.o lj_bcwrite.o lj_load.o \ lj_ir.o lj_opt_mem.o lj_opt_fold.o lj_opt_narrow.o \ lj_opt_dce.o lj_opt_loop.o lj_opt_split.o lj_opt_sink.o \ diff --git a/src/lj_profile.c b/src/lj_profile.c index 7b09a63a..4412d68b 100644 --- a/src/lj_profile.c +++ b/src/lj_profile.c @@ -19,66 +19,19 @@ #include "lj_trace.h" #endif #include "lj_profile.h" +#include "lj_profile_timer.h" #include "luajit.h" -#if LJ_PROFILE_SIGPROF - -#include -#include -#define profile_lock(ps) UNUSED(ps) -#define profile_unlock(ps) UNUSED(ps) - -#elif LJ_PROFILE_PTHREAD - -#include -#include -#if LJ_TARGET_PS3 -#include -#endif -#define profile_lock(ps) pthread_mutex_lock(&ps->lock) -#define profile_unlock(ps) pthread_mutex_unlock(&ps->lock) - -#elif LJ_PROFILE_WTHREAD - -#define WIN32_LEAN_AND_MEAN -#if LJ_TARGET_XBOX360 -#include -#include -#else -#include -#endif -typedef unsigned int (WINAPI *WMM_TPFUNC)(unsigned int); -#define profile_lock(ps) EnterCriticalSection(&ps->lock) -#define profile_unlock(ps) LeaveCriticalSection(&ps->lock) - -#endif - /* Profiler state. */ typedef struct ProfileState { global_State *g; /* VM state that started the profiler. */ luaJIT_profile_callback cb; /* Profiler callback. */ void *data; /* Profiler callback data. */ SBuf sb; /* String buffer for stack dumps. */ - int interval; /* Sample interval in milliseconds. */ int samples; /* Number of samples for next callback. */ int vmstate; /* VM state when profile timer triggered. */ -#if LJ_PROFILE_SIGPROF - struct sigaction oldsa; /* Previous SIGPROF state. */ -#elif LJ_PROFILE_PTHREAD - pthread_mutex_t lock; /* g->hookmask update lock. */ - pthread_t thread; /* Timer thread. */ - int abort; /* Abort timer thread. */ -#elif LJ_PROFILE_WTHREAD -#if LJ_TARGET_WINDOWS - HINSTANCE wmm; /* WinMM library handle. */ - WMM_TPFUNC wmm_tbp; /* WinMM timeBeginPeriod function. */ - WMM_TPFUNC wmm_tep; /* WinMM timeEndPeriod function. */ -#endif - CRITICAL_SECTION lock; /* g->hookmask update lock. */ - HANDLE thread; /* Timer thread. */ - int abort; /* Abort timer thread. */ -#endif + lj_profile_timer timer; /* Profiling timer */ } ProfileState; /* Sadly, we have to use a static profiler state. @@ -168,129 +121,21 @@ static void profile_trigger(ProfileState *ps) profile_unlock(ps); } -/* -- OS-specific profile timer handling ---------------------------------- */ - #if LJ_PROFILE_SIGPROF -/* SIGPROF handler. */ -static void profile_signal(int sig) +static void profile_handler(int sig, siginfo_t *info, void *ctx) { UNUSED(sig); + UNUSED(info); + UNUSED(ctx); profile_trigger(&profile_state); } -/* Start profiling timer. */ -static void profile_timer_start(ProfileState *ps) -{ - int interval = ps->interval; - struct itimerval tm; - struct sigaction sa; - tm.it_value.tv_sec = tm.it_interval.tv_sec = interval / 1000; - tm.it_value.tv_usec = tm.it_interval.tv_usec = (interval % 1000) * 1000; - setitimer(ITIMER_PROF, &tm, NULL); - sa.sa_flags = SA_RESTART; - sa.sa_handler = profile_signal; - sigemptyset(&sa.sa_mask); - sigaction(SIGPROF, &sa, &ps->oldsa); -} - -/* Stop profiling timer. */ -static void profile_timer_stop(ProfileState *ps) -{ - struct itimerval tm; - tm.it_value.tv_sec = tm.it_interval.tv_sec = 0; - tm.it_value.tv_usec = tm.it_interval.tv_usec = 0; - setitimer(ITIMER_PROF, &tm, NULL); - sigaction(SIGPROF, &ps->oldsa, NULL); -} - -#elif LJ_PROFILE_PTHREAD - -/* POSIX timer thread. */ -static void *profile_thread(ProfileState *ps) -{ - int interval = ps->interval; -#if !LJ_TARGET_PS3 - struct timespec ts; - ts.tv_sec = interval / 1000; - ts.tv_nsec = (interval % 1000) * 1000000; -#endif - while (1) { -#if LJ_TARGET_PS3 - sys_timer_usleep(interval * 1000); #else - nanosleep(&ts, NULL); -#endif - if (ps->abort) break; - profile_trigger(ps); - } - return NULL; -} - -/* Start profiling timer thread. */ -static void profile_timer_start(ProfileState *ps) -{ - pthread_mutex_init(&ps->lock, 0); - ps->abort = 0; - pthread_create(&ps->thread, NULL, (void *(*)(void *))profile_thread, ps); -} - -/* Stop profiling timer thread. */ -static void profile_timer_stop(ProfileState *ps) -{ - ps->abort = 1; - pthread_join(ps->thread, NULL); - pthread_mutex_destroy(&ps->lock); -} - -#elif LJ_PROFILE_WTHREAD - -/* Windows timer thread. */ -static DWORD WINAPI profile_thread(void *psx) -{ - ProfileState *ps = (ProfileState *)psx; - int interval = ps->interval; -#if LJ_TARGET_WINDOWS - ps->wmm_tbp(interval); -#endif - while (1) { - Sleep(interval); - if (ps->abort) break; - profile_trigger(ps); - } -#if LJ_TARGET_WINDOWS - ps->wmm_tep(interval); -#endif - return 0; -} - -/* Start profiling timer thread. */ -static void profile_timer_start(ProfileState *ps) -{ -#if LJ_TARGET_WINDOWS - if (!ps->wmm) { /* Load WinMM library on-demand. */ - ps->wmm = LoadLibraryExA("winmm.dll", NULL, 0); - if (ps->wmm) { - ps->wmm_tbp = (WMM_TPFUNC)GetProcAddress(ps->wmm, "timeBeginPeriod"); - ps->wmm_tep = (WMM_TPFUNC)GetProcAddress(ps->wmm, "timeEndPeriod"); - if (!ps->wmm_tbp || !ps->wmm_tep) { - ps->wmm = NULL; - return; - } - } - } -#endif - InitializeCriticalSection(&ps->lock); - ps->abort = 0; - ps->thread = CreateThread(NULL, 0, profile_thread, ps, 0, NULL); -} -/* Stop profiling timer thread. */ -static void profile_timer_stop(ProfileState *ps) +static void profile_handler() { - ps->abort = 1; - WaitForSingleObject(ps->thread, INFINITE); - DeleteCriticalSection(&ps->lock); + profile_trigger(&profile_state); } #endif @@ -327,12 +172,13 @@ LUA_API void luaJIT_profile_start(lua_State *L, const char *mode, if (ps->g) return; /* Profiler in use by another VM. */ } ps->g = G(L); - ps->interval = interval; ps->cb = cb; ps->data = data; ps->samples = 0; lj_buf_init(L, &ps->sb); - profile_timer_start(ps); + ps->timer.opt.interval_msec = interval; + ps->timer.opt.handler = profile_handler; + lj_profile_timer_start(&ps->timer); } /* Stop profiling. */ @@ -341,7 +187,7 @@ LUA_API void luaJIT_profile_stop(lua_State *L) ProfileState *ps = &profile_state; global_State *g = ps->g; if (G(L) == g) { /* Only stop profiler if started by this VM. */ - profile_timer_stop(ps); + lj_profile_timer_stop(&ps->timer); g->hookmask &= ~HOOK_PROFILE; lj_dispatch_update(g); #if LJ_HASJIT diff --git a/src/lj_profile_timer.c b/src/lj_profile_timer.c new file mode 100644 index 00000000..056fd1f7 --- /dev/null +++ b/src/lj_profile_timer.c @@ -0,0 +1,133 @@ +/* +** Simple profiling timer. +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h +*/ + +#define lj_profile_timer_c +#define LUA_CORE + +#include "lj_profile_timer.h" + +#if LJ_HASPROFILE + +#if LJ_PROFILE_SIGPROF + +/* Start profiling timer. */ +void lj_profile_timer_start(lj_profile_timer *timer) +{ + const int interval = timer->opt.interval_msec; + struct itimerval tm; + struct sigaction sa; + tm.it_value.tv_sec = tm.it_interval.tv_sec = interval / 1000; + tm.it_value.tv_usec = tm.it_interval.tv_usec = (interval % 1000) * 1000; + setitimer(ITIMER_PROF, &tm, NULL); + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sa.sa_sigaction = timer->opt.handler; + sigemptyset(&sa.sa_mask); + sigaction(SIGPROF, &sa, &timer->oldsa); +} + +/* Stop profiling timer. */ +void lj_profile_timer_stop(lj_profile_timer *timer) +{ + struct itimerval tm; + tm.it_value.tv_sec = tm.it_interval.tv_sec = 0; + tm.it_value.tv_usec = tm.it_interval.tv_usec = 0; + setitimer(ITIMER_PROF, &tm, NULL); + sigaction(SIGPROF, &timer->oldsa, NULL); +} + +#elif LJ_PROFILE_PTHREAD + +/* POSIX timer thread. */ +static void *timer_thread(lj_profile_timer *timer) +{ + int interval = timer->opt.interval_msec; +#if !LJ_TARGET_PS3 + struct timespec ts; + ts.tv_sec = interval / 1000; + ts.tv_nsec = (interval % 1000) * 1000000; +#endif + while (1) { +#if LJ_TARGET_PS3 + sys_timer_usleep(interval * 1000); +#else + nanosleep(&ts, NULL); +#endif + if (timer->abort) break; + timer->opt.handler(); + } + return NULL; +} + +/* Start profiling timer thread. */ +void lj_profile_timer_start(lj_profile_timer *timer) +{ + pthread_mutex_init(&timer->lock, 0); + timer->abort = 0; + pthread_create(&timer->thread, NULL, (void *(*)(void *))timer_thread, + timer); +} + +/* Stop profiling timer thread. */ +void lj_profile_timer_stop(lj_profile_timer *timer) +{ + timer->abort = 1; + pthread_join(timer->thread, NULL); + pthread_mutex_destroy(&timer->lock); +} + +#elif LJ_PROFILE_WTHREAD + +/* Windows timer thread. */ +static DWORD WINAPI timer_thread(void *timerx) +{ + lj_profile_timer *timer = (lj_profile_timer *)timerx; + int interval = timer->opt.interval_msec; +#if LJ_TARGET_WINDOWS + timer->wmm_tbp(interval); +#endif + while (1) { + Sleep(interval); + if (timer->abort) break; + timer->opt.handler(); + } +#if LJ_TARGET_WINDOWS + timer->wmm_tep(interval); +#endif + return 0; +} + +/* Start profiling timer thread. */ +void lj_profile_timer_start(lj_profile_timer *timer) +{ +#if LJ_TARGET_WINDOWS + if (!timer->wmm) { /* Load WinMM library on-demand. */ + timer->wmm = LoadLibraryExA("winmm.dll", NULL, 0); + if (timer->wmm) { + timer->wmm_tbp = + (WMM_TPFUNC)GetProcAddress(timer->wmm, "timeBeginPeriod"); + timer->wmm_tep = (WMM_TPFUNC)GetProcAddress(timer->wmm, "timeEndPeriod"); + if (!timer->wmm_tbp || !timer->wmm_tep) { + timer->wmm = NULL; + return; + } + } + } +#endif + InitializeCriticalSection(&timer->lock); + timer->abort = 0; + timer->thread = CreateThread(NULL, 0, timer_thread, timer, 0, NULL); +} + +/* Stop profiling timer thread. */ +void lj_profile_timer_stop(lj_profile_timer *timer) +{ + timer->abort = 1; + WaitForSingleObject(timer->thread, INFINITE); + DeleteCriticalSection(&timer->lock); +} + +#endif + +#endif /* LJ_HASPROFILE */ diff --git a/src/lj_profile_timer.h b/src/lj_profile_timer.h new file mode 100644 index 00000000..1deeea53 --- /dev/null +++ b/src/lj_profile_timer.h @@ -0,0 +1,83 @@ +/* +** Simple profiling timer. +** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h +*/ + +#ifndef _LJ_PROFILE_TIMER_H +#define _LJ_PROFILE_TIMER_H + +#include "lj_def.h" +#include "lj_arch.h" + +#if LJ_HASPROFILE + +#if LJ_PROFILE_SIGPROF + +#include +#include +#define profile_lock(ps) UNUSED(ps) +#define profile_unlock(ps) UNUSED(ps) + +#elif LJ_PROFILE_PTHREAD + +#include +#include +#if LJ_TARGET_PS3 +#include +#endif +#define profile_lock(ps) pthread_mutex_lock(&ps->lock) +#define profile_unlock(ps) pthread_mutex_unlock(&ps->lock) + +#elif LJ_PROFILE_WTHREAD + +#define WIN32_LEAN_AND_MEAN +#if LJ_TARGET_XBOX360 +#include +#include +#else +#include +#endif +typedef unsigned int (WINAPI *WMM_TPFUNC)(unsigned int); +#define profile_lock(ps) EnterCriticalSection(&ps->lock) +#define profile_unlock(ps) LeaveCriticalSection(&ps->lock) + +#endif + +typedef struct { +#if LJ_PROFILE_SIGPROF + void (*handler)(int, siginfo_t*, void*); +#else + void (*handler)(void); +#endif + uint32_t interval_msec; +} lj_profile_timer_opt; + +typedef struct { + lj_profile_timer_opt opt; +#if LJ_PROFILE_SIGPROF + struct sigaction oldsa; /* Previous SIGPROF state. */ +#elif LJ_PROFILE_PTHREAD + pthread_mutex_t lock; /* g->hookmask update lock. */ + pthread_t thread; /* Timer thread. */ + int abort; /* Abort timer thread. */ +#elif LJ_PROFILE_WTHREAD +#if LJ_TARGET_WINDOWS + HINSTANCE wmm; /* WinMM library handle. */ + WMM_TPFUNC wmm_tbp; /* WinMM timeBeginPeriod function. */ + WMM_TPFUNC wmm_tep; /* WinMM timeEndPeriod function. */ +#endif + CRITICAL_SECTION lock; /* g->hookmask update lock. */ + HANDLE thread; /* Timer thread. */ + int abort; /* Abort timer thread. */ +#endif +} lj_profile_timer; + +/* Start profiling timer. */ +void lj_profile_timer_start(lj_profile_timer *timer); + +/* Stop profiling timer. */ +void lj_profile_timer_stop(lj_profile_timer *timer); + +#endif /* LJ_HASPROFILE */ + +#endif diff --git a/src/ljamalg.c b/src/ljamalg.c index 3f7e6860..ce7a0d6c 100644 --- a/src/ljamalg.c +++ b/src/ljamalg.c @@ -51,6 +51,7 @@ #include "lj_api.c" #include "lj_mapi.c" #include "lj_profile.c" +#include "lj_profile_timer.c" #include "lj_memprof.c" #include "lj_lex.c" #include "lj_parse.c" -- 2.35.1