yarv-diff:398
From: ko1 atdot.net
Date: 5 Oct 2006 22:21:55 +0900
Subject: [yarv-diff:398] r565 - branches/parallel
Author: ko1
Date: 2006-10-05 22:21:54 +0900 (Thu, 05 Oct 2006)
New Revision: 565
Modified:
branches/parallel/ChangeLog
branches/parallel/eval.c
branches/parallel/gc.c
branches/parallel/main.c
branches/parallel/st.c
branches/parallel/thread.c
branches/parallel/thread_pthread.h
branches/parallel/thread_win32.h
branches/parallel/yarv.h
Log:
* eval.c : move Init_gc_lock() to main.c
* main.c : ditto
* gc.c : fix to run GC if freelist is not 0
* st.c (st_copy) : initialize fglock
* thread.c : support win32
* thread_win32.h : ditto
* thread_pthread.h : adapt above changes
* yarv.h : add comments
Modified: branches/parallel/ChangeLog
===================================================================
--- branches/parallel/ChangeLog 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/ChangeLog 2006-10-05 13:21:54 UTC (rev 565)
@@ -4,6 +4,25 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-10-05(Thu) 22:14:54 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * eval.c : move Init_gc_lock() to main.c
+
+ * main.c : ditto
+
+ * gc.c : fix to run GC if freelist is not 0
+
+ * st.c (st_copy) : initialize fglock
+
+ * thread.c : support win32
+
+ * thread_win32.h : ditto
+
+ * thread_pthread.h : adapt above changes
+
+ * yarv.h : add comments
+
+
2006-10-04(Wed) 23:01:58 +0900 Koichi Sasada <ko1 atdot.net>
* thread.c : remove pthread depend code (and move to thread_pthread.c)
Modified: branches/parallel/eval.c
===================================================================
--- branches/parallel/eval.c 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/eval.c 2006-10-05 13:21:54 UTC (rev 565)
@@ -109,7 +109,6 @@
#endif
Init_stack((void *)&state);
- Init_gc_lock();
Init_yarv();
Init_heap();
Modified: branches/parallel/gc.c
===================================================================
--- branches/parallel/gc.c 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/gc.c 2006-10-05 13:21:54 UTC (rev 565)
@@ -248,7 +248,7 @@
mem = malloc(size);
});
if (!mem) {
- if (garbage_collect()) {
+ if (garbage_collect()) {
FGLOCK_RANGE(&g_mem_lock, {
mem = malloc(size);
});
@@ -1385,12 +1385,7 @@
printf("gc [0]: %ld.%06ld sec\n", d/1000000, d%1000000);
}
- if (freelist == 0 || gc_stress) {
- r = garbage_collect_thread_unsafe();
- }
- else {
- r = Qtrue;
- }
+ r = garbage_collect_thread_unsafe();
if (GCSTAT) {
gettimeofday(&tve, 0);
Modified: branches/parallel/main.c
===================================================================
--- branches/parallel/main.c 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/main.c 2006-10-05 13:21:54 UTC (rev 565)
@@ -29,6 +29,8 @@
int
main(int argc, char **argv, char **envp)
{
+ Init_gc_lock();
+
#ifdef RUBY_GC_STRESS
RUBY_EXTERN int gc_stress;
gc_stress = getenv("RUBY_GC_STRESS") != NULL;
Modified: branches/parallel/st.c
===================================================================
--- branches/parallel/st.c 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/st.c 2006-10-05 13:21:54 UTC (rev 565)
@@ -379,6 +379,8 @@
}
*new_table = *old_table;
+ native_fglock_init(&new_table->lock);
+
new_table->bins = (st_table_entry **)
Calloc((unsigned)num_bins, sizeof(st_table_entry *));
Modified: branches/parallel/thread.c
===================================================================
--- branches/parallel/thread.c 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/thread.c 2006-10-05 13:21:54 UTC (rev 565)
@@ -324,14 +324,19 @@
}
vm->interrupt_gc_flag = 1;
+ native_cond_reset(&vm->gc_barrier_waits_cond);
+ native_cond_reset(&vm->gc_barrier_waits_cond);
while (vm->living_threads->num_entries != vm->num_wait_threads + 1) {
+
thread_debug("rb_thread_gc_barrier_start: block start - ltnum: %d, wtnum: %d\n",
vm->living_threads->num_entries, vm->num_wait_threads);
native_cond_wait(&vm->gc_barrier_owner_cond,
&vm->gc_lock);
thread_debug("rb_thread_gc_barrier_start: block end - ltnum: %d, wtnum: %d\n",
vm->living_threads->num_entries, vm->num_wait_threads);
+
+ native_cond_reset(&vm->gc_barrier_waits_cond);
}
});
}
@@ -350,11 +355,17 @@
vm->living_threads->num_entries - vm->num_wait_threads - 1);
}
- LOCK_RANGE(&vm->gc_lock, {
- vm->interrupt_gc_flag = 0;
- native_cond_broadcast(&vm->gc_barrier_waits_cond);
- });
+ if (rb_thread_alone() || vm->living_threads == 0) {
+ /* skip */
+ }
+ else {
+ LOCK_RANGE(&vm->gc_lock, {
+ vm->interrupt_gc_flag = 0;
+ native_cond_broadcast(&vm->gc_barrier_waits_cond);
+ });
+ }
+
thread_debug("rb_thread_gc_barrier_end: end\n");
}
@@ -2386,7 +2397,7 @@
native_cond_init(&GET_VM()->gc_barrier_waits_cond);
}
}
-
+
make_timer_thread();
//atexit(show_func);
//atexit(pr_show);
Modified: branches/parallel/thread_pthread.h
===================================================================
--- branches/parallel/thread_pthread.h 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/thread_pthread.h 2006-10-05 13:21:54 UTC (rev 565)
@@ -21,6 +21,7 @@
void native_cond_signal(yarv_thread_cond_t *cond);
void native_cond_broadcast(yarv_thread_cond_t *cond);
void native_cond_wait(yarv_thread_cond_t *cond, yarv_thread_lock_t *lock);
+#define native_cond_reset(cond)
typedef struct native_thread_data_struct {
void *signal_thread_list;
Modified: branches/parallel/thread_win32.h
===================================================================
--- branches/parallel/thread_win32.h 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/thread_win32.h 2006-10-05 13:21:54 UTC (rev 565)
@@ -10,9 +10,14 @@
#define TLS_SPECIFIER __declspec( thread )
+typedef struct {
+ CRITICAL_SECTION cs;
+ int entered;
+} yarv_critical_section_lock_t;
+
typedef HANDLE yarv_thread_id_t;
-typedef CRITICAL_SECTION yarv_thread_lock_t;
-typedef CRITICAL_SECTION yarv_thread_fglock_t;
+typedef yarv_critical_section_lock_t yarv_thread_lock_t;
+typedef yarv_critical_section_lock_t yarv_thread_fglock_t;
typedef HANDLE yarv_thread_cond_t;
int native_mutex_lock(yarv_thread_lock_t *);
@@ -26,6 +31,7 @@
void native_cond_signal(yarv_thread_cond_t *cond);
void native_cond_broadcast(yarv_thread_cond_t *cond);
void native_cond_wait(yarv_thread_cond_t *cond, yarv_thread_lock_t *lock);
+void native_cond_reset(yarv_thread_cond_t *cond);
#define native_fg_lock native_mutex_lock
#define native_fg_unlock native_mutex_unlock
@@ -147,7 +153,6 @@
thread_debug("native_sleep start (%d)\n", (int)msec);
ret = w32_wait_event(0, msec, th);
thread_debug("native_sleep done (%d)\n", ret);
- th->interrupt_function = 0;
th->status = status;
});
}
@@ -183,7 +188,11 @@
}
return 0;
#else
- EnterCriticalSection(lock);
+ EnterCriticalSection(&lock->cs);
+ if (lock->entered == 1) {
+ rb_bug("native_mutex_lock: already owned");
+ }
+ lock->entered = 1;
return 0;
#endif
}
@@ -195,7 +204,8 @@
thread_debug("release mutex: %p\n", *lock);
return ReleaseMutex(*lock);
#else
- LeaveCriticalSection(lock);
+ lock->entered = 0;
+ LeaveCriticalSection(&lock->cs);
return 0;
#endif
}
@@ -216,7 +226,12 @@
}
return EINVAL;
#else
- return TryEnterCriticalSection(lock) == 0;
+ if (lock->entered) {
+ return EBUSY;
+ }
+ else {
+ return TryEnterCriticalSection(&lock->cs) == 0;
+ }
#endif
}
@@ -225,9 +240,9 @@
{
#if USE_WIN32MUTEX
*lock = CreateMutex(NULL, FALSE, NULL);
- // thread_debug("initialize mutex: %p\n", *lock);
#else
- InitializeCriticalSection(lock);
+ lock->entered = 0;
+ InitializeCriticalSection(&lock->cs);
#endif
}
@@ -237,14 +252,14 @@
#if USE_WIN32MUTEX
CloseHandle(lock);
#else
- DeleteCriticalSection(lock);
+ DeleteCriticalSection(&lock->cs);
#endif
}
void
native_cond_init(yarv_thread_cond_t *cond)
{
- *cond = CreateEvent(0, FALSE, FALSE, 0);
+ *cond = CreateEvent(0, TRUE, FALSE, 0);
if (*cond == 0) {
rb_bug("native_cond_init: error");
}
@@ -261,7 +276,7 @@
void
native_cond_signal(yarv_thread_cond_t *cond)
{
- if (SetEvent(cond) == 0) {
+ if (SetEvent(*cond) == 0) {
rb_bug("native_cond_signal: error");
}
}
@@ -269,22 +284,54 @@
void
native_cond_broadcast(yarv_thread_cond_t *cond)
{
- if (SetEvent(cond) == 0) {
+ if (SetEvent(*cond) == 0) {
rb_bug("native_cond_broadcast: error");
}
}
+static void
+show_error(void)
+{
+ LPVOID lpMsgBuf;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ 0, // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+ // Process any inserts in lpMsgBuf.
+ // ...
+ // Display the string.
+ MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Ruby Error", MB_OK | MB_ICONINFORMATION);
+ // Free the buffer.
+ LocalFree( lpMsgBuf );
+ exit(1);
+}
+
void
native_cond_wait(yarv_thread_cond_t *cond, yarv_thread_lock_t *lock)
{
- /* TODO: dangrous */
+ DWORD err;
+
native_mutex_unlock(lock);
- if (WaitForSingleObject(lock, INFINITE) != WAIT_OBJECT_0) {
+ if ((err = WaitForSingleObject(*cond, INFINITE)) != WAIT_OBJECT_0) {
+ show_error();
rb_bug("native_cond_wait: error");
}
native_mutex_lock(lock);
}
+void
+native_cond_reset(yarv_thread_cond_t *cond)
+{
+ ResetEvent(*cond);
+}
+
NOINLINE(static int
thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
void static thread_cleanup_func(void *th_ptr);
@@ -299,6 +346,7 @@
thread_debug("thread created (th: %p, thid: %p, event: %p)\n", th,
th->thread_id, th->native_thread_data.interrupt_event);
+
thread_start_func_2(th, &stack_start);
thread_cleanup_func(th);
Modified: branches/parallel/yarv.h
===================================================================
--- branches/parallel/yarv.h 2006-10-04 14:05:55 UTC (rev 564)
+++ branches/parallel/yarv.h 2006-10-05 13:21:54 UTC (rev 565)
@@ -58,12 +58,15 @@
/**********************************************************/
#elif YARV_THREAD_MODEL == 3
+/*****/
#if defined(__GNUC__)
extern TLS_SPECIFIER yarv_thread_t *yarvCurrentThread;
extern yarv_vm_t *theYarvVM;
#define GET_VM() theYarvVM
#define GET_THREAD() yarvCurrentThread
+
+/*****/
#elif defined(_WIN32)
extern TLS_SPECIFIER yarv_thread_t *yarvCurrentThread;
extern yarv_vm_t *theYarvVM;
@@ -71,6 +74,7 @@
#define GET_VM() theYarvVM
#define GET_THREAD() yarvCurrentThread
+/*****/
#else
#error "Does not support Parallel Ruby on this platform"
#endif
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml