summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-09-26 00:47:18 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-09-26 00:47:18 +0000
commit18684d9f7cb64b93ec610f1c1deeabcfea364c08 (patch)
tree77faa9f8cf1601f672e720f5dcbe8936aebcf5b1
parent3ceca921fc904e520131e81f17c66d344e117790 (diff)
* include/rubysig.h: old macros for backward compatibility.
* thread.c (BLOCKING_REGION): rewritten using helper functions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19562 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--include/rubysig.h34
-rw-r--r--thread.c69
3 files changed, 96 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index bdb55b7388..81c574b79f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Sep 26 09:47:15 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * include/rubysig.h: old macros for backward compatibility.
+
+ * thread.c (BLOCKING_REGION): rewritten using helper functions.
+
Fri Sep 26 03:03:32 2008 Tanaka Akira <akr@fsij.org>
* vm_eval.c (Init_vm_eval): define module_eval, class_eval and eval
diff --git a/include/rubysig.h b/include/rubysig.h
index 9546127938..6a0cf0ef9c 100644
--- a/include/rubysig.h
+++ b/include/rubysig.h
@@ -1 +1,33 @@
-#include "ruby/signal.h"
+/**********************************************************************
+
+ rubysig.h -
+
+ $Author$
+ $Date$
+ created at: Wed Aug 16 01:15:38 JST 1995
+
+ Copyright (C) 1993-2008 Yukihiro Matsumoto
+
+**********************************************************************/
+
+#if defined __GNUC__
+#warning rubysig.h is obsolete
+#elif defined _MSC_VER || defined __BORLANDC__
+#pragma message("warning: rubysig.h is obsolete")
+#endif
+
+#ifndef RUBYSIG_H
+#define RUBYSIG_H
+#include "ruby/ruby.h"
+
+struct rb_blocking_region_buffer;
+RUBY_EXTERN struct rb_blocking_region_buffer *rb_thread_blocking_region_begin(void);
+RUBY_EXTERN void rb_thread_blocking_region_end(struct rb_blocking_region_buffer *);
+#define TRAP_BEG do {void *__region = rb_thread_blocking_region_begin(void);
+#define TRAP_END rb_thread_blocking_region_end(__region);} while (0)
+#define RUBY_CRITICAL(statements) do {statements;} while (0)
+#define DEFER_INTS (0)
+#define ENABLE_INTS (1)
+#define ALLOW_INTS do {CHECK_INTS;} while (0)
+#define CHECK_INTS rb_thread_check_ints()
+#endif
diff --git a/thread.c b/thread.c
index 70b369a164..964fb7c60a 100644
--- a/thread.c
+++ b/thread.c
@@ -86,10 +86,19 @@ st_delete_wrap(st_table *table, st_data_t key)
#define THREAD_SYSTEM_DEPENDENT_IMPLEMENTATION
+struct rb_blocking_region_buffer {
+ enum rb_thread_status prev_status;
+ struct rb_unblock_callback oldubf;
+};
+
static void set_unblock_function(rb_thread_t *th, rb_unblock_function_t *func, void *arg,
struct rb_unblock_callback *old);
static void reset_unblock_function(rb_thread_t *th, const struct rb_unblock_callback *old);
+static void blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer *region,
+ rb_unblock_function_t *func, void *arg);
+static void blocking_region_end(rb_thread_t *th, struct rb_blocking_region_buffer *region);
+
#define GVL_UNLOCK_BEGIN() do { \
rb_thread_t *_th_stored = GET_THREAD(); \
rb_gc_save_machine_context(_th_stored); \
@@ -109,18 +118,10 @@ static void reset_unblock_function(rb_thread_t *th, const struct rb_unblock_call
#define BLOCKING_REGION(exec, ubf, ubfarg) do { \
rb_thread_t *__th = GET_THREAD(); \
- enum rb_thread_status __prev_status = __th->status; \
- struct rb_unblock_callback __oldubf; \
- set_unblock_function(__th, ubf, ubfarg, &__oldubf); \
- __th->status = THREAD_STOPPED; \
- thread_debug("enter blocking region (%p)\n", __th); \
- BLOCKING_REGION_CORE(exec); \
- thread_debug("leave blocking region (%p)\n", __th); \
- remove_signal_thread_list(__th); \
- reset_unblock_function(__th, &__oldubf); \
- if (__th->status == THREAD_STOPPED) { \
- __th->status = __prev_status; \
- } \
+ struct rb_blocking_region_buffer __region; \
+ blocking_region_begin(__th, &__region, ubf, ubfarg); \
+ exec; \
+ blocking_region_end(__th, &__region); \
RUBY_VM_CHECK_INTS(); \
} while(0)
@@ -939,6 +940,50 @@ rb_thread_schedule(void)
}
}
+/* blocking region */
+static inline void
+blocking_region_begin(rb_thread_t *th, struct rb_blocking_region_buffer *region,
+ rb_unblock_function_t *func, void *arg)
+{
+ region->prev_status = th->status;
+ set_unblock_function(th, func, arg, &region->oldubf);
+ th->status = THREAD_STOPPED;
+ thread_debug("enter blocking region (%p)\n", th);
+ rb_gc_save_machine_context(th);
+ native_mutex_unlock(&th->vm->global_vm_lock);
+}
+
+static inline void
+blocking_region_end(rb_thread_t *th, struct rb_blocking_region_buffer *region)
+{
+ native_mutex_lock(&th->vm->global_vm_lock);
+ rb_thread_set_current(th);
+ thread_debug("leave blocking region (%p)\n", th);
+ remove_signal_thread_list(th);
+ reset_unblock_function(th, &region->oldubf);
+ if (th->status == THREAD_STOPPED) {
+ th->status = region->prev_status;
+ }
+}
+
+struct rb_blocking_region_buffer *
+rb_thread_blocking_region_begin(void)
+{
+ rb_thread_t *th = GET_THREAD();
+ struct rb_blocking_region_buffer *region = ALLOC(struct rb_blocking_region_buffer);
+ blocking_region_begin(th, region, ubf_select, th);
+ return region;
+}
+
+void
+rb_thread_blocking_region_end(struct rb_blocking_region_buffer *region)
+{
+ rb_thread_t *th = GET_THREAD();
+ blocking_region_end(th, region);
+ xfree(region);
+ RUBY_VM_CHECK_INTS();
+}
+
/*
* rb_thread_blocking_region - permit concurrent/parallel execution.
*