aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2013-09-16 11:23:10 +0200
committerMike Pall <mike>2013-09-16 11:23:10 +0200
commitb30a789ab8513f58c9696ed1e20042065e0fcef0 (patch)
treebb6d502900e13b1ef262bef8f2ab3d5b74458517 /src
parent8201fda2fc4f43856a27607b4784e9b09fd3ccb4 (diff)
downloadluajit-b30a789ab8513f58c9696ed1e20042065e0fcef0.tar.gz
luajit-b30a789ab8513f58c9696ed1e20042065e0fcef0.tar.bz2
luajit-b30a789ab8513f58c9696ed1e20042065e0fcef0.zip
Protect g->hookmask with lock when using profiler thread.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.dep6
-rw-r--r--src/lib_jit.c2
-rw-r--r--src/lj_dispatch.c34
-rw-r--r--src/lj_profile.c36
4 files changed, 49 insertions, 29 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index 9ae6043a..6348d483 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -24,9 +24,9 @@ lib_io.o: lib_io.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
24 lj_strfmt.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h 24 lj_strfmt.h lj_ff.h lj_ffdef.h lj_lib.h lj_libdef.h
25lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 25lib_jit.o: lib_jit.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
26 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \ 26 lj_arch.h lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_str.h lj_tab.h \
27 lj_state.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h \ 27 lj_state.h lj_bc.h lj_ctype.h lj_ir.h lj_jit.h lj_trace.h lj_dispatch.h \
28 lj_target.h lj_target_*.h lj_dispatch.h lj_vm.h lj_vmevent.h lj_lib.h \ 28 lj_traceerr.h lj_ircall.h lj_iropt.h lj_target.h lj_target_*.h lj_vm.h \
29 luajit.h lj_libdef.h 29 lj_vmevent.h lj_lib.h luajit.h lj_libdef.h
30lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \ 30lib_math.o: lib_math.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h \
31 lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h 31 lj_def.h lj_arch.h lj_lib.h lj_vm.h lj_libdef.h
32lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \ 32lib_os.o: lib_os.c lua.h luaconf.h lauxlib.h lualib.h lj_obj.h lj_def.h \
diff --git a/src/lib_jit.c b/src/lib_jit.c
index be075ce4..7bb642cb 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -24,6 +24,7 @@
24#if LJ_HASJIT 24#if LJ_HASJIT
25#include "lj_ir.h" 25#include "lj_ir.h"
26#include "lj_jit.h" 26#include "lj_jit.h"
27#include "lj_trace.h"
27#include "lj_ircall.h" 28#include "lj_ircall.h"
28#include "lj_iropt.h" 29#include "lj_iropt.h"
29#include "lj_target.h" 30#include "lj_target.h"
@@ -560,6 +561,7 @@ static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
560 if (G(L2)->panic) G(L2)->panic(L2); 561 if (G(L2)->panic) G(L2)->panic(L2);
561 exit(EXIT_FAILURE); 562 exit(EXIT_FAILURE);
562 } 563 }
564 lj_trace_abort(G(L2));
563 } 565 }
564} 566}
565 567
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index 01bc4239..af269c44 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -508,28 +508,18 @@ out:
508void LJ_FASTCALL lj_dispatch_profile(lua_State *L, const BCIns *pc) 508void LJ_FASTCALL lj_dispatch_profile(lua_State *L, const BCIns *pc)
509{ 509{
510 ERRNO_SAVE 510 ERRNO_SAVE
511 global_State *g = G(L); 511 GCfunc *fn = curr_func(L);
512 uint8_t mask = g->hookmask; 512 GCproto *pt = funcproto(fn);
513 g->hookmask = (mask & ~HOOK_PROFILE); 513 void *cf = cframe_raw(L->cframe);
514 lj_dispatch_update(g); 514 const BCIns *oldpc = cframe_pc(cf);
515 if (!(mask & HOOK_VMEVENT)) { 515 global_State *g;
516 GCfunc *fn = curr_func(L); 516 setcframe_pc(cf, pc);
517 GCproto *pt = funcproto(fn); 517 L->top = L->base + cur_topslot(pt, pc, cframe_multres_n(cf));
518 void *cf = cframe_raw(L->cframe); 518 lj_profile_interpreter(L);
519 const BCIns *oldpc = cframe_pc(cf); 519 setcframe_pc(cf, oldpc);
520 uint8_t oldh = hook_save(g); 520 g = G(L);
521 BCReg slots; 521 setgcref(g->cur_L, obj2gco(L));
522 hook_vmevent(g); 522 setvmstate(g, INTERP);
523 setcframe_pc(cf, pc);
524 slots = cur_topslot(pt, pc, cframe_multres_n(cf));
525 L->top = L->base + slots; /* Fix top. */
526 lj_profile_interpreter(L);
527 setgcref(g->cur_L, obj2gco(L));
528 setcframe_pc(cf, oldpc);
529 hook_restore(g, oldh);
530 lj_trace_abort(g);
531 setvmstate(g, INTERP);
532 }
533 ERRNO_RESTORE 523 ERRNO_RESTORE
534} 524}
535#endif 525#endif
diff --git a/src/lj_profile.c b/src/lj_profile.c
index c7bc6168..1984a676 100644
--- a/src/lj_profile.c
+++ b/src/lj_profile.c
@@ -26,6 +26,8 @@
26 26
27#include <sys/time.h> 27#include <sys/time.h>
28#include <signal.h> 28#include <signal.h>
29#define profile_lock(ps) UNUSED(ps)
30#define profile_unlock(ps) UNUSED(ps)
29 31
30#elif LJ_PROFILE_PTHREAD 32#elif LJ_PROFILE_PTHREAD
31 33
@@ -34,12 +36,16 @@
34#if LJ_TARGET_PS3 36#if LJ_TARGET_PS3
35#include <sys/timer.h> 37#include <sys/timer.h>
36#endif 38#endif
39#define profile_lock(ps) pthread_mutex_lock(&ps->lock)
40#define profile_unlock(ps) pthread_mutex_unlock(&ps->lock)
37 41
38#elif LJ_PROFILE_WTHREAD 42#elif LJ_PROFILE_WTHREAD
39 43
40#define WIN32_LEAN_AND_MEAN 44#define WIN32_LEAN_AND_MEAN
41#include <windows.h> 45#include <windows.h>
42typedef unsigned int (WINAPI *WMM_TPFUNC)(unsigned int); 46typedef unsigned int (WINAPI *WMM_TPFUNC)(unsigned int);
47#define profile_lock(ps) EnterCriticalSection(&ps->lock)
48#define profile_unlock(ps) LeaveCriticalSection(&ps->lock)
43 49
44#endif 50#endif
45 51
@@ -55,6 +61,7 @@ typedef struct ProfileState {
55#if LJ_PROFILE_SIGPROF 61#if LJ_PROFILE_SIGPROF
56 struct sigaction oldsa; /* Previous SIGPROF state. */ 62 struct sigaction oldsa; /* Previous SIGPROF state. */
57#elif LJ_PROFILE_PTHREAD 63#elif LJ_PROFILE_PTHREAD
64 pthread_mutex_t lock; /* g->hookmask update lock. */
58 pthread_t thread; /* Timer thread. */ 65 pthread_t thread; /* Timer thread. */
59 int abort; /* Abort timer thread. */ 66 int abort; /* Abort timer thread. */
60#elif LJ_PROFILE_WTHREAD 67#elif LJ_PROFILE_WTHREAD
@@ -63,6 +70,7 @@ typedef struct ProfileState {
63 WMM_TPFUNC wmm_tbp; /* WinMM timeBeginPeriod function. */ 70 WMM_TPFUNC wmm_tbp; /* WinMM timeBeginPeriod function. */
64 WMM_TPFUNC wmm_tep; /* WinMM timeEndPeriod function. */ 71 WMM_TPFUNC wmm_tep; /* WinMM timeEndPeriod function. */
65#endif 72#endif
73 CRITICAL_SECTION lock; /* g->hookmask update lock. */
66 HANDLE thread; /* Timer thread. */ 74 HANDLE thread; /* Timer thread. */
67 int abort; /* Abort timer thread. */ 75 int abort; /* Abort timer thread. */
68#endif 76#endif
@@ -85,9 +93,23 @@ static ProfileState profile_state;
85void LJ_FASTCALL lj_profile_interpreter(lua_State *L) 93void LJ_FASTCALL lj_profile_interpreter(lua_State *L)
86{ 94{
87 ProfileState *ps = &profile_state; 95 ProfileState *ps = &profile_state;
88 int samples = ps->samples; 96 global_State *g = G(L);
89 ps->samples = 0; 97 uint8_t mask;
90 ps->cb(ps->data, L, samples, ps->vmstate); /* Invoke user callback. */ 98 profile_lock(ps);
99 mask = (g->hookmask & ~HOOK_PROFILE);
100 if (!(mask & HOOK_VMEVENT)) {
101 int samples = ps->samples;
102 ps->samples = 0;
103 g->hookmask = HOOK_VMEVENT;
104 lj_dispatch_update(g);
105 profile_unlock(ps);
106 ps->cb(ps->data, L, samples, ps->vmstate); /* Invoke user callback. */
107 profile_lock(ps);
108 mask |= (g->hookmask & HOOK_PROFILE);
109 }
110 g->hookmask = mask;
111 lj_dispatch_update(g);
112 profile_unlock(ps);
91} 113}
92 114
93/* Trigger profile hook. Asynchronous call from OS-specific profile timer. */ 115/* Trigger profile hook. Asynchronous call from OS-specific profile timer. */
@@ -95,9 +117,10 @@ static void profile_trigger(ProfileState *ps)
95{ 117{
96 global_State *g = ps->g; 118 global_State *g = ps->g;
97 uint8_t mask; 119 uint8_t mask;
120 profile_lock(ps);
98 ps->samples++; /* Always increment number of samples. */ 121 ps->samples++; /* Always increment number of samples. */
99 mask = g->hookmask; 122 mask = g->hookmask;
100 if (!(mask & HOOK_PROFILE)) { /* Set profile hook, unless already set. */ 123 if (!(mask & (HOOK_PROFILE|HOOK_VMEVENT))) { /* Set profile hook. */
101 int st = g->vmstate; 124 int st = g->vmstate;
102 ps->vmstate = st >= 0 ? 'N' : 125 ps->vmstate = st >= 0 ? 'N' :
103 st == ~LJ_VMST_INTERP ? 'I' : 126 st == ~LJ_VMST_INTERP ? 'I' :
@@ -106,6 +129,7 @@ static void profile_trigger(ProfileState *ps)
106 g->hookmask = (mask | HOOK_PROFILE); 129 g->hookmask = (mask | HOOK_PROFILE);
107 lj_dispatch_update(g); 130 lj_dispatch_update(g);
108 } 131 }
132 profile_unlock(ps);
109} 133}
110 134
111/* -- OS-specific profile timer handling ---------------------------------- */ 135/* -- OS-specific profile timer handling ---------------------------------- */
@@ -170,6 +194,7 @@ static void *profile_thread(ProfileState *ps)
170/* Start profiling timer thread. */ 194/* Start profiling timer thread. */
171static void profile_timer_start(ProfileState *ps) 195static void profile_timer_start(ProfileState *ps)
172{ 196{
197 pthread_mutex_init(&ps->lock, 0);
173 ps->abort = 0; 198 ps->abort = 0;
174 pthread_create(&ps->thread, NULL, (void *(*)(void *))profile_thread, ps); 199 pthread_create(&ps->thread, NULL, (void *(*)(void *))profile_thread, ps);
175} 200}
@@ -179,6 +204,7 @@ static void profile_timer_stop(ProfileState *ps)
179{ 204{
180 ps->abort = 1; 205 ps->abort = 1;
181 pthread_join(ps->thread, NULL); 206 pthread_join(ps->thread, NULL);
207 pthread_mutex_destroy(&ps->lock);
182} 208}
183 209
184#elif LJ_PROFILE_WTHREAD 210#elif LJ_PROFILE_WTHREAD
@@ -218,6 +244,7 @@ static void profile_timer_start(ProfileState *ps)
218 } 244 }
219 } 245 }
220#endif 246#endif
247 InitializeCriticalSection(&ps->lock);
221 ps->abort = 0; 248 ps->abort = 0;
222 ps->thread = CreateThread(NULL, 0, profile_thread, ps, 0, NULL); 249 ps->thread = CreateThread(NULL, 0, profile_thread, ps, 0, NULL);
223} 250}
@@ -227,6 +254,7 @@ static void profile_timer_stop(ProfileState *ps)
227{ 254{
228 ps->abort = 1; 255 ps->abort = 1;
229 WaitForSingleObject(ps->thread, INFINITE); 256 WaitForSingleObject(ps->thread, INFINITE);
257 DeleteCriticalSection(&ps->lock);
230} 258}
231 259
232#endif 260#endif