* vm_trace.c (postponed_job): use preallocated buffer.
Pre-allocate MAX_POSTPONED_JOB (1024) sized buffer and use it. If rb_postponed_job_register() cause overflow, simply it fails and returns 0. And maybe rb_postponed_job_register() is signal safe. * vm_core.h: change data structure. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43234 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3d3a0d88c9
commit
fa7bf880b4
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Thu Oct 10 13:52:37 2013 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* vm_trace.c (postponed_job): use preallocated buffer.
|
||||||
|
Pre-allocate MAX_POSTPONED_JOB (1024) sized buffer
|
||||||
|
and use it.
|
||||||
|
If rb_postponed_job_register() cause overflow, simply it
|
||||||
|
fails and returns 0.
|
||||||
|
And maybe rb_postponed_job_register() is signal safe.
|
||||||
|
|
||||||
|
* vm_core.h: change data structure.
|
||||||
|
|
||||||
Thu Oct 10 11:11:33 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Oct 10 11:11:33 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* vm.c (Init_VM): hide also the singleton class of frozen-core, not
|
* vm.c (Init_VM): hide also the singleton class of frozen-core, not
|
||||||
|
@ -389,7 +389,9 @@ typedef struct rb_vm_struct {
|
|||||||
/* hook */
|
/* hook */
|
||||||
rb_hook_list_t event_hooks;
|
rb_hook_list_t event_hooks;
|
||||||
|
|
||||||
struct rb_postponed_job_struct *postponed_job;
|
/* postponed_job */
|
||||||
|
struct rb_postponed_job_struct *postponed_job_buffer;
|
||||||
|
int postponed_job_index;
|
||||||
|
|
||||||
int src_encoding_index;
|
int src_encoding_index;
|
||||||
|
|
||||||
|
67
vm_trace.c
67
vm_trace.c
@ -1280,6 +1280,8 @@ tracepoint_inspect(VALUE self)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Init_postponed_job(void);
|
||||||
|
|
||||||
/* This function is called from inits.c */
|
/* This function is called from inits.c */
|
||||||
void
|
void
|
||||||
Init_vm_trace(void)
|
Init_vm_trace(void)
|
||||||
@ -1370,33 +1372,54 @@ Init_vm_trace(void)
|
|||||||
rb_define_method(rb_cTracePoint, "self", tracepoint_attr_self, 0);
|
rb_define_method(rb_cTracePoint, "self", tracepoint_attr_self, 0);
|
||||||
rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0);
|
rb_define_method(rb_cTracePoint, "return_value", tracepoint_attr_return_value, 0);
|
||||||
rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0);
|
rb_define_method(rb_cTracePoint, "raised_exception", tracepoint_attr_raised_exception, 0);
|
||||||
|
|
||||||
|
/* initialized for postponed job */
|
||||||
|
|
||||||
|
Init_postponed_job();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct rb_postponed_job_struct {
|
typedef struct rb_postponed_job_struct {
|
||||||
unsigned long flags; /* reserve */
|
unsigned long flags; /* reserved */
|
||||||
rb_thread_t *th; /* created thread, reserve */
|
struct rb_thread_struct *th; /* created thread, reserved */
|
||||||
rb_postponed_job_func_t func;
|
rb_postponed_job_func_t func;
|
||||||
void *data;
|
void *data;
|
||||||
struct rb_postponed_job_struct *next;
|
|
||||||
} rb_postponed_job_t;
|
} rb_postponed_job_t;
|
||||||
|
|
||||||
|
#define MAX_POSTPONED_JOB 1024
|
||||||
|
|
||||||
|
static void
|
||||||
|
Init_postponed_job(void)
|
||||||
|
{
|
||||||
|
rb_vm_t *vm = GET_VM();
|
||||||
|
vm->postponed_job_buffer = ALLOC_N(rb_postponed_job_t, MAX_POSTPONED_JOB);
|
||||||
|
vm->postponed_job_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return 0 if job buffer is full */
|
||||||
int
|
int
|
||||||
rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data)
|
rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data)
|
||||||
{
|
{
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
rb_vm_t *vm = th->vm;
|
rb_vm_t *vm = th->vm;
|
||||||
rb_postponed_job_t *pjob = (rb_postponed_job_t *)ruby_xmalloc(sizeof(rb_postponed_job_t));
|
rb_postponed_job_t *pjob;
|
||||||
if (pjob == NULL) return 0; /* failed */
|
|
||||||
|
while (1) {
|
||||||
|
int index = vm->postponed_job_index;
|
||||||
|
if (index >= MAX_POSTPONED_JOB) return 0; /* failed */
|
||||||
|
|
||||||
|
if (ATOMIC_CAS(vm->postponed_job_index, index, index+1) == index) {
|
||||||
|
pjob = &vm->postponed_job_buffer[index];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pjob->flags = flags;
|
pjob->flags = flags;
|
||||||
pjob->th = th;
|
pjob->th = th;
|
||||||
pjob->func = func;
|
pjob->func = func;
|
||||||
pjob->data = data;
|
pjob->data = data;
|
||||||
|
|
||||||
pjob->next = vm->postponed_job;
|
|
||||||
vm->postponed_job = pjob;
|
|
||||||
|
|
||||||
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th);
|
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(th);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1404,13 +1427,15 @@ int
|
|||||||
rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data)
|
rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data)
|
||||||
{
|
{
|
||||||
rb_vm_t *vm = GET_VM();
|
rb_vm_t *vm = GET_VM();
|
||||||
rb_postponed_job_t *pjob = vm->postponed_job;
|
rb_postponed_job_t *pjob;
|
||||||
|
int i;
|
||||||
|
|
||||||
while (pjob) {
|
/* TODO: this check is not signal safe, but I believe this is not critical prbolem */
|
||||||
|
for (i=0; i<vm->postponed_job_index; i++) {
|
||||||
|
pjob = &vm->postponed_job_buffer[i];
|
||||||
if (pjob->func == func) {
|
if (pjob->func == func) {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
pjob = pjob->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rb_postponed_job_register(flags, func, data);
|
return rb_postponed_job_register(flags, func, data);
|
||||||
@ -1419,13 +1444,19 @@ rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func,
|
|||||||
void
|
void
|
||||||
rb_postponed_job_flush(rb_vm_t *vm)
|
rb_postponed_job_flush(rb_vm_t *vm)
|
||||||
{
|
{
|
||||||
rb_postponed_job_t *pjob = vm->postponed_job, *next_pjob;
|
rb_postponed_job_t *pjob;
|
||||||
vm->postponed_job = 0;
|
|
||||||
|
|
||||||
while (pjob) {
|
while (1) {
|
||||||
next_pjob = pjob->next;
|
int index = vm->postponed_job_index;
|
||||||
pjob->func(pjob->data);
|
|
||||||
ruby_xfree(pjob);
|
if (index <= 0) {
|
||||||
pjob = next_pjob;
|
return; /* finished */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ATOMIC_CAS(vm->postponed_job_index, index, index-1) == index) {
|
||||||
|
pjob = &vm->postponed_job_buffer[index-1];
|
||||||
|
/* do postponed job */
|
||||||
|
pjob->func(pjob->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user