diff options
author | Koichi Sasada <[email protected]> | 2020-03-10 02:22:11 +0900 |
---|---|---|
committer | Koichi Sasada <[email protected]> | 2020-09-03 21:11:06 +0900 |
commit | 79df14c04b452411b9d17e26a398e491bca1a811 (patch) | |
tree | 7598cee0f105439efd5bb328a727b0fe27d7c666 /vm_sync.h | |
parent | eeb5325d3bfd71301896360c17e8f51abcb9a7e5 (diff) |
Introduce Ractor mechanism for parallel execution
This commit introduces Ractor mechanism to run Ruby program in
parallel. See doc/ractor.md for more details about Ractor.
See ticket [Feature #17100] to see the implementation details
and discussions.
[Feature #17100]
This commit does not complete the implementation. You can find
many bugs on using Ractor. Also the specification will be changed
so that this feature is experimental. You will see a warning when
you make the first Ractor with `Ractor.new`.
I hope this feature can help programmers from thread-safety issues.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/3365
Diffstat (limited to 'vm_sync.h')
-rw-r--r-- | vm_sync.h | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/vm_sync.h b/vm_sync.h new file mode 100644 index 0000000000..e9cc274bb8 --- /dev/null +++ b/vm_sync.h @@ -0,0 +1,96 @@ + +#ifndef RUBY_VM_SYNC_H +#define RUBY_VM_SYNC_H + +#include "vm_core.h" +#include "vm_debug.h" + +#if USE_RUBY_DEBUG_LOG +#define LOCATION_ARGS const char *file, int line +#define LOCATION_PARAMS file, line +#define APPEND_LOCATION_ARGS , const char *file, int line +#define APPEND_LOCATION_PARAMS , file, line +#else +#define LOCATION_ARGS void +#define LOCATION_PARAMS +#define APPEND_LOCATION_ARGS +#define APPEND_LOCATION_PARAMS +#endif + +bool rb_vm_locked_p(void); +void rb_vm_lock_body(LOCATION_ARGS); +void rb_vm_unlock_body(LOCATION_ARGS); +void rb_vm_lock_enter_body(unsigned int *lev APPEND_LOCATION_ARGS); +void rb_vm_lock_leave_body(unsigned int *lev APPEND_LOCATION_ARGS); +void rb_vm_barrier(void); +void rb_vm_cond_wait(rb_vm_t *vm, rb_nativethread_cond_t *cond); +void rb_vm_cond_timedwait(rb_vm_t *vm, rb_nativethread_cond_t *cond, unsigned long msec); + +extern bool ruby_multi_ractor; + +static inline bool +rb_multi_ractor_p(void) +{ + if (LIKELY(!ruby_multi_ractor)) { + // 0 on boot time. + VM_ASSERT(GET_VM()->ractor.cnt <= 1); + return false; + } + else { + // multi-ractor mode can run ractor.cnt == 1 + return true; + } +} + +static inline void +rb_vm_lock(const char *file, int line) +{ + if (rb_multi_ractor_p()) { + rb_vm_lock_body(LOCATION_PARAMS); + } +} + +static inline void +rb_vm_unlock(const char *file, int line) +{ + if (rb_multi_ractor_p()) { + rb_vm_unlock_body(LOCATION_PARAMS); + } +} + +static inline void +rb_vm_lock_enter(unsigned int *lev, const char *file, int line) +{ + if (rb_multi_ractor_p()) { + rb_vm_lock_enter_body(lev APPEND_LOCATION_PARAMS); + } +} + +static inline void +rb_vm_lock_leave(unsigned int *lev, const char *file, int line) +{ + if (rb_multi_ractor_p()) { + rb_vm_lock_leave_body(lev APPEND_LOCATION_PARAMS); + } +} + +#define RB_VM_LOCKED_P() rb_vm_locked_p() + +#define RB_VM_LOCK() rb_vm_lock(__FILE__, __LINE__) +#define RB_VM_UNLOCK() rb_vm_unlock(__FILE__, __LINE__) + +#define RB_VM_LOCK_ENTER_LEV(levp) rb_vm_lock_enter(levp, __FILE__, __LINE__); +#define RB_VM_LOCK_LEAVE_LEV(levp) rb_vm_lock_leave(levp, __FILE__, __LINE__); + +#define RB_VM_LOCK_ENTER() { unsigned int _lev; RB_VM_LOCK_ENTER_LEV(&_lev); +#define RB_VM_LOCK_LEAVE() RB_VM_LOCK_LEAVE_LEV(&_lev); } + +#if VM_CHECK_MODE > 0 +void ASSERT_vm_locking(void); +void ASSERT_vm_unlocking(void); +#else +#define ASSERT_vm_locking() +#define ASSERT_vm_unlocking() +#endif + +#endif // RUBY_VM_SYNC_H |