1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

vm_trace.c: MJIT-limited thread-safety for postponed_job

[Bug #15316]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66001 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
k0kubun 2018-11-26 15:47:20 +00:00
parent 01e2bf35bc
commit 67485fee42
3 changed files with 22 additions and 1 deletions

14
mjit.c
View file

@ -106,6 +106,20 @@ mjit_gc_finish_hook(void)
CRITICAL_SECTION_FINISH(4, "mjit_gc_finish_hook");
}
/* Wrap critical section to prevent [Bug #15316] */
void
mjit_postponed_job_register_start_hook(void)
{
CRITICAL_SECTION_START(4, "mjit_postponed_job_register_start_hook");
}
/* Unwrap critical section of mjit_postponed_job_register_start_hook() */
void
mjit_postponed_job_register_finish_hook(void)
{
CRITICAL_SECTION_FINISH(4, "mjit_postponed_job_register_finish_hook");
}
/* Iseqs can be garbage collected. This function should call when it
happens. It removes iseq from the unit. */
void

4
mjit.h
View file

@ -66,6 +66,8 @@ RUBY_SYMBOL_EXPORT_END
extern int mjit_compile(FILE *f, const struct rb_iseq_constant_body *body, const char *funcname, struct rb_call_cache *cc_entries, union iseq_inline_storage_entry *is_entries);
extern void mjit_init(struct mjit_options *opts);
extern void mjit_postponed_job_register_start_hook(void);
extern void mjit_postponed_job_register_finish_hook(void);
extern void mjit_gc_start_hook(void);
extern void mjit_gc_finish_hook(void);
extern void mjit_free_iseq(const rb_iseq_t *iseq);
@ -131,6 +133,8 @@ void mjit_child_after_fork(void);
#else /* USE_MJIT */
static inline struct mjit_cont *mjit_cont_new(rb_execution_context_t *ec){return NULL;}
static inline void mjit_cont_free(struct mjit_cont *cont){}
static inline void mjit_postponed_job_register_start_hook(void){}
static inline void mjit_postponed_job_register_finish_hook(void){}
static inline void mjit_gc_start_hook(void){}
static inline void mjit_gc_finish_hook(void){}
static inline void mjit_free_iseq(const rb_iseq_t *iseq){}

View file

@ -1588,7 +1588,7 @@ enum postponed_job_register_result {
PJRR_INTERRUPTED = 2
};
/* Async-signal-safe */
/* Async-signal-safe, thread-safe against MJIT worker thread */
static enum postponed_job_register_result
postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
unsigned int flags, rb_postponed_job_func_t func, void *data, int max, int expected_index)
@ -1596,11 +1596,13 @@ postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
rb_postponed_job_t *pjob;
if (expected_index >= max) return PJRR_FULL; /* failed */
if (mjit_enabled) mjit_postponed_job_register_start_hook();
if (ATOMIC_CAS(vm->postponed_job_index, expected_index, expected_index+1) == expected_index) {
pjob = &vm->postponed_job_buffer[expected_index];
}
else {
if (mjit_enabled) mjit_postponed_job_register_finish_hook();
return PJRR_INTERRUPTED;
}
@ -1609,6 +1611,7 @@ postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
pjob->data = data;
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec);
if (mjit_enabled) mjit_postponed_job_register_finish_hook();
return PJRR_SUCCESS;
}