mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Make Mutex per-Fiber instead of per-Thread
* Enables Mutex to be used as synchronization between multiple Fibers of the same Thread. * With a Fiber scheduler we can yield to another Fiber on contended Mutex#lock instead of blocking the entire thread. * This also makes the behavior of Mutex consistent across CRuby, JRuby and TruffleRuby. * [Feature #16792]
This commit is contained in:
parent
9e0a48c7a3
commit
178c1b0922
Notes:
git
2020-09-14 13:44:37 +09:00
9 changed files with 199 additions and 54 deletions
11
thread.c
11
thread.c
|
@ -75,11 +75,13 @@
|
|||
#include "hrtime.h"
|
||||
#include "internal.h"
|
||||
#include "internal/class.h"
|
||||
#include "internal/cont.h"
|
||||
#include "internal/error.h"
|
||||
#include "internal/hash.h"
|
||||
#include "internal/io.h"
|
||||
#include "internal/object.h"
|
||||
#include "internal/proc.h"
|
||||
#include "internal/scheduler.h"
|
||||
#include "internal/signal.h"
|
||||
#include "internal/thread.h"
|
||||
#include "internal/time.h"
|
||||
|
@ -548,7 +550,7 @@ rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th)
|
|||
/* rb_warn("mutex #<%p> remains to be locked by terminated thread",
|
||||
(void *)mutexes); */
|
||||
mutexes = mutex->next_mutex;
|
||||
err = rb_mutex_unlock_th(mutex, th);
|
||||
err = rb_mutex_unlock_th(mutex, th, mutex->fiber);
|
||||
if (err) rb_bug("invalid keeping_mutexes: %s", err);
|
||||
}
|
||||
}
|
||||
|
@ -5040,7 +5042,7 @@ rb_thread_shield_wait(VALUE self)
|
|||
|
||||
if (!mutex) return Qfalse;
|
||||
m = mutex_ptr(mutex);
|
||||
if (m->th == GET_THREAD()) return Qnil;
|
||||
if (m->fiber == GET_EC()->fiber_ptr) return Qnil;
|
||||
rb_thread_shield_waiting_inc(self);
|
||||
rb_mutex_lock(mutex);
|
||||
rb_thread_shield_waiting_dec(self);
|
||||
|
@ -5540,7 +5542,7 @@ debug_deadlock_check(rb_ractor_t *r, VALUE msg)
|
|||
if (th->locking_mutex) {
|
||||
rb_mutex_t *mutex = mutex_ptr(th->locking_mutex);
|
||||
rb_str_catf(msg, " mutex:%p cond:%"PRIuSIZE,
|
||||
(void *)mutex->th, rb_mutex_num_waiting(mutex));
|
||||
(void *)mutex->fiber, rb_mutex_num_waiting(mutex));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -5574,8 +5576,7 @@ rb_check_deadlock(rb_ractor_t *r)
|
|||
}
|
||||
else if (th->locking_mutex) {
|
||||
rb_mutex_t *mutex = mutex_ptr(th->locking_mutex);
|
||||
|
||||
if (mutex->th == th || (!mutex->th && !list_empty(&mutex->waitq))) {
|
||||
if (mutex->fiber == th->ec->fiber_ptr || (!mutex->fiber && !list_empty(&mutex->waitq))) {
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue