Feature #15438 » 0001-2.6-fix-handling-of-negative-priorities.patch
| thread.c | ||
|---|---|---|
|
#ifndef USE_NATIVE_THREAD_PRIORITY
|
||
|
#define USE_NATIVE_THREAD_PRIORITY 0
|
||
|
#define RUBY_THREAD_PRIORITY_MAX 3
|
||
|
#define RUBY_THREAD_PRIORITY_MIN -3
|
||
|
#define RUBY_THREAD_PRIORITY_MIN -5
|
||
|
#endif
|
||
|
#ifndef THREAD_DEBUG
|
||
| ... | ... | |
|
rb_thread_wakeup_timer_thread(0);
|
||
|
}
|
||
|
static int thread_time_quantum_usec_from_priority(int priority);
|
||
|
#if defined(_WIN32)
|
||
|
#include "thread_win32.c"
|
||
| ... | ... | |
|
#error "unsupported thread type"
|
||
|
#endif
|
||
|
static int thread_time_quantum_usec_from_priority(int priority) {
|
||
|
if (priority > 0) {
|
||
|
return TIME_QUANTUM_USEC_BASE << priority;
|
||
|
}
|
||
|
else {
|
||
|
return TIME_QUANTUM_USEC_BASE >> -priority;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
* TODO: somebody with win32 knowledge should be able to get rid of
|
||
|
* timer-thread by busy-waiting on signals. And it should be possible
|
||
| ... | ... | |
|
}
|
||
|
if (timer_interrupt) {
|
||
|
uint32_t limits_us = TIME_QUANTUM_USEC;
|
||
|
if (th->priority > 0)
|
||
|
limits_us <<= th->priority;
|
||
|
else
|
||
|
limits_us >>= -th->priority;
|
||
|
uint32_t limits_us = thread_time_quantum_usec_from_priority(th->priority);
|
||
|
if (th->status == THREAD_RUNNABLE)
|
||
|
th->running_time_us += TIME_QUANTUM_USEC;
|
||
| ... | ... | |
|
else if (priority < RUBY_THREAD_PRIORITY_MIN) {
|
||
|
priority = RUBY_THREAD_PRIORITY_MIN;
|
||
|
}
|
||
|
native_update_quantum(priority);
|
||
|
target_th->priority = (int8_t)priority;
|
||
|
#endif
|
||
|
return INT2NUM(target_th->priority);
|
||
| ... | ... | |
|
sigwait_timeout(rb_thread_t *th, int sigwait_fd, const rb_hrtime_t *orig,
|
||
|
int *drained_p)
|
||
|
{
|
||
|
static const rb_hrtime_t quantum = TIME_QUANTUM_USEC * 1000;
|
||
|
if (sigwait_fd >= 0 && (!ubf_threads_empty() || BUSY_WAIT_SIGNALS)) {
|
||
|
*drained_p = check_signals_nogvl(th, sigwait_fd);
|
||
|
if (!orig || *orig > quantum)
|
||
|
return &quantum;
|
||
|
if (!orig || *orig > TIME_QUANTUM_NSEC)
|
||
|
return &TIME_QUANTUM_NSEC;
|
||
|
}
|
||
|
return orig;
|
||
| thread_pthread.c | ||
|---|---|---|
|
/* 100ms. 10ms is too small for user level thread scheduling
|
||
|
* on recent Linux (tested on 2.6.35)
|
||
|
*/
|
||
|
#define TIME_QUANTUM_MSEC (100)
|
||
|
#define TIME_QUANTUM_USEC (TIME_QUANTUM_MSEC * 1000)
|
||
|
#define TIME_QUANTUM_NSEC (TIME_QUANTUM_USEC * 1000)
|
||
|
#define TIME_QUANTUM_USEC_BASE (100 * 1000)
|
||
|
static rb_hrtime_t TIME_QUANTUM_MSEC = TIME_QUANTUM_USEC_BASE / 1000;
|
||
|
static rb_hrtime_t TIME_QUANTUM_USEC = TIME_QUANTUM_USEC_BASE;
|
||
|
static rb_hrtime_t TIME_QUANTUM_NSEC = TIME_QUANTUM_USEC_BASE * 1000;
|
||
|
static rb_hrtime_t native_cond_timeout(rb_nativethread_cond_t *, rb_hrtime_t);
|
||
|
static void
|
||
|
native_update_quantum(int priority)
|
||
|
{
|
||
|
rb_hrtime_t new_quantum_usec;
|
||
|
new_quantum_usec = thread_time_quantum_usec_from_priority(priority);
|
||
|
if (TIME_QUANTUM_USEC > new_quantum_usec)
|
||
|
{
|
||
|
TIME_QUANTUM_USEC = new_quantum_usec;
|
||
|
TIME_QUANTUM_MSEC = new_quantum_usec / 1000;
|
||
|
TIME_QUANTUM_NSEC = new_quantum_usec * 1000;
|
||
|
}
|
||
|
}
|
||
|
/*
|
||
|
* Designate the next gvl.timer thread, favor the last thread in
|
||
|
* the waitq since it will be in waitq longest
|
||
| thread_win32.c | ||
|---|---|---|
|
#include <process.h>
|
||
|
#define TIME_QUANTUM_USEC (10 * 1000)
|
||
|
#define TIME_QUANTUM_USEC_BASE (100 * 1000)
|
||
|
#define TIME_QUANTUM_USEC TIME_QUANTUM_USEC
|
||
|
static const rb_hrtime_t TIME_QUANTUM_NSEC = &TIME_QUANTUM_USEC * 1000;
|
||
|
#define RB_CONDATTR_CLOCK_MONOTONIC 1 /* no effect */
|
||
|
void native_update_quantum(int priority) { }
|
||
|
#undef Sleep
|
||
|
#define native_thread_yield() Sleep(0)
|
||
- « Previous
- 1
- 2
- Next »