mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
3ceca921fc
commit
18684d9f7c
3 changed files with 96 additions and 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
|
||||
|
|
|
@ -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
|
||||
|
|
69
thread.c
69
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.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue