yarv-diff:389
From: ko1 atdot.net
Date: 6 Sep 2006 22:44:34 +0900
Subject: [yarv-diff:389] r556 - branches/parallel
Author: ko1
Date: 2006-09-06 22:44:33 +0900 (Wed, 06 Sep 2006)
New Revision: 556
Modified:
branches/parallel/ChangeLog
branches/parallel/thread.c
branches/parallel/yarvcore.h
Log:
* thread.c : add CPU control feature for multi-CPU/Core
* yarvcore.h : ditto
Modified: branches/parallel/ChangeLog
===================================================================
--- branches/parallel/ChangeLog 2006-09-05 13:22:49 UTC (rev 555)
+++ branches/parallel/ChangeLog 2006-09-06 13:44:33 UTC (rev 556)
@@ -4,6 +4,13 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2006-09-06(Wed) 22:43:04 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * thread.c : add CPU control feature for multi-CPU/Core
+
+ * yarvcore.h : ditto
+
+
2006-09-05(Tue) 22:16:37 +0900 Koichi Sasada <ko1 atdot.net>
* thread.c : add rb_thread_write
Modified: branches/parallel/thread.c
===================================================================
--- branches/parallel/thread.c 2006-09-05 13:22:49 UTC (rev 555)
+++ branches/parallel/thread.c 2006-09-06 13:44:33 UTC (rev 556)
@@ -60,6 +60,7 @@
static const VALUE eTerminateSignal = INT2FIX(1);
static int system_working = 1;
+static int profile_conflict = 0;
inline static void
st_delete_wrap(st_table * table, VALUE key)
@@ -136,11 +137,10 @@
#define DEC_WAIT_THREAD(vm) ((vm)->num_wait_threads--)
#endif
-static int profile_confilict;
static void __attribute__((destructor))
pr_show(void)
{
- fprintf(stderr, "profile_confilict: %d\n", profile_confilict);
+ // fprintf(stderr, "profile_conflict: %d\n", profile_conflict);
}
static int g_spinlock_count;
@@ -160,10 +160,14 @@
else {
thread_debug("rb_thread_global_lock_acquire: try acquire (%p) --> \n",
vm->lock_owner_thread);
-
+
if (native_mutex_trylock(&vm->global_interpreter_lock) == EBUSY) {
int i;
+ th->profile_conflict++;
+ profile_conflict++;
for (i=0; i<g_spinlock_count; i++) {
+ th->profile_conflict++;
+ profile_conflict++;
if (native_mutex_trylock(&vm->global_interpreter_lock) == 0) {
goto gotlock;
}
@@ -172,11 +176,9 @@
}
native_thread_yield();
}
-
+
yarv_save_machine_context(th);
- profile_confilict++;
-
native_mutex_lock(&vm->gc_lock);
{
INC_WAIT_THREAD(vm);
@@ -185,7 +187,7 @@
}
}
native_mutex_unlock(&vm->gc_lock);
-
+
native_mutex_lock(&vm->global_interpreter_lock);
thread_debug("rb_thread_global_lock_acquire: <-- done (lock)\n");
@@ -1825,7 +1827,66 @@
fclose(fp);
}
+#define TS_CONFLICT 10000
+
+#if HAVE_SCHED_SETAFFINITY
+
static void
+set_cpu_cnt(yarv_thread_t *th, int num)
+{
+ cpu_set_t mask;
+ int i;
+
+ __CPU_ZERO(&mask);
+ for (i=0; i<num; i++) {
+ __CPU_SET(i, &mask);
+ }
+ if (pthread_setaffinity_np(th->thread_id, sizeof(cpu_set_t), &mask) != 0) {
+ rb_bug("sched_setaffinity error: %d\n", errno);
+ }
+
+ if (0) {
+ /* for debug */
+ pthread_getaffinity_np(th->thread_id, sizeof(cpu_set_t), &mask);
+ for (i=0; i<8; i++) {
+ fprintf(stderr, "%d: %d\n", i, __CPU_ISSET(i, &mask));
+ }
+ }
+}
+
+static int
+set_cpu_cnt_i(st_data_t key, st_data_t val, int is_clear)
+{
+ VALUE thval = key;
+ yarv_thread_t *th;
+ int i;
+ GetThreadPtr(thval, th);
+// fprintf(stderr, ">> %p: %d\n", th, th->profile_conflict);
+
+// #define thread_debug(x, y) fprintf(stderr, x, y)
+ if (th->profile_conflict > 1000 && !is_clear) {
+ if (th->profile_conflict_toggle == 0) {
+ thread_debug("cpu down: %d\n", th->profile_conflict);
+ set_cpu_cnt(th, 1);
+ //th->profile_conflict_limited_count = 10;
+ th->profile_conflict_toggle = 1;
+ }
+ }
+ else {
+ if (th->profile_conflict_toggle == 1) {
+ thread_debug("cpu up: %d\n", th->profile_conflict);
+ set_cpu_cnt(th, 8);
+ //th->profile_conflict_limited_count = 0;
+ th->profile_conflict_toggle = 0;
+ }
+ }
+// #define thread_debug if (0) printf
+ th->profile_conflict = 0;
+ return ST_CONTINUE;
+}
+#endif
+
+static void
timer_function(void)
{
yarv_vm_t *vm = GET_VM(); /* TODO: fix me for Multi-VM */
@@ -1851,6 +1912,54 @@
prof_in_r++;
}
#endif
+
+
+#if 1
+#if HAVE_SCHED_SETAFFINITY
+ {
+ static int prev_confilict;
+ static int cnt = 100;
+
+ if (cnt-- < 0) {
+ st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t)1);
+ cnt = 100;
+ }
+ else {
+ if (profile_conflict - prev_confilict > 10000) {
+ st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t)0);
+ }
+ }
+ prev_confilict = profile_conflict;
+ }
+#elif 0
+ {
+ static int prev_confilict;
+ static int toggle = 1;
+ static int buff = 0;
+ int d = profile_conflict - prev_confilict;
+
+ //fprintf(stderr, "%d\n", d);
+ if (d > TS_CONFLICT) {
+ if (toggle == 1 && buff-- < 0) {
+ thread_debug("cpu down: %d\n", d);
+ st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t) 1);
+ toggle = 0;
+ buff = 100;
+ }
+ }
+ else {
+ if (toggle == 0 && buff-- < 0) {
+ thread_debug("cpu up: %d\n", d);
+ st_foreach(vm->living_threads, set_cpu_cnt_i, (st_data_t) 2);
+ toggle = 1;
+ buff = 0;
+ }
+ }
+ prev_confilict = profile_conflict;
+ }
+#endif
+#endif
+
}
/*
@@ -2303,7 +2412,7 @@
g_spinlock_count = atoi(env);
}
else {
- g_spinlock_count = 100;
+ g_spinlock_count = 50;
}
rb_disable_interrupt(); /* only timer thread recieve signal */
Modified: branches/parallel/yarvcore.h
===================================================================
--- branches/parallel/yarvcore.h 2006-09-05 13:22:49 UTC (rev 555)
+++ branches/parallel/yarvcore.h 2006-09-06 13:44:33 UTC (rev 556)
@@ -470,6 +470,11 @@
/* misc */
int method_missing_reason;
int abort_on_exception;
+
+ int profile_conflict;
+ int profile_conflict_toggle;
+ int profile_conflict_limited_count;
+
struct re_registers regs;
} yarv_thread_t;
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml