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