From 18684d9f7cb64b93ec610f1c1deeabcfea364c08 Mon Sep 17 00:00:00 2001 From: nobu Date: Fri, 26 Sep 2008 00:47:18 +0000 Subject: * 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 --- ChangeLog | 6 +++++ include/rubysig.h | 34 ++++++++++++++++++++++++++- thread.c | 69 +++++++++++++++++++++++++++++++++++++++++++++---------- 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 + + * 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 * 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, ®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. * -- cgit v1.2.3