Misc #14497 ยป 0001-thread-all-condvars-are-monotonic.patch
| mjit.c | ||
|---|---|---|
|
extern void rb_native_mutex_initialize(rb_nativethread_lock_t *lock);
|
||
|
extern void rb_native_mutex_destroy(rb_nativethread_lock_t *lock);
|
||
|
extern void rb_native_cond_initialize(rb_nativethread_cond_t *cond, int flags);
|
||
|
extern void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
|
||
|
extern void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
|
||
|
extern void rb_native_cond_signal(rb_nativethread_cond_t *cond);
|
||
|
extern void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
|
||
| ... | ... | |
|
/* Initialize mutex */
|
||
|
rb_native_mutex_initialize(&mjit_engine_mutex);
|
||
|
rb_native_cond_initialize(&mjit_pch_wakeup, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&mjit_client_wakeup, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&mjit_worker_wakeup, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&mjit_gc_wakeup, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&mjit_pch_wakeup);
|
||
|
rb_native_cond_initialize(&mjit_client_wakeup);
|
||
|
rb_native_cond_initialize(&mjit_worker_wakeup);
|
||
|
rb_native_cond_initialize(&mjit_gc_wakeup);
|
||
|
/* Initialize class_serials cache for compilation */
|
||
|
valid_class_serials = rb_hash_new();
|
||
| thread_pthread.c | ||
|---|---|---|
|
void rb_native_cond_signal(rb_nativethread_cond_t *cond);
|
||
|
void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
|
||
|
void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
|
||
|
void rb_native_cond_initialize(rb_nativethread_cond_t *cond, int flags);
|
||
|
void rb_native_cond_initialize(rb_nativethread_cond_t *cond);
|
||
|
void rb_native_cond_destroy(rb_nativethread_cond_t *cond);
|
||
|
static void rb_thread_wakeup_timer_thread_low(void);
|
||
|
static struct {
|
||
| ... | ... | |
|
} timer_thread;
|
||
|
#define TIMER_THREAD_CREATED_P() (timer_thread.created != 0)
|
||
|
#define RB_CONDATTR_CLOCK_MONOTONIC 1
|
||
|
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(HAVE_CLOCKID_T) && \
|
||
|
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
|
||
|
defined(CLOCK_REALTIME) && defined(CLOCK_MONOTONIC) && \
|
||
|
defined(HAVE_CLOCK_GETTIME)
|
||
|
#define USE_MONOTONIC_COND 1
|
||
|
static pthread_condattr_t mono_condattr;
|
||
|
static pthread_condattr_t *const monotonic = &mono_condattr;
|
||
|
#else
|
||
|
#define USE_MONOTONIC_COND 0
|
||
|
static const void *monotonic;
|
||
|
#endif
|
||
|
#if defined(HAVE_POLL) && defined(HAVE_FCNTL) && defined(F_GETFL) && defined(F_SETFL) && defined(O_NONBLOCK)
|
||
| ... | ... | |
|
gvl_init(rb_vm_t *vm)
|
||
|
{
|
||
|
rb_native_mutex_initialize(&vm->gvl.lock);
|
||
|
rb_native_cond_initialize(&vm->gvl.cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&vm->gvl.switch_cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&vm->gvl.switch_wait_cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&vm->gvl.cond);
|
||
|
rb_native_cond_initialize(&vm->gvl.switch_cond);
|
||
|
rb_native_cond_initialize(&vm->gvl.switch_wait_cond);
|
||
|
vm->gvl.acquired = 0;
|
||
|
vm->gvl.waiting = 0;
|
||
|
vm->gvl.need_yield = 0;
|
||
| ... | ... | |
|
}
|
||
|
void
|
||
|
rb_native_cond_initialize(rb_nativethread_cond_t *cond, int flags)
|
||
|
rb_native_cond_initialize(rb_nativethread_cond_t *cond)
|
||
|
{
|
||
|
int r;
|
||
|
# if USE_MONOTONIC_COND
|
||
|
pthread_condattr_t attr;
|
||
|
pthread_condattr_init(&attr);
|
||
|
cond->clockid = CLOCK_REALTIME;
|
||
|
if (flags & RB_CONDATTR_CLOCK_MONOTONIC) {
|
||
|
r = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
||
|
if (r == 0) {
|
||
|
cond->clockid = CLOCK_MONOTONIC;
|
||
|
}
|
||
|
}
|
||
|
r = pthread_cond_init(&cond->cond, &attr);
|
||
|
pthread_condattr_destroy(&attr);
|
||
|
# else
|
||
|
r = pthread_cond_init(&cond->cond, NULL);
|
||
|
# endif
|
||
|
int r = pthread_cond_init(cond, monotonic);
|
||
|
if (r != 0) {
|
||
|
rb_bug_errno("pthread_cond_init", r);
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
void
|
||
|
rb_native_cond_destroy(rb_nativethread_cond_t *cond)
|
||
|
{
|
||
|
int r = pthread_cond_destroy(&cond->cond);
|
||
|
int r = pthread_cond_destroy(cond);
|
||
|
if (r != 0) {
|
||
|
rb_bug_errno("pthread_cond_destroy", r);
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
int r;
|
||
|
do {
|
||
|
r = pthread_cond_signal(&cond->cond);
|
||
|
r = pthread_cond_signal(cond);
|
||
|
} while (r == EAGAIN);
|
||
|
if (r != 0) {
|
||
|
rb_bug_errno("pthread_cond_signal", r);
|
||
| ... | ... | |
|
{
|
||
|
int r;
|
||
|
do {
|
||
|
r = pthread_cond_broadcast(&cond->cond);
|
||
|
r = pthread_cond_broadcast(cond);
|
||
|
} while (r == EAGAIN);
|
||
|
if (r != 0) {
|
||
|
rb_bug_errno("rb_native_cond_broadcast", r);
|
||
| ... | ... | |
|
void
|
||
|
rb_native_cond_wait(rb_nativethread_cond_t *cond, pthread_mutex_t *mutex)
|
||
|
{
|
||
|
int r = pthread_cond_wait(&cond->cond, mutex);
|
||
|
int r = pthread_cond_wait(cond, mutex);
|
||
|
if (r != 0) {
|
||
|
rb_bug_errno("pthread_cond_wait", r);
|
||
|
}
|
||
| ... | ... | |
|
* Let's hide it from arch generic code.
|
||
|
*/
|
||
|
do {
|
||
|
r = pthread_cond_timedwait(&cond->cond, mutex, ts);
|
||
|
r = pthread_cond_timedwait(cond, mutex, ts);
|
||
|
} while (r == EINTR);
|
||
|
if (r != 0 && r != ETIMEDOUT) {
|
||
| ... | ... | |
|
{
|
||
|
struct timespec abs;
|
||
|
#if USE_MONOTONIC_COND
|
||
|
if (cond->clockid == CLOCK_MONOTONIC) {
|
||
|
getclockofday(&abs);
|
||
|
goto out;
|
||
|
if (monotonic) {
|
||
|
getclockofday(&abs);
|
||
|
}
|
||
|
else {
|
||
|
rb_timespec_now(&abs);
|
||
|
}
|
||
|
if (cond->clockid != CLOCK_REALTIME)
|
||
|
rb_bug("unsupported clockid %"PRIdVALUE, (SIGNED_VALUE)cond->clockid);
|
||
|
#endif
|
||
|
rb_timespec_now(&abs);
|
||
|
#if USE_MONOTONIC_COND
|
||
|
out:
|
||
|
#endif
|
||
|
timespec_add(&abs, &timeout_rel);
|
||
|
return abs;
|
||
| ... | ... | |
|
void
|
||
|
Init_native_thread(rb_thread_t *th)
|
||
|
{
|
||
|
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
|
||
|
if (monotonic) {
|
||
|
int r = pthread_condattr_setclock(monotonic, CLOCK_MONOTONIC);
|
||
|
if (r) rb_bug_errno("pthread_condattr_setclock", r);
|
||
|
}
|
||
|
#endif
|
||
|
pthread_key_create(&ruby_native_thread_key, NULL);
|
||
|
th->thread_id = pthread_self();
|
||
|
fill_thread_id_str(th);
|
||
| ... | ... | |
|
#ifdef USE_UBF_LIST
|
||
|
list_node_init(&nd->ubf_list);
|
||
|
#endif
|
||
|
rb_native_cond_initialize(&nd->sleep_cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&nd->sleep_cond);
|
||
|
ruby_thread_set_native(th);
|
||
|
}
|
||
| ... | ... | |
|
struct timespec end = { 60, 0 };
|
||
|
struct cached_thread_entry entry;
|
||
|
rb_native_cond_initialize(&entry.cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&entry.cond);
|
||
|
entry.th = NULL;
|
||
|
entry.thread_id = thread_self_id;
|
||
|
end = native_cond_timeout(&entry.cond, end);
|
||
| ... | ... | |
|
#if !USE_SLEEPY_TIMER_THREAD
|
||
|
rb_native_mutex_initialize(&timer_thread_lock);
|
||
|
rb_native_cond_initialize(&timer_thread_cond, RB_CONDATTR_CLOCK_MONOTONIC);
|
||
|
rb_native_cond_initialize(&timer_thread_cond);
|
||
|
rb_native_mutex_lock(&timer_thread_lock);
|
||
|
#endif
|
||
|
while (system_working > 0) {
|
||
| thread_pthread.h | ||
|---|---|---|
|
#endif
|
||
|
#define RB_NATIVETHREAD_LOCK_INIT PTHREAD_MUTEX_INITIALIZER
|
||
|
#define RB_NATIVETHREAD_COND_INIT { PTHREAD_COND_INITIALIZER, }
|
||
|
#define RB_NATIVETHREAD_COND_INIT PTHREAD_COND_INITIALIZER
|
||
|
typedef struct rb_thread_cond_struct {
|
||
|
pthread_cond_t cond;
|
||
|
#ifdef HAVE_CLOCKID_T
|
||
|
clockid_t clockid;
|
||
|
#endif
|
||
|
} rb_nativethread_cond_t;
|
||
|
typedef pthread_cond_t rb_nativethread_cond_t;
|
||
|
typedef struct native_thread_data_struct {
|
||
|
struct list_node ubf_list;
|
||
| thread_win32.c | ||
|---|---|---|
|
#endif
|
||
|
void
|
||
|
rb_native_cond_initialize(rb_nativethread_cond_t *cond, int flags)
|
||
|
rb_native_cond_initialize(rb_nativethread_cond_t *cond)
|
||
|
{
|
||
|
cond->next = (struct cond_event_entry *)cond;
|
||
|
cond->prev = (struct cond_event_entry *)cond;
|
||
|
-
|
||