[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:326

From: ko1 atdot.net
Date: 3 May 2006 15:34:08 -0000
Subject: [yarv-diff:326] r493 - trunk

Author: ko1
Date: 2006-05-04 00:34:08 +0900 (Thu, 04 May 2006)
New Revision: 493

Modified:
   trunk/
   trunk/ChangeLog
   trunk/thread_pthread.h
Log:
 r762@lermite:  ko1 | 2006-05-04 00:30:21 +0900
 	* thread_pthread.h : experimental support of thread cache
 



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:749
   + 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:762

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-04-25 13:34:50 UTC (rev 492)
+++ trunk/ChangeLog	2006-05-03 15:34:08 UTC (rev 493)
@@ -4,6 +4,11 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-05-04(Thu) 00:26:18 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* thread_pthread.h : experimental support of thread cache
+
+
 2006-04-25(Tue) 22:30:14 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* yarvcore.h : remove struct yarv_cmethod_info, add

Modified: trunk/thread_pthread.h
===================================================================
--- trunk/thread_pthread.h	2006-04-25 13:34:50 UTC (rev 492)
+++ trunk/thread_pthread.h	2006-05-03 15:34:08 UTC (rev 493)
@@ -52,47 +52,155 @@
 	 thread_start_func_2(yarv_thread_t *th, VALUE *stack_start));
 void static thread_cleanup_func(void *th_ptr);
 
+static void register_cached_thread_and_wait(volatile yarv_thread_t **th);
+
+#define USE_THREAD_CACHE 0
+
 static void *
 thread_start_func_1(void *th_ptr)
 {
-    yarv_thread_t *th = th_ptr;
-    VALUE stack_start;
-    /* ignore self and klass */
+  thread_start:
+    {
+	yarv_thread_t *th = th_ptr;
+	VALUE stack_start;
+	/* ignore self and klass */
 
-    native_cleanup_push(thread_cleanup_func, th);
+	native_cleanup_push(thread_cleanup_func, th);
 
-    /* run */
-    thread_start_func_2(th, &stack_start);
-    thread_cleanup_func(th);
-    native_cleanup_pop(0);
+	/* run */
+	thread_start_func_2(th, &stack_start);
+
+	/* cleanup */
+	thread_cleanup_func(th);
+	native_cleanup_pop(0);
+    }
+#if USE_THREAD_CACHE
+    if (1) {
+	/* cache thread */
+	volatile yarv_thread_t * th = 0;
+	register_cached_thread_and_wait(&th);
+	if (th != 0) {
+	    pritnf("!\n");
+	    th_ptr = (void *)th;
+	    goto thread_start;
+	}
+    }
+#endif
     return 0;
 }
 
 static void make_timer_thread();
 
+static pthread_mutex_t thread_cache_lock = PTHREAD_MUTEX_INITIALIZER;
+
+struct cached_thread_entry {
+    volatile yarv_thread_t **th_area;
+    pthread_cond_t *cond;
+    struct cached_thread_entry *next;
+};
+
+struct cached_thread_entry *cached_thread_root;
+
+static void
+register_cached_thread_and_wait(volatile yarv_thread_t **th_area)
+{
+    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+    
+    struct cached_thread_entry *entry =
+      (struct cached_thread_entry *)malloc(sizeof(struct cached_thread_entry));
+    
+    struct timespec tm = {
+	time(0) + 60, 0,
+    };
+    
+    pthread_mutex_lock(&thread_cache_lock);
+    {
+	entry->th_area = th_area;
+	entry->cond = &cond;
+	entry->next = cached_thread_root;
+	cached_thread_root = entry;
+    }
+    
+    pthread_cond_timedwait(&cond, &thread_cache_lock, &tm);
+    
+    {
+	struct cached_thread_entry *e = cached_thread_root;
+	struct cached_thread_entry *prev = cached_thread_root;
+
+	if (*th_area == 0) {
+	    while (e) {
+		if (e == entry) {
+		    if (prev == cached_thread_root) {
+			cached_thread_root = e->next;
+		    }
+		    else {
+			prev->next = e->next;
+		    }
+		    break;
+		}
+		prev = e;
+		e = e->next;
+	    }
+	}
+    }
+    free(entry);
+    pthread_mutex_unlock(&thread_cache_lock);
+}
+
+
 static int
+use_cached_thread(yarv_thread_t *th)
+{
+    int result = 0;
+#if USE_THREAD_CACHE
+    struct cached_thread_entry *entry;
+    pthread_mutex_lock(&thread_cache_lock);
+    entry = cached_thread_root;
+    {
+	if (cached_thread_root) {
+	    cached_thread_root = entry->next;
+	    *entry->th_area = th;
+	    result = 1;
+	}
+    }
+    if (result) {
+	pthread_cond_signal(entry->cond);
+    }
+    pthread_mutex_unlock(&thread_cache_lock);
+#endif
+    return result;
+}
+
+static int
 native_thread_create(yarv_thread_t *th)
 {
-    pthread_attr_t attr;
-    size_t stack_size = 4 * 1024 - sizeof(int);	/* 4KB */
-    int err;
-    static int init = 0;
+    int err = 0;
 
-    if (!init) {
-	make_timer_thread();
+    if (use_cached_thread(th)) {
     }
+    else {
+	pthread_attr_t attr;
+	size_t stack_size = 4 * 1024 - sizeof(int);	/* 4KB */
+	static int init = 0;
 
-    thread_debug("create: %p, stack size: %ld\n", th, stack_size);
+	if (!init) {
+	    make_timer_thread();
+	}
 
-    pthread_attr_init(&attr);
-    pthread_attr_setstacksize(&attr, stack_size);
-    pthread_attr_setdetachstate(&attr, 1);
-    
-    err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
-    
-    if (err != 0) {
-	th->status = THREAD_KILLED;
-	rb_raise(rb_eThreadError, "can't create Thread (%d)", err);
+	thread_debug("create: %p, stack size: %ld\n", th, stack_size);
+
+	pthread_attr_init(&attr);
+	pthread_attr_setstacksize(&attr, stack_size);
+	pthread_attr_setdetachstate(&attr, 1);
+
+	//
+
+	err = pthread_create(&th->thread_id, &attr, thread_start_func_1, th);
+
+	if (err != 0) {
+	    th->status = THREAD_KILLED;
+	    rb_raise(rb_eThreadError, "can't create Thread (%d)", err);
+	}
     }
     return err;
 }


-- 
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]