Project

General

Profile

« Previous | Next » 

Revision 3586c9e0

Added by normal almost 7 years ago

reduce rb_mutex_t size from 160 to 80 bytes on 64-bit

Instead of relying on a native condition variable and mutex for
every Ruby Mutex object, use a doubly linked-list to implement a
waiter queue in the Mutex. The immediate benefit of this is
reducing the size of every Mutex object, as some projects have
many objects requiring synchronization.

In the future, this technique using a linked-list and on-stack
list node (struct mutex_waiter) should allow us to easily
transition to M:N threading model, as we can avoid the native
thread dependency to implement Mutex.

We already do something similar for autoload in variable.c,
and this was inspired by the Linux kernel wait queue (as
ccan/list is inspired by the Linux kernel linked-list).

Finaly, there are big performance improvements for Mutex
benchmarks, especially in contended cases:

measure target: real

name trunk built
loop_whileloop2 0.149 0.148
vm2_mutex* 0.893 0.651
vm_thread_mutex1 0.809 0.624
vm_thread_mutex2 2.608 0.628
vm_thread_mutex3 28.227 0.881

Speedup ratio: compare with the result of `trunk' (greater is better)

name built
loop_whileloop2 1.002
vm2_mutex* 1.372
vm_thread_mutex1 1.297
vm_thread_mutex2 4.149
vm_thread_mutex3 32.044

Tested on AMD FX-8320 8-core at 3.5GHz

  • thread_sync.c (struct mutex_waiter): new on-stack struct
    (struct rb_mutex_struct): remove native lock/cond, use ccan/list
    (rb_mutex_num_waiting): new function for debug_deadlock_check
    (mutex_free): remove native_destroy
    (mutex_alloc): initialize waitq, remove native
    initialize
    (rb_mutex_trylock): remove native_mutex
    {lock,unlock}
    (lock_func): remove
    (lock_interrupt): remove
    (rb_mutex_lock): rewrite waiting path to use native_sleep + ccan/list
    (rb_mutex_unlock_th): rewrite to wake up from native_sleep
    using rb_threadptr_interrupt
    (rb_mutex_abandon_all): empty waitq
  • thread.c (debug_deadlock_check): update for new struct
    (rb_check_deadlock): ditto
    [ruby-core:80913] [Feature #13517]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58604 b2dd03c8-39d4-4d8f-98ff-823fe69b080e