ruby-changes:49446
From: shyouhei <ko1@a...>
Date: Tue, 2 Jan 2018 20:29:35 +0900 (JST)
Subject: [ruby-changes:49446] shyouhei:r61560 (trunk): offsetof(type, foo.bar) is (arguably) a GCCism
shyouhei 2018-01-02 15:41:56 +0900 (Tue, 02 Jan 2018) New Revision: 61560 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61560 Log: offsetof(type, foo.bar) is (arguably) a GCCism TL;DR see http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2031.htm Suppose we have: struct X { struct Y { z_t z; } y; } x; then, you _cant_ infer offsetof(struct X, y.z). The ISO C99 section 7.17 says nothing about such situation. At least clang warns this being an extension to the language (-Wextended-offsetof). Modified files: trunk/thread_pthread.c trunk/variable.c Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 61559) +++ thread_pthread.c (revision 61560) @@ -1221,11 +1221,13 @@ static void https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L1221 ubf_wakeup_all_threads(void) { rb_thread_t *th; + native_thread_data_t *dat; if (!ubf_threads_empty()) { native_mutex_lock(&ubf_list_lock); - list_for_each(&ubf_list_head, th, - native_thread_data.ubf_list) { + list_for_each(&ubf_list_head, dat, ubf_list) { + th = (rb_thread_t *)( + ((char *)dat) - offsetof(rb_thread_t, native_thread_data)); ubf_wakeup_thread(th); } native_mutex_unlock(&ubf_list_lock); Index: variable.c =================================================================== --- variable.c (revision 61559) +++ variable.c (revision 61560) @@ -1846,10 +1846,8 @@ struct autoload_state { https://github.com/ruby/ruby/blob/trunk/variable.c#L1846 VALUE result; ID id; VALUE thread; - union { - struct list_node node; - struct list_head head; - } waitq; + struct list_node node; + struct list_head head; }; struct autoload_data_i { @@ -2102,11 +2100,11 @@ autoload_reset(VALUE arg) https://github.com/ruby/ruby/blob/trunk/variable.c#L2100 if (need_wakeups) { struct autoload_state *cur = 0, *nxt; - list_for_each_safe(&state->waitq.head, cur, nxt, waitq.node) { + list_for_each_safe(&state->head, cur, nxt, node) { VALUE th = cur->thread; cur->thread = Qfalse; - list_del_init(&cur->waitq.node); /* idempotent */ + list_del_init(&cur->node); /* idempotent */ /* * cur is stored on the stack of cur->waiting_th, @@ -2141,7 +2139,7 @@ autoload_sleep_done(VALUE arg) https://github.com/ruby/ruby/blob/trunk/variable.c#L2139 struct autoload_state *state = (struct autoload_state *)arg; if (state->thread != Qfalse && rb_thread_to_be_killed(state->thread)) { - list_del(&state->waitq.node); /* idempotent after list_del_init */ + list_del(&state->node); /* idempotent after list_del_init */ } return Qfalse; @@ -2177,13 +2175,13 @@ rb_autoload_load(VALUE mod, ID id) https://github.com/ruby/ruby/blob/trunk/variable.c#L2175 * autoload_reset will wake up any threads added to this * iff the GVL is released during autoload_require */ - list_head_init(&state.waitq.head); + list_head_init(&state.head); } else if (state.thread == ele->state->thread) { return Qfalse; } else { - list_add_tail(&ele->state->waitq.head, &state.waitq.node); + list_add_tail(&ele->state->head, &state.node); rb_ensure(autoload_sleep, (VALUE)&state, autoload_sleep_done, (VALUE)&state); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/