[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]