(1) add rb_hook_list_t data structure which includes
hooks, events (flag) and `need_clean' flag.
If the last flag is true, then clean the hooks list.
In other words, deleted hooks are contained by `hooks'.
Cleanup process should run before traversing the list.
(2) Change check mechanism
See EXEC_EVENT_HOOK() in vm_core.h.
(3) Add `raw' hooks APIs
Normal hooks are guarded from exception by rb_protect().
However, this protection is overhead for too simple
functions which never cause exceptions. `raw' hooks
are executed without protection and faster.
Now, we only provide registration APIs. All `raw'
hooks are kicked under protection (same as normal hooks).
* include/ruby/ruby.h: remove internal data definition and
macros.
* internal.h (ruby_suppress_tracing), vm_trace.c: rename
ruby_suppress_tracing() to rb_suppress_tracing()
and remove unused function parameter.
* parse.y: fix to use renamed rb_suppress_tracing().
* thread.c (thread_create_core): no need to set RUBY_VM_VM.
* vm.c (mark_event_hooks): move definition to vm_trace.c.
* vm.c (ruby_vm_event_flags): add a global variable.
This global variable represents all of Threads and VM's
event masks (T1#events | T2#events | ... | VM#events).
You can check the possibility kick trace func or not
with ruby_vm_event_flags.
ruby_vm_event_flags is maintained by vm_trace.c.
* cont.c (fiber_switch, rb_cont_call): restore tracing status.
[Feature #4347]
* test/ruby/test_continuation.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36715 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_thread_s_check_interrupt): added for
Thread.control_intgerrupt and Thread.check_interrupt.
See details on rdoc.
I'll make an ticket for this feature.
* test/ruby/test_thread.rb: add a test for Thread.control_intgerrupt.
* thread.c (rb_threadptr_raise): make a new exception object
even if argc is 0.
* thread.c (rb_thread_kill): kill thread immediately if target thread
is current thread.
* vm_core.h (RUBY_VM_CHECK_INTS_BLOCKING): added.
CHECK_INTS while/after blocking operation.
* vm_core.h (RUBY_VM_CHECK_INTS): require rb_thread_t ptr.
* cont.c (fiber_switch): use replaced RUBY_VM_CHECK_INTS().
* eval.c (ruby_cleanup): ditto.
* insns.def: ditto.
* process.c (rb_waitpid): ditto.
* vm_eval.c (vm_call0): ditto.
* vm_insnhelper.c (vm_call_method): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36470 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Async events such as an exception throwed by Thread#raise,
Thread#kill and thread termination (after main thread termination)
will be queued to th->async_errinfo_queue.
- clear: clear the queue.
- enque: enque err object into queue.
- deque: deque err object from queue.
- active_p: return 1 if the queue should be checked.
rb_thread_t#thrown_errinfo was removed.
* vm_core.h: add declarations of rb_threadptr_async_errinfo_*.
remove rb_thread_t#thrown_errinfo field and
add rb_thread_t#async_errinfo_queue (queue body: Array),
rb_thread_t#async_errinfo_queue_checked (flag),
rb_thread_t#async_errinfo_mask_stack(Array, not used yet).
* vm.c (rb_thread_mark): fix a mark function.
* cont.c (rb_fiber_start): enque an error.
* process.c (after_fork): clear async errinfo queue.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36430 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
dfp (dynamic frame pointer) to ep (environment pointer).
This change make VM `normal' (similar to other interpreters).
Before this commit:
Each frame has two env pointers lfp and dfp. lfp points
local environment which is method/class/toplevel frame.
lfp[0] is block pointer.
dfp is block local frame. dfp[0] points previous (parent)
environment pointer.
lfp == dfp when frame is method/class/toplevel.
You can get lfp from dfp by traversing previous environment
pointers.
After this commit:
Each frame has only `ep' to point respective enviornoment.
If there is parent environment, then ep[0] points parent
envioenment (as dfp). If there are no more environment,
then ep[0] points block pointer (as lfp). We call such ep
as `LEP' (local EP). We add some macros to get LEP and to
detect LEP or not.
In short, we replace dfp and lfp with ep and LEP.
rb_block_t and rb_binding_t member `lfp' and `dfp' are removed
and member `ep' is added.
rename rb_thread_t's member `local_lfp' and `local_svar' to
`root_lep' and `root_svar'.
(VM_EP_PREV_EP(ep)): get previous environment pointer. This macro
assume that ep is not LEP.
(VM_EP_BLOCK_PTR(ep)): get block pointer. This macro assume
that ep is LEP.
(VM_EP_LEP_P(ep)): detect ep is LEP or not.
(VM_ENVVAL_BLOCK_PTR(ptr)): make block pointer.
(VM_ENVVAL_BLOCK_PTR_P(v)): detect v is block pointer.
(VM_ENVVAL_PREV_EP_PTR(ptr)): make prev environment pointer.
(VM_ENVVAL_PREV_EP_PTR_P(v)): detect v is prev env pointer.
* vm.c: apply above changes.
(VM_EP_LEP(ep)): get LEP.
(VM_CF_LEP(cfp)): get LEP of cfp->ep.
(VM_CF_PREV_EP(cfp)): utility function VM_EP_PREV_EP(cfp->ep).
(VM_CF_BLOCK_PTR(cfp)): utility function VM_EP_BLOCK_PTR(cfp->ep).
* vm.c, vm_eval.c, vm_insnhelper.c, vm_insnhelper.h, insns.def:
apply above changes.
* cont.c: ditto.
* eval.c, eval_intern.h: ditto.
* proc.c: ditto.
* thread.c: ditto.
* vm_dump.c: ditto.
* vm_exec.h: fix function name (on vm debug mode).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36030 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
documentation. emphasize the difference between transfer and resume.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35521 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
restore rb_thread_t::local_storage.
* cont.c (rb_obj_is_fiber): add a new function to tell finalizer to
prevent fibers from destroy.
* gc.c (rb_objspace_call_finalizer): don't sweep fibers at finalizing
objspace.
* internal.h (rb_fiber_reset_root_local_storage, rb_obj_is_fiber):
add prototypes.
* vm.c (ruby_vm_destruct): reset main thread's local_storage before
free main thread. rb_thread_t::local_storage is replaced by fiber's
local storage when forked from fiber, and it should be already freed
when the fiber was destroyed.
* test/ruby/test_fiber.rb (test_fork_from_fiber): add test for fork
from fiber.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34629 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
reserving a memory space with ALLOCA_N for restoring machine stack
stored in cont->machine_stack, but clang optimized out it (and
maybe #5851 is also caused by this).
This affected TestContinuation#test_check_localvars.
* cont.c (cont_restore_1): revert workaround introduced in r32201.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34278 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because destination fiber is same as current fiber.
With out this, it may segv on FreeBSD 9.
patched by Koichi Sasada.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33804 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
"resume" after "transfer" method are used. You should not mix
"resume" fiber and "transfer" fiber.
[Bug #5526]
* NEWS: add information about this change.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
be marked by itself. Patch by Koichi Sasada.
[ruby-dev:44567] [Bug #5386]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33371 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
guard page should have PROT_NONE.
* cont.c (fiber_initialize_machine_stack_context):
th->machine_stack_maxsize shouldn't be included guard pages size.
[Bug #4983][ruby-dev:44043]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32421 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Fiber caused SEGV. I haven't follow up the issue deeply, but it
works when disabling the feature.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
On clang -O, it is needed to avoid the optimization.
With this and llvm/clang's recent fix, clang 3.0 can
build ruby-trunk with -O option.
* cont.c (cont_capture): use for-loop.
* array.c (rb_ary_each): add volatile and use it.
* vm_insnhelper.c (vm_call_cfunc): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_context_t::saved_thread.machine_stack_start and
machine_stack_end should be cleared immediately after a snapshot of
current thread is stored to saved_thread.
this change aims to get rid of unnecessary GC mark at machine stack.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
in cont_mark() only RUNNING fiber's machine stack is marked.
root fiber's status should be RUNNING at the beginning regardless of
FIBER_USE_NATIVE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31954 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
you can suppress use of setcontext for Fiber with compile option
-DFIBER_USE_NATIVE=0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31944 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
prevent mark machine stack of GC'ed Thread. root Fiber is not initialized by
fiber_init(). based on a patch by Serge Balyuk [ruby-core:35891] fixes#4612
* test/ruby/test_fiber.rb (test_gc_root_fiber): add test for it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31577 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
unnecessary fibers and retry to create. based on a patch from
masaya tarui at [ruby-dev:41230].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27701 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
on Windows because Fiber APIs are supported only such building
(and running) environments.
[ruby-dev:41192]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27646 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Fiber context switching cost using system APIs. Detail comments
are written in cont.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
added. Unlinked method entries are collected to
vm->unlinked_method_entry_list. On the GC timing, mark all method
entries which are on all living threads. Only non-marked method
entries are collected. This hack prevents releasing living method
entry.
[Performance Consideration] Since this Method Entry GC (MEGC)
doesn't occuer frequently, MEGC will not be a performance bottleneck.
However, to traverse living method entries, every control frame push
needs to clear cfp->me field. This will be a performance issue
(because pushing control frame is occurred frequently).
Bug #2777 [ruby-dev:40457]
* cont.c (fiber_init): init cfp->me.
* gc.c (garbage_collect): kick rb_sweep_method_entry().
* method.h (rb_method_entry_t): add a mark field.
* vm.c (invoke_block_from_c): set passed me.
* vm.c (rb_thread_mark): mark cfp->me.
* vm_core.h (rb_thread_t): add a field passed_me.
* vm_core.h (rb_vm_t): add a field unlinked_method_entry_list.
* vm_insnhelper.c (vm_push_frame): clear cfp->me at all times.
* vm_insnhelper.c (vm_call_bmethod): pass me.
* bootstraptest/test_method.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@27634 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
it seems not to make sense. [ruby-dev:40121]
* vm_core.h, eval.c (rb_protect): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26407 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_init): clear local_storage not to use current thread's.
* cont.c (fiber_t_alloc, root_fiber_alloc): link itself always for
a case that fiber_link_remove() is called before fiber_link_join().
* cont.c (fiber_init): clear cont->vm_stack and th->stack before
root_fiber_alloc() in rb_fiber_current().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_init): clear local_storage not to use current thread's.
* cont.c (fiber_t_alloc, root_fiber_alloc): link itself always for
a case that fiber_link_remove() is called before fiber_link_join().
* cont.c (fiber_init): don't join half-baked fiber.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25623 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (fiber_switch): transfers dead fiber error to the previouse
or root fiber if the current fiber is dead. [ruby-core:23651]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23616 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
[ruby-dev:37991]
* test/ruby/test_fiber.rb: add a test for Fiber#alive?
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22274 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
of #elif. a patch from NISHIMATSU Takeshi <t_nissie at yahoo.co.jp>
in [ruby-list:45856].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22081 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
vm_get_ruby_level_next_cfp(), rb_vm_make_env_object(),
vm_stack_to_heap(), vm_make_proc(), vm_invoke_proc(),
vm_get_sourceline(), vm_cref(), vm_localjump_error(),
vm_make_jump_tag_but_local_jump(), vm_jump_tag_but_local_jump().
This changes may affect only core because most of renamed functions
require a pointer of not-exposed struct such as rb_thread_t or NODE.
In short, they are core functions.
* cont.c, eval.c, eval_intern.h, load.c, proc.c, thread.c,
vm_core.h, vm_dump.c, vm_eval.c, vm_exec.c, vm_insnhelper.c:
ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
vm_insnhelper.h (BOP): ISO C forbids comma at end of enumerator
list.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20591 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_context_t (rb_fiber_t includes rb_context_t).
rb_fiber_t has double linked list of fibers in same threads.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19890 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
RUBY_VM_SET_TIMER_INTERRUPT(), RUBY_VM_INTERRUPTED().
* thread.c, thread_pthread.c, thread_win32.c: fix to ignore time slice
event until sleep.
* bootstraptest/test_thread.rb: add a test for time limited join test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
suppress warnings.
* cont.c (rb_fiber_start): change on non-volatile variable between
setjmp and longjmp may not has an effect.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13237 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
and Fiber::Core class to realize Coroutine.
* include/ruby/intern.h: declare rb_fiber_yield(), rb_fiber_resume(),
* enumerator.c: use above api.
* test/ruby/test_fiber.rb: fix and add tests for above changes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13130 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (rb_fiber_current): export
* include/ruby/intern.h: export several functions from cont.c.
* enumerator.c (enumerator_next): new method to implement external
iterator (generator) using fiber.
* enumerator.c (enumerator_next_p): new method to check whether
any element is left in the generator sequence.
* enumerator.c (enumerator_rewind): a new method to rewind the
generator sequence.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12891 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* gc.h (SET_MACHINE_STACK_END): new macro to replace
rb_gc_set_stack_end. it find out accurate stack boundary by
asm using gcc on x86.
* thread.c (rb_gc_set_stack_end): don't define if asm-version
SET_MACHINE_STACK_END is available.
* gc.c (mark_current_thread): extracted from garbage_collect.
it use SET_MACHINE_STACK_END to not scan out of stack area.
it notify conservative GC information to valgrind if
--enable-valgrind.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12785 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* yarvcore.c (th_init2): ditto.
* vm.c, vm.h: fix to stop using Qundef on VM stack. According to
this change, VM stack should not include Qundef value.
* insns.def (putundef): removed.
* compile.c (iseq_compile_each): ditto.
* eval.c (eval): fix spacing.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12621 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
to avoid GC problem in very early stage.
(RUBY_GC_STRESS causes GC in such stage.)
* variable.c (rb_gc_mark_global_tbl): rb_global_tbl may be 0 in
very early stage.
* thread.c (thread_cleanup_func) [IA64]: clear register stack position.
(thread_start_func_2) [IA64]: record the beginning of register
stack using extra argument.
(rb_gc_save_machine_context) [IA64]: record the end of register
stack.
* gc.c [IA64] (SET_STACK_END): record the end of register stack.
(garbage_collect) [IA64]: use recorded register stack area for
GC marking.
(yarv_machine_stack_mark) [IA64]: GC mark from the register stack
area.
* yarvcore.c [IA64] (rb_gc_register_stack_start): defined.
(Init_VM): store th->self on stack to fix GC problem.
(Init_yarv) [IA64]: initialize the beginning of register stack.
* yarvcore.h (struct rb_thread_struct) [IA64]: new members for
register stack area.
* thread_pthread.ci (thread_start_func_1) [IA64]: call
thread_start_func_2 with the end of register stack.
* cont.c (struct rb_context_struct) [IA64]: new members for register
stack area.
(cont_mark) [IA64]: GC mark from register stack area.
(cont_free) [IA64]: free saved register stack.
(cont_save_machine_stack) [IA64]: record the position and contents
of the register stack.
(cont_capture): store cont->self on stack to fix GC problem.
(cont_restore_1) [IA64]: restore the register stack.
[IA64] (register_stack_extend): new function.
(cont_restore_0) [IA64]: call register_stack_extend instead of
cont_restore_1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12537 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (cont_restore_1): copy stack information from fiber.
* cont.c (rb_fiber_s_new): fix to mark created fiber.
* test/ruby/test_fiber.rb: add some tests around Thread and Fiber.
* yarvcore.c (thread_free): fix to skip freeing stack if root fiber
is available.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12454 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
of fiber body receive first yield values.
e.g.: Fiber.new{|x| p x}.yield(:ok) #=> :ok
* cont.c: rename rb_context_t#retval to rb_context_t#value.
* test/ruby/test_fiber.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12425 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Fiber is known as "Micro Thread", "Coroutine", and other terms.
At this time, only Fiber#pass is supported to change context.
I want to know more suitable method name/API for Fiber (... do you
know more suitable class name instead of Fiber?) as "suspend/resume",
"call", "yield", "start/kick/stop/restart", ....
* eval.c, eval_intern.h, thread.c, yarvcore.c, yarvcore.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12395 b2dd03c8-39d4-4d8f-98ff-823fe69b080e