summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-02 21:51:59 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-02 21:51:59 +0000
commit7bbff60485b155119fc965e3cc5a4dea6b69cefb (patch)
tree9e11a118470929c4e14463aa3b77a53c1d44b1c4
parent2244bf5716c0362aec8f4881fdca9f8f1457d9b3 (diff)
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
-rw-r--r--variable.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/variable.c b/variable.c
index dda92cd723..b74bb7ef90 100644
--- a/variable.c
+++ b/variable.c
@@ -1847,8 +1847,7 @@ struct autoload_state {
VALUE result;
ID id;
VALUE thread;
- struct list_node node;
- struct list_head head;
+ struct list_node waitq;
};
struct autoload_data_i {
@@ -2101,11 +2100,11 @@ autoload_reset(VALUE arg)
if (need_wakeups) {
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;
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,
@@ -2140,7 +2139,7 @@ autoload_sleep_done(VALUE arg)
struct autoload_state *state = (struct autoload_state *)arg;
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;
@@ -2176,13 +2175,13 @@ rb_autoload_load(VALUE mod, ID id)
* autoload_reset will wake up any threads added to this
* 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) {
return Qfalse;
}
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,
autoload_sleep_done, (VALUE)&state);