diff --git a/ChangeLog b/ChangeLog index 9c99edb75e..33b2b14401 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Thu Jan 29 02:06:09 2015 Eric Wong + + * thread.c (struct join_arg): restructure and make smaller + (thread_join_sleep): avoid timeofday() call if forever + (thread_join): pass join_arg.delay directly + (rb_thread_inspect_msg): remove, inline into rb_thread_inspect + (rb_thread_inspect): reduce branching and string creation + * thread_pthread.c (native_set_thread_name): create string directly + to avoid reparsing. [Misc #10723] + Wed Jan 28 21:32:24 2015 SHIBATA Hiroshi * thread.c: Improve documentation for Thread#value diff --git a/thread.c b/thread.c index b7056a764d..4ac93e85a1 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)); @@ -2711,40 +2710,6 @@ rb_thread_safe_level(VALUE thread) return INT2NUM(th->safe_level); } -static VALUE -rb_thread_inspect_msg(VALUE thread, int show_enclosure, int show_location, int show_status) -{ - VALUE cname = rb_class_path(rb_obj_class(thread)); - rb_thread_t *th; - const char *status; - VALUE str; - - 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); - 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 = ':'; - } - } - } - if (show_status || show_enclosure) - rb_str_catf(str, " %s%s", - show_status ? status : "", - show_enclosure ? ">" : ""); - OBJ_INFECT(str, thread); - - return str; -} - /* * call-seq: * thr.inspect -> string @@ -2755,7 +2720,26 @@ rb_thread_inspect_msg(VALUE thread, int show_enclosure, int show_location, int s static VALUE rb_thread_inspect(VALUE thread) { - return rb_thread_inspect_msg(thread, 1, 1, 1); + VALUE cname = rb_class_path(rb_obj_class(thread)); + rb_thread_t *th; + const char *status; + VALUE str; + + GetThreadPtr(thread, th); + status = thread_status_name(th); + 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)) { + const VALUE *ptr = RARRAY_CONST_PTR(loc); + rb_str_catf(str, "@%"PRIsVALUE":%"PRIsVALUE, ptr[0], ptr[1]); + rb_gc_force_recycle(loc); + } + } + rb_str_catf(str, " %s>", status); + OBJ_INFECT(str, thread); + + return str; } /* variables for recursive traversals */ diff --git a/thread_pthread.c b/thread_pthread.c index 7e4d36c479..3ef316c639 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; + 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; - 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; + name = RSTRING_PTR(ptr[0]); + 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'; + 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); + } } - else { - memcpy(buf, name, sizeof(buf)-2); - buf[sizeof(buf)-2] = '*'; - buf[sizeof(buf)-1] = '\0'; - } - SET_THREAD_NAME(buf); #endif }