dumping ground for random patches and texts
 help / color / mirror / Atom feed
* [PATCH] thread: micro-optimize thread create/join
@ 2015-01-17  2:49 Eric Wong
  0 siblings, 0 replies; only message in thread
From: Eric Wong @ 2015-01-17  2:49 UTC (permalink / raw)
  To: spew

This reduces time in benchmark/bm_vm_thread_create_join.rb by
a few percent.

Minor improvements only:

target 0: 2.1.5 (ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]) at "/home/ew/ruby-2.1/bin/ruby"
target 1: trunk (ruby 2.3.0dev (2015-01-16 trunk 49282) [x86_64-linux]) at "/home/ew/rrrr/b/i/bin/ruby"
target 2: built (ruby 2.3.0dev (2015-01-16 trunk 49282) [x86_64-linux]) at "/home/ew/ruby/b/i/bin/ruby"

2.1.5	1.0573025540215895
2.1.5	1.0493981029139832
2.1.5	1.0576379200210795
trunk	1.2876477020327002
trunk	1.2424484699731693
trunk	1.2432217099703848
built	1.1531978889834136
built	1.137529328931123
built	1.1509092160267755

Elapsed time: 10.381246521 (sec)
-----------------------------------------------------------
benchmark results:
minimum results in each 3 measurements.
Execution time (sec)
name	2.1.5	trunk	built
vm_thread_create_join	1.049	1.242	1.138

Speedup ratio: compare with the result of `2.1.5' (greater is better)
name	trunk	built
vm_thread_create_join	0.845	0.923

---
 thread.c         | 58 ++++++++++++++++++++------------------------------------
 thread_pthread.c | 49 +++++++++++++++++++++++------------------------
 2 files changed, 45 insertions(+), 62 deletions(-)

diff --git a/thread.c b/thread.c
index 5d8ac7e..412e983 100644
--- a/thread.c
+++ b/thread.c
@@ -796,8 +796,7 @@ rb_thread_create(VALUE (*fn)(ANYARGS), void *arg)
 
 struct join_arg {
     rb_thread_t *target, *waiting;
-    double limit;
-    int forever;
+    double delay;
 };
 
 static VALUE
@@ -826,14 +825,15 @@ thread_join_sleep(VALUE arg)
 {
     struct join_arg *p = (struct join_arg *)arg;
     rb_thread_t *target_th = p->target, *th = p->waiting;
-    double now, limit = p->limit;
+    const int forever = p->delay == DELAY_INFTY;
+    const double limit = forever ? 0 : timeofday() + p->delay;
 
     while (target_th->status != THREAD_KILLED) {
-	if (p->forever) {
+	if (forever) {
 	    sleep_forever(th, 1, 0);
 	}
 	else {
-	    now = timeofday();
+	    double now = timeofday();
 	    if (now > limit) {
 		thread_debug("thread_join: timeout (thid: %"PRI_THREAD_ID")\n",
 			     thread_id_str(target_th));
@@ -862,8 +862,7 @@ thread_join(rb_thread_t *target_th, double delay)
 
     arg.target = target_th;
     arg.waiting = th;
-    arg.limit = timeofday() + delay;
-    arg.forever = delay == DELAY_INFTY;
+    arg.delay = delay;
 
     thread_debug("thread_join (thid: %"PRI_THREAD_ID")\n", thread_id_str(target_th));
 
@@ -2707,8 +2706,15 @@ rb_thread_safe_level(VALUE thread)
     return INT2NUM(th->safe_level);
 }
 
+/*
+ * call-seq:
+ *   thr.inspect   -> string
+ *
+ * Dump the name, id, and status of _thr_ to a string.
+ */
+
 static VALUE
-rb_thread_inspect_msg(VALUE thread, int show_enclosure, int show_location, int show_status)
+rb_thread_inspect(VALUE thread)
 {
     VALUE cname = rb_class_path(rb_obj_class(thread));
     rb_thread_t *th;
@@ -2717,43 +2723,21 @@ rb_thread_inspect_msg(VALUE thread, int show_enclosure, int show_location, int s
 
     GetThreadPtr(thread, th);
     status = thread_status_name(th);
-    if (show_enclosure)
-        str = rb_sprintf("#<%"PRIsVALUE":%p", cname, (void *)thread);
-    else
-        str = rb_str_new(NULL, 0);
-    if (show_location && !th->first_func && th->first_proc) {
-	long i;
-	VALUE v, loc = rb_proc_location(th->first_proc);
+    str = rb_sprintf("#<%"PRIsVALUE":%p", cname, (void *)thread);
+    if (!th->first_func && th->first_proc) {
+	VALUE loc = rb_proc_location(th->first_proc);
 	if (!NIL_P(loc)) {
-	    char sep = '@';
-	    for (i = 0; i < RARRAY_LEN(loc) && !NIL_P(v = RARRAY_AREF(loc, i)); ++i) {
-		rb_str_catf(str, "%c%"PRIsVALUE, sep, v);
-		sep = ':';
-	    }
+	    const VALUE *ptr = RARRAY_CONST_PTR(loc);
+	    rb_str_catf(str, "@%"PRIsVALUE":%"PRIsVALUE, ptr[0], ptr[1]);
+	    rb_gc_force_recycle(loc);
 	}
     }
-    if (show_status || show_enclosure)
-        rb_str_catf(str, " %s%s",
-                show_status ? status : "",
-                show_enclosure ? ">" : "");
+    rb_str_catf(str, " %s>", status);
     OBJ_INFECT(str, thread);
 
     return str;
 }
 
-/*
- * call-seq:
- *   thr.inspect   -> string
- *
- * Dump the name, id, and status of _thr_ to a string.
- */
-
-static VALUE
-rb_thread_inspect(VALUE thread)
-{
-    return rb_thread_inspect_msg(thread, 1, 1, 1);
-}
-
 /* variables for recursive traversals */
 static ID recursive_key;
 
diff --git a/thread_pthread.c b/thread_pthread.c
index 7e4d36c..3ef316c 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -1447,36 +1447,35 @@ timer_thread_sleep(rb_global_vm_lock_t* unused)
 # define SET_THREAD_NAME(name) (void)0
 #endif
 
-static VALUE rb_thread_inspect_msg(VALUE thread, int show_enclosure, int show_location, int show_status);
-
 static void
 native_set_thread_name(rb_thread_t *th)
 {
 #if defined(__linux__) && defined(PR_SET_NAME)
-    VALUE str;
-    char *name, *p;
-    char buf[16];
-    size_t len;
-
-    str = rb_thread_inspect_msg(th->self, 0, 1, 0);
-    name = StringValueCStr(str);
-    if (*name == '@')
-        name++;
-    p = strrchr(name, '/'); /* show only the basename of the path. */
-    if (p && p[1])
-        name = p + 1;
-
-    len = strlen(name);
-    if (len < sizeof(buf)) {
-        memcpy(buf, name, len);
-        buf[len] = '\0';
-    }
-    else {
-        memcpy(buf, name, sizeof(buf)-2);
-        buf[sizeof(buf)-2] = '*';
-        buf[sizeof(buf)-1] = '\0';
+    if (!th->first_func && th->first_proc) {
+	VALUE loc = rb_proc_location(th->first_proc);
+	if (!NIL_P(loc)) {
+	    const VALUE *ptr = RARRAY_CONST_PTR(loc); /* [ String, Fixnum ] */
+	    char *name, *p;
+	    char buf[16];
+	    size_t len;
+	    int n;
+
+	    name = RSTRING_PTR(ptr[0]);
+	    p = strrchr(name, '/'); /* show only the basename of the path. */
+	    if (p && p[1])
+		name = p + 1;
+
+	    n = snprintf(buf, sizeof(buf), "%s:%d", name, NUM2INT(ptr[1]));
+	    rb_gc_force_recycle(loc); /* acts as a GC guard, too */
+
+	    len = (size_t)n;
+	    if (len >= sizeof(buf)) {
+		buf[sizeof(buf)-2] = '*';
+		buf[sizeof(buf)-1] = '\0';
+	    }
+	    SET_THREAD_NAME(buf);
+	}
     }
-    SET_THREAD_NAME(buf);
 #endif
 }
 
-- 
EW


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2015-01-17  2:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-17  2:49 [PATCH] thread: micro-optimize thread create/join Eric Wong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).