2006-12-31 18:02:22 +03:00
|
|
|
/* -*-c-*- */
|
|
|
|
/**********************************************************************
|
|
|
|
|
2007-12-20 12:29:46 +03:00
|
|
|
thread_win32.c -
|
2006-12-31 18:02:22 +03:00
|
|
|
|
|
|
|
$Author$
|
|
|
|
|
* blockinlining.c, compile.c, compile.h, debug.c, debug.h,
id.c, insnhelper.h, insns.def, thread.c, thread_pthread.ci,
thread_pthread.h, thread_win32.ci, thread_win32.h, vm.h,
vm_dump.c, vm_evalbody.ci, vm_opts.h: fix comments and
copyright year.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-11-14 01:13:04 +03:00
|
|
|
Copyright (C) 2004-2007 Koichi Sasada
|
2006-12-31 18:02:22 +03:00
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#ifdef THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
|
|
|
|
|
2023-11-12 05:34:43 +03:00
|
|
|
#include "internal/sanitizers.h"
|
2006-12-31 18:02:22 +03:00
|
|
|
#include <process.h>
|
|
|
|
|
2012-03-29 05:17:39 +04:00
|
|
|
#define TIME_QUANTUM_USEC (10 * 1000)
|
2011-05-06 21:50:23 +04:00
|
|
|
#define RB_CONDATTR_CLOCK_MONOTONIC 1 /* no effect */
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
#undef Sleep
|
|
|
|
|
|
|
|
#define native_thread_yield() Sleep(0)
|
2015-11-30 23:33:20 +03:00
|
|
|
#define unregister_ubf_list(th)
|
2018-08-14 00:34:20 +03:00
|
|
|
#define ubf_wakeup_all_threads() do {} while (0)
|
|
|
|
#define ubf_threads_empty() (1)
|
2018-08-16 12:16:11 +03:00
|
|
|
#define ubf_timer_disarm() do {} while (0)
|
2018-08-21 00:34:39 +03:00
|
|
|
#define ubf_list_atfork() do {} while (0)
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2007-08-18 12:40:13 +04:00
|
|
|
static volatile DWORD ruby_native_thread_key = TLS_OUT_OF_INDEXES;
|
|
|
|
|
2011-04-29 16:12:52 +04:00
|
|
|
static int w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th);
|
|
|
|
|
2022-01-27 19:12:22 +03:00
|
|
|
rb_internal_thread_event_hook_t *
|
|
|
|
rb_internal_thread_add_event_hook(rb_internal_thread_event_callback callback, rb_event_flag_t internal_event, void *user_data)
|
|
|
|
{
|
|
|
|
// not implemented
|
2022-06-23 10:45:05 +03:00
|
|
|
return NULL;
|
2022-01-27 19:12:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
rb_internal_thread_remove_event_hook(rb_internal_thread_event_hook_t * hook)
|
|
|
|
{
|
|
|
|
// not implemented
|
2022-06-23 10:45:05 +03:00
|
|
|
return false;
|
2022-01-27 19:12:22 +03:00
|
|
|
}
|
|
|
|
|
2021-05-02 08:11:28 +03:00
|
|
|
RBIMPL_ATTR_NORETURN()
|
2010-11-27 23:15:59 +03:00
|
|
|
static void
|
|
|
|
w32_error(const char *func)
|
|
|
|
{
|
|
|
|
LPVOID lpMsgBuf;
|
|
|
|
DWORD err = GetLastError();
|
|
|
|
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
NULL,
|
|
|
|
err,
|
|
|
|
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
|
|
|
(LPTSTR) & lpMsgBuf, 0, NULL) == 0)
|
|
|
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
NULL,
|
|
|
|
err,
|
|
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
|
|
(LPTSTR) & lpMsgBuf, 0, NULL);
|
|
|
|
rb_bug("%s: %s", func, (char*)lpMsgBuf);
|
2021-05-02 08:11:28 +03:00
|
|
|
UNREACHABLE;
|
2010-11-27 23:15:59 +03:00
|
|
|
}
|
|
|
|
|
2022-05-23 21:58:18 +03:00
|
|
|
#define W32_EVENT_DEBUG 0
|
|
|
|
|
|
|
|
#if W32_EVENT_DEBUG
|
|
|
|
#define w32_event_debug printf
|
|
|
|
#else
|
|
|
|
#define w32_event_debug if (0) printf
|
|
|
|
#endif
|
|
|
|
|
2010-11-27 23:15:59 +03:00
|
|
|
static int
|
2020-11-17 10:40:47 +03:00
|
|
|
w32_mutex_lock(HANDLE lock, bool try)
|
2010-11-27 23:15:59 +03:00
|
|
|
{
|
|
|
|
DWORD result;
|
|
|
|
while (1) {
|
2022-05-23 21:58:18 +03:00
|
|
|
// RUBY_DEBUG_LOG() is not available because RUBY_DEBUG_LOG() calls it.
|
|
|
|
w32_event_debug("lock:%p\n", lock);
|
|
|
|
|
2020-11-17 10:40:47 +03:00
|
|
|
result = w32_wait_events(&lock, 1, try ? 0 : INFINITE, 0);
|
2010-11-27 23:15:59 +03:00
|
|
|
switch (result) {
|
|
|
|
case WAIT_OBJECT_0:
|
|
|
|
/* get mutex object */
|
2022-05-23 21:58:18 +03:00
|
|
|
w32_event_debug("locked lock:%p\n", lock);
|
2010-11-27 23:15:59 +03:00
|
|
|
return 0;
|
2022-05-23 21:58:18 +03:00
|
|
|
|
|
|
|
case WAIT_OBJECT_0 + 1:
|
2010-11-27 23:15:59 +03:00
|
|
|
/* interrupt */
|
|
|
|
errno = EINTR;
|
2022-05-23 21:58:18 +03:00
|
|
|
w32_event_debug("interrupted lock:%p\n", lock);
|
2010-11-27 23:15:59 +03:00
|
|
|
return 0;
|
2022-05-23 21:58:18 +03:00
|
|
|
|
|
|
|
case WAIT_TIMEOUT:
|
|
|
|
w32_event_debug("timeout locK:%p\n", lock);
|
2020-11-17 10:40:47 +03:00
|
|
|
return EBUSY;
|
2022-05-23 21:58:18 +03:00
|
|
|
|
|
|
|
case WAIT_ABANDONED:
|
2010-11-27 23:15:59 +03:00
|
|
|
rb_bug("win32_mutex_lock: WAIT_ABANDONED");
|
|
|
|
break;
|
2022-05-23 21:58:18 +03:00
|
|
|
|
|
|
|
default:
|
|
|
|
rb_bug("win32_mutex_lock: unknown result (%ld)", result);
|
2010-11-27 23:15:59 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static HANDLE
|
|
|
|
w32_mutex_create(void)
|
|
|
|
{
|
|
|
|
HANDLE lock = CreateMutex(NULL, FALSE, NULL);
|
|
|
|
if (lock == NULL) {
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
w32_error("rb_native_mutex_initialize");
|
2010-11-27 23:15:59 +03:00
|
|
|
}
|
|
|
|
return lock;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GVL_DEBUG 0
|
|
|
|
|
|
|
|
static void
|
2022-04-16 21:40:23 +03:00
|
|
|
thread_sched_to_running(struct rb_thread_sched *sched, rb_thread_t *th)
|
2010-11-27 23:15:59 +03:00
|
|
|
{
|
2022-04-16 21:40:23 +03:00
|
|
|
w32_mutex_lock(sched->lock, false);
|
2010-11-27 23:15:59 +03:00
|
|
|
if (GVL_DEBUG) fprintf(stderr, "gvl acquire (%p): acquire\n", th);
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:29:39 +03:00
|
|
|
#define thread_sched_to_dead thread_sched_to_waiting
|
|
|
|
|
2010-11-27 23:15:59 +03:00
|
|
|
static void
|
2023-03-31 11:57:25 +03:00
|
|
|
thread_sched_to_waiting(struct rb_thread_sched *sched, rb_thread_t *th)
|
2010-11-27 23:15:59 +03:00
|
|
|
{
|
2022-04-16 21:40:23 +03:00
|
|
|
ReleaseMutex(sched->lock);
|
2010-11-27 23:15:59 +03:00
|
|
|
}
|
|
|
|
|
2011-06-13 19:06:30 +04:00
|
|
|
static void
|
2022-04-16 21:40:23 +03:00
|
|
|
thread_sched_yield(struct rb_thread_sched *sched, rb_thread_t *th)
|
2011-06-13 19:06:30 +04:00
|
|
|
{
|
2023-03-31 11:57:25 +03:00
|
|
|
thread_sched_to_waiting(sched, th);
|
2022-04-16 21:40:23 +03:00
|
|
|
native_thread_yield();
|
|
|
|
thread_sched_to_running(sched, th);
|
2011-06-13 19:06:30 +04:00
|
|
|
}
|
|
|
|
|
2020-03-09 20:22:11 +03:00
|
|
|
void
|
2023-04-10 04:53:13 +03:00
|
|
|
rb_thread_sched_init(struct rb_thread_sched *sched, bool atfork)
|
2010-11-27 23:15:59 +03:00
|
|
|
{
|
2022-04-16 21:40:23 +03:00
|
|
|
if (GVL_DEBUG) fprintf(stderr, "sched init\n");
|
|
|
|
sched->lock = w32_mutex_create();
|
2010-11-27 23:15:59 +03:00
|
|
|
}
|
|
|
|
|
2024-03-22 12:53:44 +03:00
|
|
|
#if 0
|
2023-04-10 04:53:13 +03:00
|
|
|
// per-ractor
|
2022-04-16 21:40:23 +03:00
|
|
|
void
|
|
|
|
rb_thread_sched_destroy(struct rb_thread_sched *sched)
|
2010-11-27 23:15:59 +03:00
|
|
|
{
|
2022-04-16 21:40:23 +03:00
|
|
|
if (GVL_DEBUG) fprintf(stderr, "sched destroy\n");
|
|
|
|
CloseHandle(sched->lock);
|
2010-11-27 23:15:59 +03:00
|
|
|
}
|
2024-03-22 12:53:44 +03:00
|
|
|
#endif
|
2010-11-27 23:15:59 +03:00
|
|
|
|
2021-06-26 01:17:26 +03:00
|
|
|
rb_thread_t *
|
2007-08-18 12:40:13 +04:00
|
|
|
ruby_thread_from_native(void)
|
|
|
|
{
|
|
|
|
return TlsGetValue(ruby_native_thread_key);
|
|
|
|
}
|
|
|
|
|
2021-06-26 01:17:26 +03:00
|
|
|
int
|
2007-08-18 12:40:13 +04:00
|
|
|
ruby_thread_set_native(rb_thread_t *th)
|
|
|
|
{
|
2020-03-09 20:22:11 +03:00
|
|
|
if (th && th->ec) {
|
|
|
|
rb_ractor_set_current_ec(th->ractor, th->ec);
|
|
|
|
}
|
2007-08-18 12:40:13 +04:00
|
|
|
return TlsSetValue(ruby_native_thread_key, th);
|
|
|
|
}
|
|
|
|
|
2010-06-06 03:26:43 +04:00
|
|
|
void
|
2022-04-22 15:19:03 +03:00
|
|
|
Init_native_thread(rb_thread_t *main_th)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2020-03-09 20:22:11 +03:00
|
|
|
if ((ruby_current_ec_key = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
|
|
|
|
rb_bug("TlsAlloc() for ruby_current_ec_key fails");
|
|
|
|
}
|
|
|
|
if ((ruby_native_thread_key = TlsAlloc()) == TLS_OUT_OF_INDEXES) {
|
|
|
|
rb_bug("TlsAlloc() for ruby_native_thread_key fails");
|
|
|
|
}
|
2022-04-22 15:19:03 +03:00
|
|
|
|
|
|
|
// setup main thread
|
|
|
|
|
|
|
|
ruby_thread_set_native(main_th);
|
|
|
|
main_th->nt->interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
DuplicateHandle(GetCurrentProcess(),
|
|
|
|
GetCurrentThread(),
|
|
|
|
GetCurrentProcess(),
|
2022-04-22 15:19:03 +03:00
|
|
|
&main_th->nt->thread_id, 0, FALSE, DUPLICATE_SAME_ACCESS);
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("initial thread th:%u thid:%p, event: %p",
|
|
|
|
rb_th_serial(main_th),
|
|
|
|
main_th->nt->thread_id,
|
|
|
|
main_th->nt->interrupt_event);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
|
2023-04-10 04:53:13 +03:00
|
|
|
void
|
|
|
|
ruby_mn_threads_params(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
static int
|
2007-02-23 12:33:53 +03:00
|
|
|
w32_wait_events(HANDLE *events, int count, DWORD timeout, rb_thread_t *th)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2007-02-23 12:33:53 +03:00
|
|
|
HANDLE *targets = events;
|
2007-04-10 11:16:42 +04:00
|
|
|
HANDLE intr;
|
2017-04-17 16:23:42 +03:00
|
|
|
const int initcount = count;
|
2006-12-31 18:02:22 +03:00
|
|
|
DWORD ret;
|
|
|
|
|
2022-05-23 21:58:18 +03:00
|
|
|
w32_event_debug("events:%p, count:%d, timeout:%ld, th:%u\n",
|
2022-06-23 16:51:31 +03:00
|
|
|
events, count, timeout, th ? rb_th_serial(th) : UINT_MAX);
|
2022-05-23 21:58:18 +03:00
|
|
|
|
2022-04-22 15:19:03 +03:00
|
|
|
if (th && (intr = th->nt->interrupt_event)) {
|
2017-11-06 10:44:28 +03:00
|
|
|
if (ResetEvent(intr) && (!RUBY_VM_INTERRUPTED(th->ec) || SetEvent(intr))) {
|
2010-05-05 15:53:03 +04:00
|
|
|
targets = ALLOCA_N(HANDLE, count + 1);
|
|
|
|
memcpy(targets, events, sizeof(HANDLE) * count);
|
|
|
|
|
|
|
|
targets[count++] = intr;
|
2022-05-23 21:58:18 +03:00
|
|
|
w32_event_debug("handle:%p (count:%d, intr)\n", intr, count);
|
|
|
|
}
|
2022-04-22 15:19:03 +03:00
|
|
|
else if (intr == th->nt->interrupt_event) {
|
2017-04-16 17:27:21 +03:00
|
|
|
w32_error("w32_wait_events");
|
|
|
|
}
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
|
2022-05-23 21:58:18 +03:00
|
|
|
w32_event_debug("WaitForMultipleObjects start count:%d\n", count);
|
2007-02-23 12:33:53 +03:00
|
|
|
ret = WaitForMultipleObjects(count, targets, FALSE, timeout);
|
2022-05-23 21:58:18 +03:00
|
|
|
w32_event_debug("WaitForMultipleObjects end ret:%lu\n", ret);
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2017-04-17 16:23:42 +03:00
|
|
|
if (ret == (DWORD)(WAIT_OBJECT_0 + initcount) && th) {
|
2006-12-31 18:02:22 +03:00
|
|
|
errno = EINTR;
|
|
|
|
}
|
2022-05-23 21:58:18 +03:00
|
|
|
if (ret == WAIT_FAILED && W32_EVENT_DEBUG) {
|
2006-12-31 18:02:22 +03:00
|
|
|
int i;
|
2022-05-23 21:58:18 +03:00
|
|
|
DWORD dmy;
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
w32_event_debug("i:%d %s\n", i, GetHandleInformation(targets[i], &dmy) ? "OK" : "NG");
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-11-20 13:47:53 +03:00
|
|
|
static void ubf_handle(void *ptr);
|
2007-02-23 12:33:53 +03:00
|
|
|
#define ubf_select ubf_handle
|
|
|
|
|
2007-02-24 12:43:40 +03:00
|
|
|
int
|
|
|
|
rb_w32_wait_events_blocking(HANDLE *events, int num, DWORD timeout)
|
|
|
|
{
|
2012-01-28 04:51:36 +04:00
|
|
|
return w32_wait_events(events, num, timeout, ruby_thread_from_native());
|
2007-02-24 12:43:40 +03:00
|
|
|
}
|
|
|
|
|
2007-02-23 12:33:53 +03:00
|
|
|
int
|
|
|
|
rb_w32_wait_events(HANDLE *events, int num, DWORD timeout)
|
|
|
|
{
|
|
|
|
int ret;
|
2018-05-17 00:54:42 +03:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2007-02-23 12:33:53 +03:00
|
|
|
|
2018-05-17 00:54:42 +03:00
|
|
|
BLOCKING_REGION(th, ret = rb_w32_wait_events_blocking(events, num, timeout),
|
2012-11-28 17:57:52 +04:00
|
|
|
ubf_handle, ruby_thread_from_native(), FALSE);
|
2007-02-23 12:33:53 +03:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-02-09 06:42:46 +03:00
|
|
|
static void
|
|
|
|
w32_close_handle(HANDLE handle)
|
|
|
|
{
|
|
|
|
if (CloseHandle(handle) == 0) {
|
2009-12-30 20:36:20 +03:00
|
|
|
w32_error("w32_close_handle");
|
2007-02-09 06:42:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
w32_resume_thread(HANDLE handle)
|
|
|
|
{
|
2010-09-23 14:29:27 +04:00
|
|
|
if (ResumeThread(handle) == (DWORD)-1) {
|
2009-12-30 20:36:20 +03:00
|
|
|
w32_error("w32_resume_thread");
|
2007-02-09 06:42:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-21 12:48:29 +04:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#define HAVE__BEGINTHREADEX 1
|
|
|
|
#else
|
|
|
|
#undef HAVE__BEGINTHREADEX
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE__BEGINTHREADEX
|
|
|
|
#define start_thread (HANDLE)_beginthreadex
|
2009-11-12 08:33:23 +03:00
|
|
|
#define thread_errno errno
|
2013-07-08 18:12:26 +04:00
|
|
|
typedef unsigned long (__stdcall *w32_thread_start_func)(void*);
|
2007-07-21 12:48:29 +04:00
|
|
|
#else
|
|
|
|
#define start_thread CreateThread
|
2009-11-12 08:33:23 +03:00
|
|
|
#define thread_errno rb_w32_map_errno(GetLastError())
|
2007-07-21 12:48:29 +04:00
|
|
|
typedef LPTHREAD_START_ROUTINE w32_thread_start_func;
|
|
|
|
#endif
|
|
|
|
|
2007-02-09 06:42:46 +03:00
|
|
|
static HANDLE
|
2007-07-21 12:48:29 +04:00
|
|
|
w32_create_thread(DWORD stack_size, w32_thread_start_func func, void *val)
|
2007-02-09 06:42:46 +03:00
|
|
|
{
|
2019-06-06 06:02:35 +03:00
|
|
|
return start_thread(0, stack_size, func, val, CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, 0);
|
2007-02-09 06:42:46 +03:00
|
|
|
}
|
|
|
|
|
2007-02-23 12:33:53 +03:00
|
|
|
int
|
|
|
|
rb_w32_sleep(unsigned long msec)
|
|
|
|
{
|
2012-01-28 04:51:36 +04:00
|
|
|
return w32_wait_events(0, 0, msec, ruby_thread_from_native());
|
2007-02-23 12:33:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int WINAPI
|
|
|
|
rb_w32_Sleep(unsigned long msec)
|
|
|
|
{
|
|
|
|
int ret;
|
2018-05-17 00:54:42 +03:00
|
|
|
rb_thread_t *th = GET_THREAD();
|
2007-02-23 12:33:53 +03:00
|
|
|
|
2018-05-17 00:54:42 +03:00
|
|
|
BLOCKING_REGION(th, ret = rb_w32_sleep(msec),
|
2012-11-28 17:57:52 +04:00
|
|
|
ubf_handle, ruby_thread_from_native(), FALSE);
|
2007-02-23 12:33:53 +03:00
|
|
|
return ret;
|
|
|
|
}
|
2007-02-08 14:51:40 +03:00
|
|
|
|
2018-08-25 09:58:35 +03:00
|
|
|
static DWORD
|
|
|
|
hrtime2msec(rb_hrtime_t hrt)
|
|
|
|
{
|
|
|
|
return (DWORD)hrt / (DWORD)RB_HRTIME_PER_MSEC;
|
|
|
|
}
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
static void
|
2018-08-25 09:58:35 +03:00
|
|
|
native_sleep(rb_thread_t *th, rb_hrtime_t *rel)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2018-08-25 09:58:35 +03:00
|
|
|
const volatile DWORD msec = rel ? hrtime2msec(*rel) : INFINITE;
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2022-04-16 21:40:23 +03:00
|
|
|
THREAD_BLOCKING_BEGIN(th);
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2008-07-09 17:41:19 +04:00
|
|
|
DWORD ret;
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_native_mutex_lock(&th->interrupt_lock);
|
2008-05-30 05:52:38 +04:00
|
|
|
th->unblock.func = ubf_handle;
|
|
|
|
th->unblock.arg = th;
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_native_mutex_unlock(&th->interrupt_lock);
|
2007-12-25 07:16:06 +03:00
|
|
|
|
2017-11-06 10:44:28 +03:00
|
|
|
if (RUBY_VM_INTERRUPTED(th->ec)) {
|
2007-12-25 07:16:06 +03:00
|
|
|
/* interrupted. return immediate */
|
|
|
|
}
|
|
|
|
else {
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("start msec:%lu", msec);
|
2007-12-25 07:16:06 +03:00
|
|
|
ret = w32_wait_events(0, 0, msec, th);
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("done ret:%lu", ret);
|
2022-06-23 16:51:31 +03:00
|
|
|
(void)ret;
|
2007-12-25 07:16:06 +03:00
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_native_mutex_lock(&th->interrupt_lock);
|
2008-05-30 05:52:38 +04:00
|
|
|
th->unblock.func = 0;
|
|
|
|
th->unblock.arg = 0;
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_native_mutex_unlock(&th->interrupt_lock);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
2022-04-16 21:40:23 +03:00
|
|
|
THREAD_BLOCKING_END(th);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_mutex_lock(rb_nativethread_lock_t *lock)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2021-05-05 02:57:24 +03:00
|
|
|
#ifdef USE_WIN32_MUTEX
|
2020-11-17 10:40:47 +03:00
|
|
|
w32_mutex_lock(lock->mutex, false);
|
2006-12-31 18:02:22 +03:00
|
|
|
#else
|
2012-06-17 11:21:03 +04:00
|
|
|
EnterCriticalSection(&lock->crit);
|
2006-12-31 18:02:22 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-11-17 10:40:47 +03:00
|
|
|
int
|
|
|
|
rb_native_mutex_trylock(rb_nativethread_lock_t *lock)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2021-05-05 02:57:24 +03:00
|
|
|
#ifdef USE_WIN32_MUTEX
|
2020-11-17 10:40:47 +03:00
|
|
|
return w32_mutex_lock(lock->mutex, true);
|
2006-12-31 18:02:22 +03:00
|
|
|
#else
|
2020-11-17 10:40:47 +03:00
|
|
|
return TryEnterCriticalSection(&lock->crit) == 0 ? EBUSY : 0;
|
2006-12-31 18:02:22 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-11-17 10:40:47 +03:00
|
|
|
void
|
|
|
|
rb_native_mutex_unlock(rb_nativethread_lock_t *lock)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2021-05-05 02:57:24 +03:00
|
|
|
#ifdef USE_WIN32_MUTEX
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("lock:%p", lock->mutex);
|
2020-11-17 10:40:47 +03:00
|
|
|
ReleaseMutex(lock->mutex);
|
2006-12-31 18:02:22 +03:00
|
|
|
#else
|
2020-11-17 10:40:47 +03:00
|
|
|
LeaveCriticalSection(&lock->crit);
|
2006-12-31 18:02:22 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_mutex_initialize(rb_nativethread_lock_t *lock)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2021-05-05 02:57:24 +03:00
|
|
|
#ifdef USE_WIN32_MUTEX
|
2012-06-17 11:21:03 +04:00
|
|
|
lock->mutex = w32_mutex_create();
|
|
|
|
/* thread_debug("initialize mutex: %p\n", lock->mutex); */
|
2006-12-31 18:02:22 +03:00
|
|
|
#else
|
2012-06-17 11:21:03 +04:00
|
|
|
InitializeCriticalSection(&lock->crit);
|
2006-12-31 18:02:22 +03:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_mutex_destroy(rb_nativethread_lock_t *lock)
|
2007-02-08 23:24:55 +03:00
|
|
|
{
|
2021-05-05 02:57:24 +03:00
|
|
|
#ifdef USE_WIN32_MUTEX
|
2012-06-17 11:21:03 +04:00
|
|
|
w32_close_handle(lock->mutex);
|
2007-02-09 06:42:46 +03:00
|
|
|
#else
|
2012-06-17 11:21:03 +04:00
|
|
|
DeleteCriticalSection(&lock->crit);
|
2007-02-09 06:42:46 +03:00
|
|
|
#endif
|
2007-02-08 23:24:55 +03:00
|
|
|
}
|
|
|
|
|
2008-07-28 16:27:43 +04:00
|
|
|
struct cond_event_entry {
|
|
|
|
struct cond_event_entry* next;
|
2011-05-07 10:17:59 +04:00
|
|
|
struct cond_event_entry* prev;
|
2008-07-28 16:27:43 +04:00
|
|
|
HANDLE event;
|
|
|
|
};
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_cond_signal(rb_nativethread_cond_t *cond)
|
2007-08-27 20:48:14 +04:00
|
|
|
{
|
|
|
|
/* cond is guarded by mutex */
|
|
|
|
struct cond_event_entry *e = cond->next;
|
2011-05-07 10:17:59 +04:00
|
|
|
struct cond_event_entry *head = (struct cond_event_entry*)cond;
|
|
|
|
|
|
|
|
if (e != head) {
|
|
|
|
struct cond_event_entry *next = e->next;
|
|
|
|
struct cond_event_entry *prev = e->prev;
|
|
|
|
|
|
|
|
prev->next = next;
|
|
|
|
next->prev = prev;
|
|
|
|
e->next = e->prev = e;
|
2007-08-27 20:48:14 +04:00
|
|
|
|
|
|
|
SetEvent(e->event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_cond_broadcast(rb_nativethread_cond_t *cond)
|
2007-08-27 20:48:14 +04:00
|
|
|
{
|
|
|
|
/* cond is guarded by mutex */
|
|
|
|
struct cond_event_entry *e = cond->next;
|
2011-05-07 10:17:59 +04:00
|
|
|
struct cond_event_entry *head = (struct cond_event_entry*)cond;
|
|
|
|
|
|
|
|
while (e != head) {
|
|
|
|
struct cond_event_entry *next = e->next;
|
|
|
|
struct cond_event_entry *prev = e->prev;
|
2007-08-27 20:48:14 +04:00
|
|
|
|
|
|
|
SetEvent(e->event);
|
2011-05-07 10:17:59 +04:00
|
|
|
|
|
|
|
prev->next = next;
|
|
|
|
next->prev = prev;
|
|
|
|
e->next = e->prev = e;
|
|
|
|
|
|
|
|
e = next;
|
2007-08-27 20:48:14 +04:00
|
|
|
}
|
|
|
|
}
|
2011-04-29 08:18:29 +04:00
|
|
|
|
|
|
|
static int
|
2013-07-23 14:50:32 +04:00
|
|
|
native_cond_timedwait_ms(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec)
|
2007-08-27 20:48:14 +04:00
|
|
|
{
|
|
|
|
DWORD r;
|
|
|
|
struct cond_event_entry entry;
|
2011-05-07 10:17:59 +04:00
|
|
|
struct cond_event_entry *head = (struct cond_event_entry*)cond;
|
2007-08-27 20:48:14 +04:00
|
|
|
|
|
|
|
entry.event = CreateEvent(0, FALSE, FALSE, 0);
|
|
|
|
|
|
|
|
/* cond is guarded by mutex */
|
2011-05-07 10:17:59 +04:00
|
|
|
entry.next = head;
|
|
|
|
entry.prev = head->prev;
|
|
|
|
head->prev->next = &entry;
|
|
|
|
head->prev = &entry;
|
2007-08-27 20:48:14 +04:00
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_native_mutex_unlock(mutex);
|
2007-08-27 20:48:14 +04:00
|
|
|
{
|
2011-04-29 08:18:29 +04:00
|
|
|
r = WaitForSingleObject(entry.event, msec);
|
|
|
|
if ((r != WAIT_OBJECT_0) && (r != WAIT_TIMEOUT)) {
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_bug("rb_native_cond_wait: WaitForSingleObject returns %lu", r);
|
2007-08-27 20:48:14 +04:00
|
|
|
}
|
|
|
|
}
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
rb_native_mutex_lock(mutex);
|
2007-08-27 20:48:14 +04:00
|
|
|
|
2011-05-07 10:17:59 +04:00
|
|
|
entry.prev->next = entry.next;
|
|
|
|
entry.next->prev = entry.prev;
|
|
|
|
|
2007-08-27 20:48:14 +04:00
|
|
|
w32_close_handle(entry.event);
|
2011-04-29 08:18:29 +04:00
|
|
|
return (r == WAIT_OBJECT_0) ? 0 : ETIMEDOUT;
|
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex)
|
2011-04-29 08:18:29 +04:00
|
|
|
{
|
2017-11-16 13:02:03 +03:00
|
|
|
native_cond_timedwait_ms(cond, mutex, INFINITE);
|
2011-04-29 08:18:29 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long
|
2014-05-09 18:31:34 +04:00
|
|
|
abs_timespec_to_timeout_ms(const struct timespec *ts)
|
2011-04-29 08:18:29 +04:00
|
|
|
{
|
|
|
|
struct timeval tv;
|
|
|
|
struct timeval now;
|
|
|
|
|
|
|
|
gettimeofday(&now, NULL);
|
|
|
|
tv.tv_sec = ts->tv_sec;
|
2011-05-07 07:43:27 +04:00
|
|
|
tv.tv_usec = ts->tv_nsec / 1000;
|
2011-04-29 08:18:29 +04:00
|
|
|
|
|
|
|
if (!rb_w32_time_subtract(&tv, &now))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2014-05-09 18:31:34 +04:00
|
|
|
native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, const struct timespec *ts)
|
2011-04-29 08:18:29 +04:00
|
|
|
{
|
|
|
|
unsigned long timeout_ms;
|
|
|
|
|
|
|
|
timeout_ms = abs_timespec_to_timeout_ms(ts);
|
|
|
|
if (!timeout_ms)
|
|
|
|
return ETIMEDOUT;
|
|
|
|
|
2012-06-17 11:20:53 +04:00
|
|
|
return native_cond_timedwait_ms(cond, mutex, timeout_ms);
|
2007-08-27 20:48:14 +04:00
|
|
|
}
|
|
|
|
|
2020-03-09 20:22:11 +03:00
|
|
|
static struct timespec native_cond_timeout(rb_nativethread_cond_t *cond, struct timespec timeout_rel);
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex, unsigned long msec)
|
|
|
|
{
|
|
|
|
struct timespec rel = {
|
|
|
|
.tv_sec = msec / 1000,
|
|
|
|
.tv_nsec = (msec % 1000) * 1000 * 1000,
|
|
|
|
};
|
|
|
|
struct timespec ts = native_cond_timeout(cond, rel);
|
|
|
|
native_cond_timedwait(cond, mutex, &ts);
|
|
|
|
}
|
|
|
|
|
2011-05-06 21:39:32 +04:00
|
|
|
static struct timespec
|
2013-07-23 14:50:32 +04:00
|
|
|
native_cond_timeout(rb_nativethread_cond_t *cond, struct timespec timeout_rel)
|
2011-05-06 21:39:32 +04:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct timeval tv;
|
|
|
|
struct timespec timeout;
|
2011-05-06 22:17:14 +04:00
|
|
|
struct timespec now;
|
2011-05-06 21:39:32 +04:00
|
|
|
|
|
|
|
ret = gettimeofday(&tv, 0);
|
|
|
|
if (ret != 0)
|
|
|
|
rb_sys_fail(0);
|
2011-05-06 22:17:14 +04:00
|
|
|
now.tv_sec = tv.tv_sec;
|
|
|
|
now.tv_nsec = tv.tv_usec * 1000;
|
2011-05-06 21:39:32 +04:00
|
|
|
|
2011-05-06 22:17:14 +04:00
|
|
|
timeout.tv_sec = now.tv_sec;
|
|
|
|
timeout.tv_nsec = now.tv_nsec;
|
2011-05-06 21:39:32 +04:00
|
|
|
timeout.tv_sec += timeout_rel.tv_sec;
|
|
|
|
timeout.tv_nsec += timeout_rel.tv_nsec;
|
2011-05-06 22:17:14 +04:00
|
|
|
|
2011-05-06 21:39:32 +04:00
|
|
|
if (timeout.tv_nsec >= 1000*1000*1000) {
|
|
|
|
timeout.tv_sec++;
|
|
|
|
timeout.tv_nsec -= 1000*1000*1000;
|
|
|
|
}
|
2011-05-06 22:17:14 +04:00
|
|
|
|
|
|
|
if (timeout.tv_sec < now.tv_sec)
|
|
|
|
timeout.tv_sec = TIMET_MAX;
|
|
|
|
|
2011-05-06 21:39:32 +04:00
|
|
|
return timeout;
|
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
2018-04-22 15:09:07 +03:00
|
|
|
rb_native_cond_initialize(rb_nativethread_cond_t *cond)
|
2007-08-27 20:48:14 +04:00
|
|
|
{
|
2011-05-07 10:17:59 +04:00
|
|
|
cond->next = (struct cond_event_entry *)cond;
|
|
|
|
cond->prev = (struct cond_event_entry *)cond;
|
2007-08-27 20:48:14 +04:00
|
|
|
}
|
|
|
|
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
void
|
|
|
|
rb_native_cond_destroy(rb_nativethread_cond_t *cond)
|
2007-08-27 20:48:14 +04:00
|
|
|
{
|
|
|
|
/* */
|
|
|
|
}
|
2007-02-08 23:24:55 +03:00
|
|
|
|
2008-06-14 06:59:19 +04:00
|
|
|
|
|
|
|
#define CHECK_ERR(expr) \
|
|
|
|
{if (!(expr)) {rb_bug("err: %lu - %s", GetLastError(), #expr);}}
|
|
|
|
|
2021-05-04 04:08:23 +03:00
|
|
|
COMPILER_WARNING_PUSH
|
2024-08-16 08:51:21 +03:00
|
|
|
#if __has_warning("-Wmaybe-uninitialized")
|
2021-05-04 04:08:23 +03:00
|
|
|
COMPILER_WARNING_IGNORED(-Wmaybe-uninitialized)
|
|
|
|
#endif
|
|
|
|
static inline SIZE_T
|
Pass down "stack start" variables from closer to the top of the stack
This commit changes how stack extents are calculated for both the main
thread and other threads. Ruby uses the address of a local variable as
part of the calculation for machine stack extents:
* pthreads uses it as a lower-bound on the start of the stack, because
glibc (and maybe other libcs) can store its own data on the stack
before calling into user code on thread creation.
* win32 uses it as an argument to VirtualQuery, which gets the extent of
the memory mapping which contains the variable
However, the local being used for this is actually too low (too close to
the leaf function call) in both the main thread case and the new thread
case.
In the main thread case, we have the `INIT_STACK` macro, which is used
for pthreads to set the `native_main_thread->stack_start` value. This
value is correctly captured at the very top level of the program (in
main.c). However, this is _not_ what's used to set the execution context
machine stack (`th->ec->machine_stack.stack_start`); that gets set as
part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the
address of a local variable allocated _inside_ `Init_BareVM`. This is
too low; we need to use a local allocated closer to the top of the
program.
In the new thread case, the lolcal is allocated inside
`native_thread_init_stack`, which is, again, too low.
In both cases, this means that we might have VALUEs lying outside the
bounds of `th->ec->machine.stack_{start,end}`, which won't be marked
correctly by the GC machinery.
To fix this,
* In the main thread case: We already have `INIT_STACK` at the right
level, so just pass that local var to `ruby_thread_init_stack`.
* In the new thread case: Allocate the local one level above the call to
`native_thread_init_stack` in `call_thread_start_func2`.
[Bug #20001]
fix
2023-11-12 05:24:55 +03:00
|
|
|
query_memory_basic_info(PMEMORY_BASIC_INFORMATION mi, void *local_in_parent_frame)
|
2021-05-04 04:08:23 +03:00
|
|
|
{
|
2023-11-12 05:34:43 +03:00
|
|
|
return VirtualQuery(asan_get_real_stack_addr(local_in_parent_frame), mi, sizeof(*mi));
|
2021-05-04 04:08:23 +03:00
|
|
|
}
|
|
|
|
COMPILER_WARNING_POP
|
|
|
|
|
2008-06-14 06:59:19 +04:00
|
|
|
static void
|
Pass down "stack start" variables from closer to the top of the stack
This commit changes how stack extents are calculated for both the main
thread and other threads. Ruby uses the address of a local variable as
part of the calculation for machine stack extents:
* pthreads uses it as a lower-bound on the start of the stack, because
glibc (and maybe other libcs) can store its own data on the stack
before calling into user code on thread creation.
* win32 uses it as an argument to VirtualQuery, which gets the extent of
the memory mapping which contains the variable
However, the local being used for this is actually too low (too close to
the leaf function call) in both the main thread case and the new thread
case.
In the main thread case, we have the `INIT_STACK` macro, which is used
for pthreads to set the `native_main_thread->stack_start` value. This
value is correctly captured at the very top level of the program (in
main.c). However, this is _not_ what's used to set the execution context
machine stack (`th->ec->machine_stack.stack_start`); that gets set as
part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the
address of a local variable allocated _inside_ `Init_BareVM`. This is
too low; we need to use a local allocated closer to the top of the
program.
In the new thread case, the lolcal is allocated inside
`native_thread_init_stack`, which is, again, too low.
In both cases, this means that we might have VALUEs lying outside the
bounds of `th->ec->machine.stack_{start,end}`, which won't be marked
correctly by the GC machinery.
To fix this,
* In the main thread case: We already have `INIT_STACK` at the right
level, so just pass that local var to `ruby_thread_init_stack`.
* In the new thread case: Allocate the local one level above the call to
`native_thread_init_stack` in `call_thread_start_func2`.
[Bug #20001]
fix
2023-11-12 05:24:55 +03:00
|
|
|
native_thread_init_stack(rb_thread_t *th, void *local_in_parent_frame)
|
2008-06-14 06:59:19 +04:00
|
|
|
{
|
|
|
|
MEMORY_BASIC_INFORMATION mi;
|
|
|
|
char *base, *end;
|
|
|
|
DWORD size, space;
|
|
|
|
|
Pass down "stack start" variables from closer to the top of the stack
This commit changes how stack extents are calculated for both the main
thread and other threads. Ruby uses the address of a local variable as
part of the calculation for machine stack extents:
* pthreads uses it as a lower-bound on the start of the stack, because
glibc (and maybe other libcs) can store its own data on the stack
before calling into user code on thread creation.
* win32 uses it as an argument to VirtualQuery, which gets the extent of
the memory mapping which contains the variable
However, the local being used for this is actually too low (too close to
the leaf function call) in both the main thread case and the new thread
case.
In the main thread case, we have the `INIT_STACK` macro, which is used
for pthreads to set the `native_main_thread->stack_start` value. This
value is correctly captured at the very top level of the program (in
main.c). However, this is _not_ what's used to set the execution context
machine stack (`th->ec->machine_stack.stack_start`); that gets set as
part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the
address of a local variable allocated _inside_ `Init_BareVM`. This is
too low; we need to use a local allocated closer to the top of the
program.
In the new thread case, the lolcal is allocated inside
`native_thread_init_stack`, which is, again, too low.
In both cases, this means that we might have VALUEs lying outside the
bounds of `th->ec->machine.stack_{start,end}`, which won't be marked
correctly by the GC machinery.
To fix this,
* In the main thread case: We already have `INIT_STACK` at the right
level, so just pass that local var to `ruby_thread_init_stack`.
* In the new thread case: Allocate the local one level above the call to
`native_thread_init_stack` in `call_thread_start_func2`.
[Bug #20001]
fix
2023-11-12 05:24:55 +03:00
|
|
|
CHECK_ERR(query_memory_basic_info(&mi, local_in_parent_frame));
|
2008-06-14 06:59:19 +04:00
|
|
|
base = mi.AllocationBase;
|
|
|
|
end = mi.BaseAddress;
|
|
|
|
end += mi.RegionSize;
|
|
|
|
size = end - base;
|
|
|
|
space = size / 5;
|
|
|
|
if (space > 1024*1024) space = 1024*1024;
|
2017-10-26 11:32:49 +03:00
|
|
|
th->ec->machine.stack_start = (VALUE *)end - 1;
|
|
|
|
th->ec->machine.stack_maxsize = size - space;
|
2008-06-14 06:59:19 +04:00
|
|
|
}
|
|
|
|
|
2010-01-04 03:30:52 +03:00
|
|
|
#ifndef InterlockedExchangePointer
|
|
|
|
#define InterlockedExchangePointer(t, v) \
|
|
|
|
(void *)InterlockedExchange((long *)(t), (long)(v))
|
|
|
|
#endif
|
2007-02-08 23:24:55 +03:00
|
|
|
static void
|
2023-10-12 19:14:17 +03:00
|
|
|
native_thread_destroy(struct rb_native_thread *nt)
|
2007-02-08 23:24:55 +03:00
|
|
|
{
|
2023-10-12 19:14:17 +03:00
|
|
|
if (nt) {
|
|
|
|
HANDLE intr = InterlockedExchangePointer(&nt->interrupt_event, 0);
|
|
|
|
RUBY_DEBUG_LOG("close handle intr:%p, thid:%p\n", intr, nt->thread_id);
|
|
|
|
w32_close_handle(intr);
|
|
|
|
}
|
2007-02-08 23:24:55 +03:00
|
|
|
}
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2013-07-08 18:12:26 +04:00
|
|
|
static unsigned long __stdcall
|
2006-12-31 18:02:22 +03:00
|
|
|
thread_start_func_1(void *th_ptr)
|
|
|
|
{
|
* blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
eval_jump.h, eval_load.c, eval_safe.h, gc.c, proc.c, signal.c,
thread.c, thread_pthread.ci, thread_win32.ci, vm.c, vm.h,
vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fix typo (rb_thead_t -> rb_thread_t).
* eval_intern.h: remove unused definitions.
* common.mk: fix around vm_opts.h path
and remove harmful argument passed to insns2vm.rb.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11658 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-08 09:37:46 +03:00
|
|
|
rb_thread_t *th = th_ptr;
|
2022-04-22 15:19:03 +03:00
|
|
|
volatile HANDLE thread_id = th->nt->thread_id;
|
2007-02-09 06:42:46 +03:00
|
|
|
|
Pass down "stack start" variables from closer to the top of the stack
This commit changes how stack extents are calculated for both the main
thread and other threads. Ruby uses the address of a local variable as
part of the calculation for machine stack extents:
* pthreads uses it as a lower-bound on the start of the stack, because
glibc (and maybe other libcs) can store its own data on the stack
before calling into user code on thread creation.
* win32 uses it as an argument to VirtualQuery, which gets the extent of
the memory mapping which contains the variable
However, the local being used for this is actually too low (too close to
the leaf function call) in both the main thread case and the new thread
case.
In the main thread case, we have the `INIT_STACK` macro, which is used
for pthreads to set the `native_main_thread->stack_start` value. This
value is correctly captured at the very top level of the program (in
main.c). However, this is _not_ what's used to set the execution context
machine stack (`th->ec->machine_stack.stack_start`); that gets set as
part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the
address of a local variable allocated _inside_ `Init_BareVM`. This is
too low; we need to use a local allocated closer to the top of the
program.
In the new thread case, the lolcal is allocated inside
`native_thread_init_stack`, which is, again, too low.
In both cases, this means that we might have VALUEs lying outside the
bounds of `th->ec->machine.stack_{start,end}`, which won't be marked
correctly by the GC machinery.
To fix this,
* In the main thread case: We already have `INIT_STACK` at the right
level, so just pass that local var to `ruby_thread_init_stack`.
* In the new thread case: Allocate the local one level above the call to
`native_thread_init_stack` in `call_thread_start_func2`.
[Bug #20001]
fix
2023-11-12 05:24:55 +03:00
|
|
|
native_thread_init_stack(th, &th);
|
2022-04-22 15:19:03 +03:00
|
|
|
th->nt->interrupt_event = CreateEvent(0, TRUE, FALSE, 0);
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2007-02-09 06:42:46 +03:00
|
|
|
/* run */
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("thread created th:%u, thid: %p, event: %p",
|
|
|
|
rb_th_serial(th), th->nt->thread_id, th->nt->interrupt_event);
|
2008-11-06 16:21:26 +03:00
|
|
|
|
2023-04-10 04:53:13 +03:00
|
|
|
thread_sched_to_running(TH_SCHED(th), th);
|
|
|
|
ruby_thread_set_native(th);
|
|
|
|
|
|
|
|
// kick threads
|
2019-06-19 12:06:57 +03:00
|
|
|
thread_start_func_2(th, th->ec->machine.stack_start);
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2007-02-09 06:42:46 +03:00
|
|
|
w32_close_handle(thread_id);
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("thread deleted th:%u", rb_th_serial(th));
|
2023-04-10 04:53:13 +03:00
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
* blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
eval_jump.h, eval_load.c, eval_safe.h, gc.c, proc.c, signal.c,
thread.c, thread_pthread.ci, thread_win32.ci, vm.c, vm.h,
vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fix typo (rb_thead_t -> rb_thread_t).
* eval_intern.h: remove unused definitions.
* common.mk: fix around vm_opts.h path
and remove harmful argument passed to insns2vm.rb.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11658 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-08 09:37:46 +03:00
|
|
|
native_thread_create(rb_thread_t *th)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2023-04-10 04:53:13 +03:00
|
|
|
// setup nt
|
|
|
|
const size_t stack_size = th->vm->default_params.thread_machine_stack_size;
|
2022-04-22 15:19:03 +03:00
|
|
|
th->nt = ZALLOC(struct rb_native_thread);
|
|
|
|
th->nt->thread_id = w32_create_thread(stack_size, thread_start_func_1, th);
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2023-04-10 04:53:13 +03:00
|
|
|
// setup vm stack
|
|
|
|
size_t vm_stack_word_size = th->vm->default_params.thread_vm_stack_size / sizeof(VALUE);
|
|
|
|
void *vm_stack = ruby_xmalloc(vm_stack_word_size * sizeof(VALUE));
|
|
|
|
th->sched.vm_stack = vm_stack;
|
|
|
|
rb_ec_initialize_vm_stack(th->ec, vm_stack, vm_stack_word_size);
|
|
|
|
|
2022-04-22 15:19:03 +03:00
|
|
|
if ((th->nt->thread_id) == 0) {
|
2009-11-12 08:33:23 +03:00
|
|
|
return thread_errno;
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
2007-02-09 06:42:46 +03:00
|
|
|
|
2022-04-22 15:19:03 +03:00
|
|
|
w32_resume_thread(th->nt->thread_id);
|
2007-02-09 06:42:46 +03:00
|
|
|
|
2022-05-23 21:58:18 +03:00
|
|
|
if (USE_RUBY_DEBUG_LOG) {
|
|
|
|
Sleep(0);
|
|
|
|
RUBY_DEBUG_LOG("th:%u thid:%p intr:%p), stack size: %"PRIuSIZE"",
|
|
|
|
rb_th_serial(th), th->nt->thread_id,
|
|
|
|
th->nt->interrupt_event, stack_size);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-01-07 12:47:52 +03:00
|
|
|
static void
|
|
|
|
native_thread_join(HANDLE th)
|
|
|
|
{
|
2010-08-02 11:35:35 +04:00
|
|
|
w32_wait_events(&th, 1, INFINITE, 0);
|
2007-01-07 12:47:52 +03:00
|
|
|
}
|
|
|
|
|
2008-08-13 11:53:35 +04:00
|
|
|
#if USE_NATIVE_THREAD_PRIORITY
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
static void
|
* blockinlining.c, error.c, eval.c, eval_error.h, eval_intern.h,
eval_jump.h, eval_load.c, eval_safe.h, gc.c, proc.c, signal.c,
thread.c, thread_pthread.ci, thread_win32.ci, vm.c, vm.h,
vm_dump.c, vm_evalbody.ci, yarvcore.c, yarvcore.h:
fix typo (rb_thead_t -> rb_thread_t).
* eval_intern.h: remove unused definitions.
* common.mk: fix around vm_opts.h path
and remove harmful argument passed to insns2vm.rb.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11658 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-02-08 09:37:46 +03:00
|
|
|
native_thread_apply_priority(rb_thread_t *th)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
|
|
|
int priority = th->priority;
|
|
|
|
if (th->priority > 0) {
|
|
|
|
priority = THREAD_PRIORITY_ABOVE_NORMAL;
|
|
|
|
}
|
|
|
|
else if (th->priority < 0) {
|
|
|
|
priority = THREAD_PRIORITY_BELOW_NORMAL;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
priority = THREAD_PRIORITY_NORMAL;
|
|
|
|
}
|
|
|
|
|
2022-04-22 15:19:03 +03:00
|
|
|
SetThreadPriority(th->nt->thread_id, priority);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
|
2008-08-13 11:53:35 +04:00
|
|
|
#endif /* USE_NATIVE_THREAD_PRIORITY */
|
|
|
|
|
2011-06-15 22:04:13 +04:00
|
|
|
int rb_w32_select_with_thread(int, fd_set *, fd_set *, fd_set *, struct timeval *, void *); /* @internal */
|
|
|
|
|
|
|
|
static int
|
|
|
|
native_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout, rb_thread_t *th)
|
|
|
|
{
|
|
|
|
fd_set *r = NULL, *w = NULL, *e = NULL;
|
|
|
|
if (readfds) {
|
|
|
|
rb_fd_resize(n - 1, readfds);
|
|
|
|
r = rb_fd_ptr(readfds);
|
|
|
|
}
|
|
|
|
if (writefds) {
|
|
|
|
rb_fd_resize(n - 1, writefds);
|
|
|
|
w = rb_fd_ptr(writefds);
|
|
|
|
}
|
|
|
|
if (exceptfds) {
|
|
|
|
rb_fd_resize(n - 1, exceptfds);
|
|
|
|
e = rb_fd_ptr(exceptfds);
|
|
|
|
}
|
|
|
|
return rb_w32_select_with_thread(n, r, w, e, timeout, th);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* @internal */
|
|
|
|
int
|
|
|
|
rb_w32_check_interrupt(rb_thread_t *th)
|
|
|
|
{
|
|
|
|
return w32_wait_events(0, 0, 0, th);
|
|
|
|
}
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
static void
|
2007-11-20 13:47:53 +03:00
|
|
|
ubf_handle(void *ptr)
|
2006-12-31 18:02:22 +03:00
|
|
|
{
|
2007-11-20 13:47:53 +03:00
|
|
|
rb_thread_t *th = (rb_thread_t *)ptr;
|
2022-05-23 21:58:18 +03:00
|
|
|
RUBY_DEBUG_LOG("th:%u\n", rb_th_serial(th));
|
2008-07-15 13:14:09 +04:00
|
|
|
|
2022-04-22 15:19:03 +03:00
|
|
|
if (!SetEvent(th->nt->interrupt_event)) {
|
2017-04-16 17:27:21 +03:00
|
|
|
w32_error("ubf_handle");
|
|
|
|
}
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
|
2017-08-26 03:30:03 +03:00
|
|
|
int rb_w32_set_thread_description(HANDLE th, const WCHAR *name);
|
|
|
|
int rb_w32_set_thread_description_str(HANDLE th, VALUE name);
|
|
|
|
#define native_set_another_thread_name rb_w32_set_thread_description_str
|
|
|
|
|
2014-06-11 12:37:44 +04:00
|
|
|
static struct {
|
|
|
|
HANDLE id;
|
|
|
|
HANDLE lock;
|
|
|
|
} timer_thread;
|
|
|
|
#define TIMER_THREAD_CREATED_P() (timer_thread.id != 0)
|
2006-12-31 18:02:22 +03:00
|
|
|
|
2013-07-08 18:12:26 +04:00
|
|
|
static unsigned long __stdcall
|
2006-12-31 18:02:22 +03:00
|
|
|
timer_thread_func(void *dummy)
|
|
|
|
{
|
2018-08-14 00:34:20 +03:00
|
|
|
rb_vm_t *vm = GET_VM();
|
2022-07-28 10:50:26 +03:00
|
|
|
RUBY_DEBUG_LOG("start");
|
2017-08-26 03:30:03 +03:00
|
|
|
rb_w32_set_thread_description(GetCurrentThread(), L"ruby-timer-thread");
|
2020-11-11 08:37:31 +03:00
|
|
|
while (WaitForSingleObject(timer_thread.lock,
|
|
|
|
TIME_QUANTUM_USEC/1000) == WAIT_TIMEOUT) {
|
|
|
|
vm->clock++;
|
2020-03-09 20:22:11 +03:00
|
|
|
rb_threadptr_check_signal(vm->ractor.main_thread);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
2022-07-28 10:50:26 +03:00
|
|
|
RUBY_DEBUG_LOG("end");
|
2006-12-31 18:02:22 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-06-27 04:30:41 +04:00
|
|
|
void
|
2018-08-14 00:34:20 +03:00
|
|
|
rb_thread_wakeup_timer_thread(int sig)
|
2011-06-27 04:30:41 +04:00
|
|
|
{
|
|
|
|
/* do nothing */
|
|
|
|
}
|
|
|
|
|
2008-11-06 16:21:26 +03:00
|
|
|
static void
|
2006-12-31 18:02:22 +03:00
|
|
|
rb_thread_create_timer_thread(void)
|
|
|
|
{
|
2014-06-11 12:37:44 +04:00
|
|
|
if (timer_thread.id == 0) {
|
|
|
|
if (!timer_thread.lock) {
|
|
|
|
timer_thread.lock = CreateEvent(0, TRUE, FALSE, 0);
|
2008-11-06 16:21:26 +03:00
|
|
|
}
|
2022-05-23 21:58:18 +03:00
|
|
|
timer_thread.id = w32_create_thread(1024 + (USE_RUBY_DEBUG_LOG ? BUFSIZ : 0),
|
|
|
|
timer_thread_func, 0);
|
2014-06-11 12:37:44 +04:00
|
|
|
w32_resume_thread(timer_thread.id);
|
2006-12-31 18:02:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-08 18:31:05 +03:00
|
|
|
static int
|
2015-08-14 12:44:10 +03:00
|
|
|
native_stop_timer_thread(void)
|
2008-11-08 18:31:05 +03:00
|
|
|
{
|
|
|
|
int stopped = --system_working <= 0;
|
|
|
|
if (stopped) {
|
2014-06-11 12:37:44 +04:00
|
|
|
SetEvent(timer_thread.lock);
|
|
|
|
native_thread_join(timer_thread.id);
|
|
|
|
CloseHandle(timer_thread.lock);
|
|
|
|
timer_thread.lock = 0;
|
2008-11-08 18:31:05 +03:00
|
|
|
}
|
|
|
|
return stopped;
|
|
|
|
}
|
2008-11-06 16:21:26 +03:00
|
|
|
|
2009-11-02 06:58:25 +03:00
|
|
|
static void
|
|
|
|
native_reset_timer_thread(void)
|
|
|
|
{
|
2014-06-11 12:37:44 +04:00
|
|
|
if (timer_thread.id) {
|
|
|
|
CloseHandle(timer_thread.id);
|
|
|
|
timer_thread.id = 0;
|
2009-11-02 06:58:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-21 10:33:41 +04:00
|
|
|
int
|
|
|
|
ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr)
|
|
|
|
{
|
2017-11-07 08:22:09 +03:00
|
|
|
return rb_ec_raised_p(th->ec, RAISED_STACKOVERFLOW);
|
2013-11-21 10:33:41 +04:00
|
|
|
}
|
|
|
|
|
2014-05-15 12:32:55 +04:00
|
|
|
#if defined(__MINGW32__)
|
|
|
|
LONG WINAPI
|
|
|
|
rb_w32_stack_overflow_handler(struct _EXCEPTION_POINTERS *exception)
|
|
|
|
{
|
|
|
|
if (exception->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
|
2017-11-07 08:22:09 +03:00
|
|
|
rb_ec_raised_set(GET_EC(), RAISED_STACKOVERFLOW);
|
2014-05-15 12:32:55 +04:00
|
|
|
raise(SIGSEGV);
|
|
|
|
}
|
|
|
|
return EXCEPTION_CONTINUE_SEARCH;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2010-10-26 13:09:45 +04:00
|
|
|
#ifdef RUBY_ALLOCA_CHKSTK
|
|
|
|
void
|
|
|
|
ruby_alloca_chkstk(size_t len, void *sp)
|
|
|
|
{
|
|
|
|
if (ruby_stack_length(NULL) * sizeof(VALUE) >= len) {
|
2017-11-07 08:22:09 +03:00
|
|
|
rb_execution_context_t *ec = GET_EC();
|
|
|
|
if (!rb_ec_raised_p(ec, RAISED_STACKOVERFLOW)) {
|
|
|
|
rb_ec_raised_set(ec, RAISED_STACKOVERFLOW);
|
2010-10-26 13:09:45 +04:00
|
|
|
rb_exc_raise(sysstack_error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2011-07-04 01:56:59 +04:00
|
|
|
int
|
|
|
|
rb_reserved_fd_p(int fd)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2013-07-23 14:46:37 +04:00
|
|
|
|
|
|
|
rb_nativethread_id_t
|
|
|
|
rb_nativethread_self(void)
|
|
|
|
{
|
|
|
|
return GetCurrentThread();
|
|
|
|
}
|
|
|
|
|
2014-09-21 09:14:47 +04:00
|
|
|
static void
|
|
|
|
native_set_thread_name(rb_thread_t *th)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2021-05-22 15:36:27 +03:00
|
|
|
static VALUE
|
|
|
|
native_thread_native_thread_id(rb_thread_t *th)
|
|
|
|
{
|
2022-04-22 15:19:03 +03:00
|
|
|
DWORD tid = GetThreadId(th->nt->thread_id);
|
2021-05-22 15:36:27 +03:00
|
|
|
if (tid == 0) rb_sys_fail("GetThreadId");
|
|
|
|
return ULONG2NUM(tid);
|
|
|
|
}
|
2021-06-01 16:27:13 +03:00
|
|
|
#define USE_NATIVE_THREAD_NATIVE_THREAD_ID 1
|
2021-05-22 15:36:27 +03:00
|
|
|
|
2023-04-10 04:53:13 +03:00
|
|
|
void
|
|
|
|
rb_add_running_thread(rb_thread_t *th){
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_del_running_thread(rb_thread_t *th)
|
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
th_has_dedicated_nt(const rb_thread_t *th)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_threadptr_sched_free(rb_thread_t *th)
|
|
|
|
{
|
2023-10-12 19:14:17 +03:00
|
|
|
native_thread_destroy(th->nt);
|
2023-04-10 04:53:13 +03:00
|
|
|
ruby_xfree(th->nt);
|
|
|
|
ruby_xfree(th->sched.vm_stack);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_threadptr_remove(rb_thread_t *th)
|
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_thread_sched_mark_zombies(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
vm_barrier_finish_p(rb_vm_t *vm)
|
|
|
|
{
|
|
|
|
RUBY_DEBUG_LOG("cnt:%u living:%u blocking:%u",
|
|
|
|
vm->ractor.blocking_cnt == vm->ractor.cnt,
|
|
|
|
vm->ractor.sync.barrier_cnt,
|
|
|
|
vm->ractor.cnt,
|
|
|
|
vm->ractor.blocking_cnt);
|
|
|
|
|
|
|
|
VM_ASSERT(vm->ractor.blocking_cnt <= vm->ractor.cnt);
|
|
|
|
return vm->ractor.blocking_cnt == vm->ractor.cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_ractor_sched_barrier_start(rb_vm_t *vm, rb_ractor_t *cr)
|
|
|
|
{
|
|
|
|
vm->ractor.sync.barrier_waiting = true;
|
|
|
|
|
|
|
|
RUBY_DEBUG_LOG("barrier start. cnt:%u living:%u blocking:%u",
|
|
|
|
vm->ractor.sync.barrier_cnt,
|
|
|
|
vm->ractor.cnt,
|
|
|
|
vm->ractor.blocking_cnt);
|
|
|
|
|
|
|
|
rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
|
|
|
|
|
|
|
|
// send signal
|
|
|
|
rb_ractor_t *r = 0;
|
|
|
|
ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
|
|
|
|
if (r != cr) {
|
|
|
|
rb_ractor_vm_barrier_interrupt_running_thread(r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait
|
|
|
|
while (!vm_barrier_finish_p(vm)) {
|
|
|
|
rb_vm_cond_wait(vm, &vm->ractor.sync.barrier_cond);
|
|
|
|
}
|
|
|
|
|
|
|
|
RUBY_DEBUG_LOG("cnt:%u barrier success", vm->ractor.sync.barrier_cnt);
|
|
|
|
|
|
|
|
rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
|
|
|
|
|
|
|
|
vm->ractor.sync.barrier_waiting = false;
|
|
|
|
vm->ractor.sync.barrier_cnt++;
|
|
|
|
|
|
|
|
ccan_list_for_each(&vm->ractor.set, r, vmlr_node) {
|
|
|
|
rb_native_cond_signal(&r->barrier_wait_cond);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rb_ractor_sched_barrier_join(rb_vm_t *vm, rb_ractor_t *cr)
|
|
|
|
{
|
|
|
|
vm->ractor.sync.lock_owner = cr;
|
|
|
|
unsigned int barrier_cnt = vm->ractor.sync.barrier_cnt;
|
|
|
|
rb_thread_t *th = GET_THREAD();
|
|
|
|
bool running;
|
|
|
|
|
|
|
|
RB_VM_SAVE_MACHINE_CONTEXT(th);
|
|
|
|
|
|
|
|
if (rb_ractor_status_p(cr, ractor_running)) {
|
|
|
|
rb_vm_ractor_blocking_cnt_inc(vm, cr, __FILE__, __LINE__);
|
|
|
|
running = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
VM_ASSERT(rb_ractor_status_p(cr, ractor_blocking));
|
|
|
|
|
|
|
|
if (vm_barrier_finish_p(vm)) {
|
|
|
|
RUBY_DEBUG_LOG("wakeup barrier owner");
|
|
|
|
rb_native_cond_signal(&vm->ractor.sync.barrier_cond);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
RUBY_DEBUG_LOG("wait for barrier finish");
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait for restart
|
|
|
|
while (barrier_cnt == vm->ractor.sync.barrier_cnt) {
|
|
|
|
vm->ractor.sync.lock_owner = NULL;
|
|
|
|
rb_native_cond_wait(&cr->barrier_wait_cond, &vm->ractor.sync.lock);
|
|
|
|
VM_ASSERT(vm->ractor.sync.lock_owner == NULL);
|
|
|
|
vm->ractor.sync.lock_owner = cr;
|
|
|
|
}
|
|
|
|
|
|
|
|
RUBY_DEBUG_LOG("barrier is released. Acquire vm_lock");
|
|
|
|
|
|
|
|
if (running) {
|
|
|
|
rb_vm_ractor_blocking_cnt_dec(vm, cr, __FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
|
|
|
|
vm->ractor.sync.lock_owner = NULL;
|
|
|
|
}
|
|
|
|
|
2024-02-20 13:09:23 +03:00
|
|
|
bool
|
|
|
|
rb_thread_lock_native_thread(void)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2024-05-29 17:46:04 +03:00
|
|
|
void *
|
|
|
|
rb_thread_prevent_fork(void *(*func)(void *), void *data)
|
|
|
|
{
|
|
|
|
return func(data);
|
|
|
|
}
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
#endif /* THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION */
|