variable.c: fix autoload stack space regression

r61560 ("offsetof(type, foo.bar) is (arguably) a GCCism")
introduced 16 bytes of stack overhead on 64-bit systems.
Remove that overhead and cast, instead.  While we're at it,
restore the "waitq" name to clarify the purpose of the field.

(This is one unfortunate consequence of the CC0 ccan/list.h
 implementation compared to the *GPL ones in glibc/urcu/linux)

* variable.c (struct autoload_state): remove head field, clarify naming
  (autoload_reset): cast and adjust
  (autoload_sleep_done): ditto
  (rb_autoload_load): ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61574 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
normal 2018-01-02 21:51:59 +00:00
Родитель 2244bf5716
Коммит 7bbff60485
1 изменённых файлов: 6 добавлений и 7 удалений

Просмотреть файл

@ -1847,8 +1847,7 @@ struct autoload_state {
VALUE result; VALUE result;
ID id; ID id;
VALUE thread; VALUE thread;
struct list_node node; struct list_node waitq;
struct list_head head;
}; };
struct autoload_data_i { struct autoload_data_i {
@ -2101,11 +2100,11 @@ autoload_reset(VALUE arg)
if (need_wakeups) { if (need_wakeups) {
struct autoload_state *cur = 0, *nxt; struct autoload_state *cur = 0, *nxt;
list_for_each_safe(&state->head, cur, nxt, node) { list_for_each_safe((struct list_head *)&state->waitq, cur, nxt, waitq) {
VALUE th = cur->thread; VALUE th = cur->thread;
cur->thread = Qfalse; cur->thread = Qfalse;
list_del_init(&cur->node); /* idempotent */ list_del_init(&cur->waitq); /* idempotent */
/* /*
* cur is stored on the stack of cur->waiting_th, * cur is stored on the stack of cur->waiting_th,
@ -2140,7 +2139,7 @@ autoload_sleep_done(VALUE arg)
struct autoload_state *state = (struct autoload_state *)arg; struct autoload_state *state = (struct autoload_state *)arg;
if (state->thread != Qfalse && rb_thread_to_be_killed(state->thread)) { if (state->thread != Qfalse && rb_thread_to_be_killed(state->thread)) {
list_del(&state->node); /* idempotent after list_del_init */ list_del(&state->waitq); /* idempotent after list_del_init */
} }
return Qfalse; return Qfalse;
@ -2176,13 +2175,13 @@ rb_autoload_load(VALUE mod, ID id)
* autoload_reset will wake up any threads added to this * autoload_reset will wake up any threads added to this
* iff the GVL is released during autoload_require * iff the GVL is released during autoload_require
*/ */
list_head_init(&state.head); list_head_init((struct list_head *)&state.waitq);
} }
else if (state.thread == ele->state->thread) { else if (state.thread == ele->state->thread) {
return Qfalse; return Qfalse;
} }
else { else {
list_add_tail(&ele->state->head, &state.node); list_add_tail((struct list_head *)&ele->state->waitq, &state.waitq);
rb_ensure(autoload_sleep, (VALUE)&state, rb_ensure(autoload_sleep, (VALUE)&state,
autoload_sleep_done, (VALUE)&state); autoload_sleep_done, (VALUE)&state);