summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-11-13 07:28:24 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-11-13 07:28:24 +0000
commiteda80cb6098ed85b1ea6f91bce59f9907f396d09 (patch)
tree4f3b148cca74619ae27a115e1988ce573e8ee426
parent7d5a6908c087410383ae2314c91ba4e78e278e4c (diff)
downloadruby-eda80cb6098ed85b1ea6f91bce59f9907f396d09.tar.gz
* thread.c (ruby_native_thread_create): start new thread with
rb_thread_t. split from thread_create_core. * vm.c (rb_vm_start, rb_vm_join): new methods, #start and #join. * vm.c (vm_make_main_thread): make bare main thread. split from ruby_make_bare_vm. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/mvm@25749 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog10
-rw-r--r--eval_intern.h11
-rw-r--r--thread.c26
-rw-r--r--vm.c79
4 files changed, 101 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index f487cb81e8..b056f83e7a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Nov 13 16:28:22 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * thread.c (ruby_native_thread_create): start new thread with
+ rb_thread_t. split from thread_create_core.
+
+ * vm.c (rb_vm_start, rb_vm_join): new methods, #start and #join.
+
+ * vm.c (vm_make_main_thread): make bare main thread. split from
+ ruby_make_bare_vm.
+
Fri Nov 13 16:22:00 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* thread.c (thread_start_func_2): see first_func, not first_proc,
diff --git a/eval_intern.h b/eval_intern.h
index 17a8e103bb..5caf65b140 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -216,16 +216,17 @@ void rb_trap_restore_mask(void);
VALUE ruby_vm_argf(rb_vm_t *vm);
+int ruby_native_thread_create(rb_thread_t *);
void ruby_native_thread_lock_initialize(rb_thread_lock_t *lock);
void ruby_native_thread_lock_destroy(rb_thread_lock_t *lock);
void ruby_native_thread_lock(rb_thread_lock_t *lock);
void ruby_native_thread_unlock(rb_thread_lock_t *lock);
void ruby_native_thread_yield(void);
-void ruby_native_cond_signal(pthread_cond_t *cond);
-void ruby_native_cond_broadcast(pthread_cond_t *cond);
-void ruby_native_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
-void ruby_native_cond_initialize(pthread_cond_t *cond);
-void ruby_native_cond_destroy(pthread_cond_t *cond);
+void ruby_native_cond_signal(rb_thread_cond_t *cond);
+void ruby_native_cond_broadcast(rb_thread_cond_t *cond);
+void ruby_native_cond_wait(rb_thread_cond_t *cond, rb_thread_lock_t *mutex);
+void ruby_native_cond_initialize(rb_thread_cond_t *cond);
+void ruby_native_cond_destroy(rb_thread_cond_t *cond);
VALUE ruby_vm_get_argv(rb_vm_t *vm);
const char *ruby_vm_get_inplace_mode(rb_vm_t *vm);
diff --git a/thread.c b/thread.c
index 27f3ef2694..f2a22ae1c1 100644
--- a/thread.c
+++ b/thread.c
@@ -417,6 +417,21 @@ ruby_thread_init_stack(rb_thread_t *th)
native_thread_init_stack(th);
}
+int
+ruby_native_thread_create(rb_thread_t *th)
+{
+ native_mutex_initialize(&th->interrupt_lock);
+ th->priority = GET_THREAD()->priority;
+ th->thgroup = GET_THREAD()->thgroup;
+
+#ifdef HAVE_FCHDIR
+ th->cwd.fd = ruby_dirfd(".");
+#else
+ th->cwd.path = rb_str_new_shared(GET_THREAD()->cwd.path);
+#endif
+ return native_thread_create(th);
+}
+
static int
thread_start_func_2(rb_thread_t *th, VALUE *stack_start, VALUE *register_stack_start)
{
@@ -548,18 +563,9 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS))
th->first_proc = fn ? Qfalse : rb_block_proc();
th->first_args = args; /* GC: shouldn't put before above line */
- th->priority = GET_THREAD()->priority;
- th->thgroup = GET_THREAD()->thgroup;
-
- native_mutex_initialize(&th->interrupt_lock);
/* kick thread */
st_insert(th->vm->living_threads, thval, (st_data_t) th->thread_id);
-#ifdef HAVE_FCHDIR
- th->cwd.fd = ruby_dirfd(".");
-#else
- th->cwd.path = rb_str_new_shared(GET_THREAD()->cwd.path);
-#endif
- err = native_thread_create(th);
+ err = ruby_native_thread_create(th);
if (err) {
st_delete_wrap(th->vm->living_threads, th->self);
th->status = THREAD_KILLED;
diff --git a/vm.c b/vm.c
index 9688357f7f..7a1f69c15c 100644
--- a/vm.c
+++ b/vm.c
@@ -1739,6 +1739,11 @@ thread_alloc(VALUE klass)
rb_thread_t *th;
obj = TypedData_Make_Struct(klass, rb_thread_t, &thread_data_type, th);
#endif
+
+#ifdef HAVE_FCHDIR
+ th->cwd.fd = -1;
+#endif
+
return obj;
}
@@ -1966,15 +1971,15 @@ rb_vm_initialize(int argc, VALUE *argv, VALUE self)
--argc;
vm_parse_opt(vm, opt);
}
- if (argc > 0) {
+ if ((vm->argc = argc) > 0) {
int i;
char **args, *argp;
VALUE argsval = 0;
- size_t len = rb_long2int(argc * sizeof(char *)), total = 0;
+ size_t len = rb_long2int(argc * sizeof(char *));
for (i = 0; i < argc; ++i) {
StringValue(argv[i]);
argv[i] = rb_str_new_frozen(argv[i]);
- rb_long2int(total += RSTRING_LEN(argv[i]) + 1);
+ rb_long2int(len += RSTRING_LEN(argv[i]) + 1);
}
args = rb_objspace_xmalloc(vm->objspace, len);
argsval = rb_str_wrap((char *)args, len);
@@ -1991,6 +1996,45 @@ rb_vm_initialize(int argc, VALUE *argv, VALUE self)
return self;
}
+static rb_thread_t *vm_make_main_thread(rb_vm_t *vm);
+
+static VALUE
+vm_create(void *arg)
+{
+ rb_vm_t *vm = arg;
+
+ ruby_native_thread_lock(&vm->global_vm_lock);
+ return (VALUE)ruby_vm_run(vm, 0);
+}
+
+static VALUE
+rb_vm_start(VALUE self)
+{
+ rb_vm_t *vm;
+ rb_thread_t *th;
+
+ GetVMPtr(self, vm);
+ if (vm->main_thread) rb_raise(rb_eArgError, "alread started");
+ th = vm_make_main_thread(vm);
+ th->first_func = vm_create;
+ th->first_proc = Qfalse;
+ th->first_args = (VALUE)vm;
+ ruby_native_thread_create(th);
+ ruby_native_thread_unlock(&vm->global_vm_lock);
+ return self;
+}
+
+static VALUE
+rb_vm_join(VALUE self)
+{
+ rb_vm_t *vm;
+ int status;
+
+ GetVMPtr(self, vm);
+ status = ruby_vm_join(vm);
+ return INT2NUM(status);
+}
+
void
Init_VM(void)
{
@@ -2007,6 +2051,8 @@ InitVM_VM(void)
rb_cRubyVM = rb_define_class("RubyVM", rb_cObject);
rb_define_alloc_func(rb_cRubyVM, rb_vm_s_alloc);
rb_define_method(rb_cRubyVM, "initialize", rb_vm_initialize, -1);
+ rb_define_method(rb_cRubyVM, "start", rb_vm_start, 0);
+ rb_define_method(rb_cRubyVM, "join", rb_vm_join, 0);
/* ::VM::FrozenCore */
fcore = rb_class_new(rb_cBasicObject);
@@ -2102,12 +2148,16 @@ InitVM_VM(void)
rb_gc_register_mark_object(iseqval);
#ifdef HAVE_FCHDIR
+ if (th->cwd.fd == -1) {
# ifdef AT_FDCWD
- th->cwd.fd = AT_FDCWD;
+ th->cwd.fd = AT_FDCWD;
# endif
- th->cwd.fd = ruby_dirfd(".");
+ th->cwd.fd = ruby_dirfd(".");
+ }
#else
- th->cwd.path = ruby_getcwd();
+ if (!th->cwd.path) {
+ th->cwd.path = rb_str_new_cstr(ruby_getcwd());
+ }
#endif
GetISeqPtr(iseqval, iseq);
th->cfp->iseq = iseq;
@@ -2143,16 +2193,25 @@ ruby_make_bare_vm(void)
vm_init2(vm);
+ th = vm_make_main_thread(vm);
+ rb_thread_set_current_raw(th);
+ ruby_thread_init_stack(th);
+
+ return vm;
+}
+
+static rb_thread_t *
+vm_make_main_thread(rb_vm_t *vm)
+{
+ rb_thread_t *th;
+
th = rb_objspace_xmalloc(vm->objspace, sizeof(*th));
MEMZERO(th, rb_thread_t, 1);
th->vm = vm;
- rb_thread_set_current_raw(th);
vm->main_thread = th;
-
th_init(th, 0);
- ruby_thread_init_stack(th);
- return vm;
+ return th;
}
rb_vm_t *