summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-09-05 16:26:24 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-09-14 16:44:09 +1200
commit178c1b0922dc727897d81d7cfe9c97d5ffa97fd9 (patch)
tree113600e7e6a196b779bcac7529535597858f78a7 /thread.c
parent9e0a48c7a31ecd39be0596d0517b9d521ae75282 (diff)
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]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3434
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c11
1 files changed, 6 insertions, 5 deletions
diff --git a/thread.c b/thread.c
index d0ebfff882..c4ff5aafde 100644
--- a/thread.c
+++ b/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;
}
}