diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-09-26 00:47:18 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-09-26 00:47:18 +0000 |
commit | 18684d9f7cb64b93ec610f1c1deeabcfea364c08 (patch) | |
tree | 77faa9f8cf1601f672e720f5dcbe8936aebcf5b1 | |
parent | 3ceca921fc904e520131e81f17c66d344e117790 (diff) | |
download | ruby-18684d9f7cb64b93ec610f1c1deeabcfea364c08.tar.gz |
* 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-- | ChangeLog | 6 | ||||
-rw-r--r-- | include/rubysig.h | 34 | ||||
-rw-r--r-- | thread.c | 69 |
3 files changed, 96 insertions, 13 deletions
@@ -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 @@ -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, ®ion->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, ®ion->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. * |