ruby-changes:38954
From: normal <ko1@a...>
Date: Fri, 26 Jun 2015 04:56:37 +0900 (JST)
Subject: [ruby-changes:38954] normal:r51035 (trunk): Revert r51034 "st.c: use ccan linked-list"
normal 2015-06-26 04:56:20 +0900 (Fri, 26 Jun 2015) New Revision: 51035 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51035 Log: Revert r51034 "st.c: use ccan linked-list" Maybe this will stop mysterious CI failures from ko1@sasada-8core: ?\227?\131?\170?\227?\131?\147?\227?\130?\184?\227?\131?\167?\227?\131?\179 51034 ?\227?\129?\167?\227?\129?\153?\227?\128?\130 make[1]: ?\227?\131?\135?\227?\130?\163?\227?\131?\172?\227?\130?\175?\227?\131?\136?\227?\131?\170 `/mnt/sdb1/ruby/build' ?\227?\129?\171?\229?\133?\165?\227?\130?\138?\227?\129?\190?\227?\129?\153 ../trunk/revision.h unchanged make[1]: ?\227?\131?\135?\227?\130?\163?\227?\131?\172?\227?\130?\175?\227?\131?\136?\227?\131?\170 `/mnt/sdb1/ruby/build' ?\227?\129?\139?\227?\130?\137?\229?\135?\186?\227?\129?\190?\227?\129?\153 make[1]: ?\227?\131?\135?\227?\130?\163?\227?\131?\172?\227?\130?\175?\227?\131?\136?\227?\131?\170 `/mnt/sdb1/ruby/build' ?\227?\129?\171?\229?\133?\165?\227?\130?\138?\227?\129?\190?\227?\129?\153 config.guess already exists config.sub already exists generating ../trunk/ext/ripper/ripper.c make[2]: ?\227?\131?\135?\227?\130?\163?\227?\131?\172?\227?\130?\175?\227?\131?\136?\227?\131?\170 `/mnt/sdb1/ruby/trunk/ext/ripper' ?\227?\129?\171?\229?\133?\165?\227?\130?\138?\227?\129?\190?\227?\129?\153 extracting ripper.y from ../../parse.y id.h not found in ["../.."] make[2]: *** [ripper.y] ?\227?\130?\168?\227?\131?\169?\227?\131?\188 1 make[2]: ?\227?\131?\135?\227?\130?\163?\227?\131?\172?\227?\130?\175?\227?\131?\136?\227?\131?\170 `/mnt/sdb1/ruby/trunk/ext/ripper' ?\227?\129?\139?\227?\130?\137?\229?\135?\186?\227?\129?\190?\227?\129?\153 make[1]: *** [../trunk/ext/ripper/ripper.c] ?\227?\130?\168?\227?\131?\169?\227?\131?\188 2 make[1]: ?\227?\131?\135?\227?\130?\163?\227?\131?\172?\227?\130?\175?\227?\131?\136?\227?\131?\170 `/mnt/sdb1/ruby/build' ?\227?\129?\139?\227?\130?\137?\229?\135?\186?\227?\129?\190?\227?\129?\153 make: [up] ?\227?\130?\168?\227?\131?\169?\227?\131?\188 2 (?\231?\132?\161?\232?\166?\150?\227?\129?\149?\227?\130?\140?\227?\129?\190?\227?\129?\151?\227?\129?\159) make: *** [.rbconfig.time] ?\227?\130?\187?\227?\130?\176?\227?\131?\161?\227?\131?\179?\227?\131?\134?\227?\131?\188?\227?\130?\183?\227?\131?\167?\227?\131?\179?\233?\129?\149?\229?\143?\141?\227?\129?\167?\227?\129?\153 Command exited with non-zero status 2 Modified files: trunk/ChangeLog trunk/include/ruby/st.h trunk/st.c Index: include/ruby/st.h =================================================================== --- include/ruby/st.h (revision 51034) +++ include/ruby/st.h (revision 51035) @@ -86,7 +86,7 @@ struct st_table { https://github.com/ruby/ruby/blob/trunk/include/ruby/st.h#L86 union { struct { struct st_table_entry **bins; - void *private_list_head[2]; + struct st_table_entry *head, *tail; } big; struct { struct st_packed_entry *entries; Index: ChangeLog =================================================================== --- ChangeLog (revision 51034) +++ ChangeLog (revision 51035) @@ -1,26 +1,3 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 -Fri Jun 26 03:52:27 2015 Eric Wong <e@8...> - - * include/ruby/st.h (struct st_table): hide struct list_head - * st.c (struct st_table_entry): adjust struct - (head, tail): remove shortcut macros - (st_head): new wrapper function - (st_init_table_with_size): adjust to new struct and API - (st_clear): ditto - (add_direct): ditto - (unpack_entries): ditto - (rehash): ditto - (st_copy): ditto - (remove_entry): ditto - (st_shift): ditto - (st_foreach_check): ditto - (st_foreach): ditto - (get_keys): ditto - (get_values): ditto - (st_values_check): ditto - (st_reverse_foreach_check): ditto (unused) - (st_reverse_foreach): ditto (unused) - [ruby-core:69726] [Misc #10278] - Thu Jun 25 21:24:28 2015 Naohisa Goto <ngotogenome@g...> * test/-ext-/popen_deadlock/test_popen_deadlock.rb: test [Bug #11265] Index: st.c =================================================================== --- st.c (revision 51034) +++ st.c (revision 51035) @@ -14,7 +14,6 @@ https://github.com/ruby/ruby/blob/trunk/st.c#L14 #include <stdlib.h> #endif #include <string.h> -#include "ccan/list/list.h" typedef struct st_table_entry st_table_entry; @@ -23,7 +22,7 @@ struct st_table_entry { https://github.com/ruby/ruby/blob/trunk/st.c#L22 st_data_t key; st_data_t record; st_table_entry *next; - struct list_node olist; + st_table_entry *fore, *back; }; typedef struct st_packed_entry { @@ -108,6 +107,8 @@ st_realloc_bins(st_table_entry **bins, s https://github.com/ruby/ruby/blob/trunk/st.c#L107 /* Shortcut */ #define bins as.big.bins +#define head as.big.head +#define tail as.big.tail #define real_entries as.packed.real_entries /* preparation for possible packing improvements */ @@ -193,12 +194,6 @@ stat_col(void) https://github.com/ruby/ruby/blob/trunk/st.c#L194 } #endif -static struct list_head * -st_head(const st_table *tbl) -{ - return (struct list_head *)&tbl->as.big.private_list_head; -} - st_table* st_init_table_with_size(const struct st_hash_type *type, st_index_t size) { @@ -224,14 +219,14 @@ st_init_table_with_size(const struct st_ https://github.com/ruby/ruby/blob/trunk/st.c#L219 tbl->entries_packed = size <= MAX_PACKED_HASH; if (tbl->entries_packed) { size = ST_DEFAULT_PACKED_TABLE_SIZE; - tbl->real_entries = 0; } else { size = new_size(size); /* round up to power-of-two */ - list_head_init(st_head(tbl)); } tbl->num_bins = size; tbl->bins = st_alloc_bins(size); + tbl->head = 0; + tbl->tail = 0; return tbl; } @@ -282,6 +277,7 @@ void https://github.com/ruby/ruby/blob/trunk/st.c#L277 st_clear(st_table *table) { register st_table_entry *ptr, *next; + st_index_t i; if (table->entries_packed) { table->num_entries = 0; @@ -289,13 +285,18 @@ st_clear(st_table *table) https://github.com/ruby/ruby/blob/trunk/st.c#L285 return; } - list_for_each_safe(st_head(table), ptr, next, olist) { - /* list_del is not needed */ - st_free_entry(ptr); + for (i = 0; i < table->num_bins; i++) { + ptr = table->bins[i]; + table->bins[i] = 0; + while (ptr != 0) { + next = ptr->next; + st_free_entry(ptr); + ptr = next; + } } table->num_entries = 0; - MEMZERO(table->bins, st_table_entry*, table->num_bins); - list_head_init(st_head(table)); + table->head = 0; + table->tail = 0; } void @@ -463,7 +464,16 @@ add_direct(st_table *table, st_data_t ke https://github.com/ruby/ruby/blob/trunk/st.c#L464 } entry = new_entry(table, key, value, hash_val, bin_pos); - list_add_tail(st_head(table), &entry->olist); + + if (table->head != 0) { + entry->fore = 0; + (entry->back = table->tail)->fore = entry; + table->tail = entry; + } + else { + table->head = table->tail = entry; + entry->fore = entry->back = 0; + } table->num_entries++; } @@ -472,7 +482,7 @@ unpack_entries(register st_table *table) https://github.com/ruby/ruby/blob/trunk/st.c#L482 { st_index_t i; st_packed_entry packed_bins[MAX_PACKED_HASH]; - register st_table_entry *entry; + register st_table_entry *entry, *preventry = 0, **chain; st_table tmp_table = *table; MEMCPY(packed_bins, PACKED_BINS(table), st_packed_entry, MAX_PACKED_HASH); @@ -484,24 +494,22 @@ unpack_entries(register st_table *table) https://github.com/ruby/ruby/blob/trunk/st.c#L494 tmp_table.bins = st_realloc_bins(tmp_table.bins, ST_DEFAULT_INIT_TABLE_SIZE, tmp_table.num_bins); tmp_table.num_bins = ST_DEFAULT_INIT_TABLE_SIZE; #endif - - /* - * order is important here, we need to keep the original table - * walkable during GC (GC may be triggered by new_entry call) - */ i = 0; - list_head_init(st_head(&tmp_table)); + chain = &tmp_table.head; do { st_data_t key = packed_bins[i].key; st_data_t val = packed_bins[i].val; st_index_t hash = packed_bins[i].hash; entry = new_entry(&tmp_table, key, val, hash, hash_pos(hash, ST_DEFAULT_INIT_TABLE_SIZE)); - list_add_tail(st_head(&tmp_table), &entry->olist); + *chain = entry; + entry->back = preventry; + preventry = entry; + chain = &entry->fore; } while (++i < MAX_PACKED_HASH); + *chain = NULL; + tmp_table.tail = entry; *table = tmp_table; - list_head_init(st_head(table)); - list_append_list(st_head(table), st_head(&tmp_table)); } static void @@ -611,10 +619,12 @@ rehash(register st_table *table) https://github.com/ruby/ruby/blob/trunk/st.c#L619 table->num_bins = new_num_bins; table->bins = new_bins; - list_for_each(st_head(table), ptr, olist) { - hash_val = hash_pos(ptr->hash, new_num_bins); - ptr->next = new_bins[hash_val]; - new_bins[hash_val] = ptr; + if ((ptr = table->head) != 0) { + do { + hash_val = hash_pos(ptr->hash, new_num_bins); + ptr->next = new_bins[hash_val]; + new_bins[hash_val] = ptr; + } while ((ptr = ptr->fore) != 0); } } @@ -622,8 +632,9 @@ st_table* https://github.com/ruby/ruby/blob/trunk/st.c#L632 st_copy(st_table *old_table) { st_table *new_table; - st_table_entry *ptr, *entry; + st_table_entry *ptr, *entry, *prev, **tailp; st_index_t num_bins = old_table->num_bins; + st_index_t hash_val; new_table = st_alloc_table(); if (new_table == 0) { @@ -643,12 +654,24 @@ st_copy(st_table *old_table) https://github.com/ruby/ruby/blob/trunk/st.c#L654 return new_table; } - list_head_init(st_head(new_table)); - - list_for_each(st_head(old_table), ptr, olist) { - entry = new_entry(new_table, ptr->key, ptr->record, ptr->hash, - hash_pos(ptr->hash, num_bins)); - list_add_tail(st_head(new_table), &entry->olist); + if ((ptr = old_table->head) != 0) { + prev = 0; + tailp = &new_table->head; + do { + entry = st_alloc_entry(); + if (entry == 0) { + st_free_table(new_table); + return 0; + } + *entry = *ptr; + hash_val = hash_pos(entry->hash, num_bins); + entry->next = new_table->bins[hash_val]; + new_table->bins[hash_val] = entry; + entry->back = prev; + *tailp = prev = entry; + tailp = &entry->fore; + } while ((ptr = ptr->fore) != 0); + new_table->tail = prev; } return new_table; @@ -657,7 +680,17 @@ st_copy(st_table *old_table) https://github.com/ruby/ruby/blob/trunk/st.c#L680 static inline void remove_entry(st_table *table, st_table_entry *ptr) { - list_del(&ptr->olist); + if (ptr->fore == 0 && ptr->back == 0) { + table->head = 0; + table->tail = 0; + } + else { + st_table_entry *fore = ptr->fore, *back = ptr->back; + if (fore) fore->back = back; + if (back) back->fore = fore; + if (ptr == table->head) table->head = fore; + if (ptr == table->tail) table->tail = back; + } table->num_entries--; } @@ -737,7 +770,6 @@ st_delete_safe(register st_table *table, https://github.com/ruby/ruby/blob/trunk/st.c#L770 int st_shift(register st_table *table, register st_data_t *key, st_data_t *value) { - st_table_entry *old; st_table_entry **prev; register st_table_entry *ptr; @@ -753,13 +785,12 @@ st_shift(register st_table *table, regis https://github.com/ruby/ruby/blob/trunk/st.c#L785 return 1; } - old = list_pop(st_head(table), st_table_entry, olist); - table->num_entries--; - prev = &table->bins[hash_pos(old->hash, table->num_bins)]; - while ((ptr = *prev) != old) prev = &ptr->next; + prev = &table->bins[hash_pos(table->head->hash, table->num_bins)]; + while ((ptr = *prev) != table->head) prev = &ptr->next; *prev = ptr->next; if (value != 0) *value = ptr->record; *key = ptr->key; + remove_entry(table, ptr); st_free_entry(ptr); return 1; } @@ -886,8 +917,7 @@ st_update(st_table *table, st_data_t key https://github.com/ruby/ruby/blob/trunk/st.c#L917 int st_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t never) { - st_table_entry *ptr, **last, *tmp, *next; - struct list_head *head; + st_table_entry *ptr, **last, *tmp; enum st_retval retval; st_index_t i; @@ -904,10 +934,8 @@ st_foreach_check(st_table *table, int (* https://github.com/ruby/ruby/blob/trunk/st.c#L934 FIND_ENTRY(table, ptr, hash, i); if (retval == ST_CHECK) { if (!ptr) goto deleted; + goto unpacked_continue; } - if (table->num_entries == 0) return 0; - head = st_head(table); - next = list_entry(ptr->olist.next, st_table_entry, olist); goto unpacked; } switch (retval) { @@ -932,10 +960,14 @@ st_foreach_check(st_table *table, int (* https://github.com/ruby/ruby/blob/trunk/st.c#L960 } return 0; } + else { + ptr = table->head; + } - head = st_head(table); - list_for_each_safe(head, ptr, next, olist) { - if (ptr->key != never) { + if (ptr != 0) { + do { + if (ptr->key == never) + goto unpacked_continue; i = hash_pos(ptr->hash, table->num_bins); retval = (*func)(ptr->key, ptr->record, arg, 0); unpacked: @@ -951,6 +983,8 @@ st_foreach_check(st_table *table, int (* https://github.com/ruby/ruby/blob/trunk/st.c#L983 } /* fall through */ case ST_CONTINUE: + unpacked_continue: + ptr = ptr->fore; break; case ST_STOP: return 0; @@ -958,15 +992,16 @@ st_foreach_check(st_table *table, int (* https://github.com/ruby/ruby/blob/trunk/st.c#L992 last = &table->bins[hash_pos(ptr->hash, table->num_bins)]; for (; (tmp = *last) != 0; last = &tmp->next) { if (ptr == tmp) { + tmp = ptr->fore; remove_entry(table, ptr); ptr->key = ptr->record = never; ptr->hash = 0; + ptr = tmp; break; } } - if (table->num_entries == 0) return 0; } - } + } while (ptr && table->head); } return 0; } @@ -974,9 +1009,8 @@ st_foreach_check(st_table *table, int (* https://github.com/ruby/ruby/blob/trunk/st.c#L1009 int st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) { - st_table_entry *ptr, **last, *tmp, *next; + st_table_entry *ptr, **last, *tmp; enum st_retval retval; - struct list_head *head; st_index_t i; if (table->entries_packed) { @@ -990,8 +1024,6 @@ st_foreach(st_table *table, int (*func)( https://github.com/ruby/ruby/blob/trunk/st.c#L1024 if (!table->entries_packed) { FIND_ENTRY(table, ptr, hash, i); if (!ptr) return 0; - head = st_head(table); - next = list_entry(ptr->olist.next, st_table_entry, olist); goto unpacked; } switch (retval) { @@ -1008,30 +1040,36 @@ st_foreach(st_table *table, int (*func)( https://github.com/ruby/ruby/blob/trunk/st.c#L1040 } return 0; } + else { + ptr = table->head; + } - head = st_head(table); - list_for_each_safe(head, ptr, next, olist) { - i = hash_pos(ptr->hash, table->num_bins); - retval = (*func)(ptr->key, ptr->record, arg, 0); - unpacked: - switch (retval) { - case ST_CONTINUE: - break; - case ST_CHECK: - case ST_STOP: - return 0; - case ST_DELETE: - last = &table->bins[hash_pos(ptr->hash, table->num_bins)]; - for (; (tmp = *last) != 0; last = &tmp->next) { - if (ptr == tmp) { - *last = ptr->next; - remove_entry(table, ptr); - st_free_entry(ptr); - break; + if (ptr != 0) { + do { + i = hash_pos(ptr->hash, table->num_bins); + retval = (*func)(ptr->key, ptr->record, arg, 0); + unpacked: + switch (retval) { + case ST_CONTINUE: + ptr = ptr->fore; + break; + case ST_CHECK: + case ST_STOP: + return 0; + case ST_DELETE: + last = &table->bins[hash_pos(ptr->hash, table->num_bins)]; + for (; (tmp = *last) != 0; last = &tmp->next) { + if (ptr == tmp) { + tmp = ptr->fore; + *last = ptr->next; + remove_entry(table, ptr); + st_free_entry(ptr); + ptr = tmp; + break; + } } } - if (table->num_entries == 0) return 0; - } + } while (ptr && table->head); } return 0; } @@ -1053,11 +1091,9 @@ get_keys(st_table *table, st_data_t *key https://github.com/ruby/ruby/blob/trunk/st.c#L1091 } } else { - st_table_entry *ptr; + st_table_entry *ptr = table->head; st_data_t *keys_end = keys + size; - - list_for_each(st_head(table), ptr, olist) { - if (keys >= keys_end) break; + for (; ptr && keys < keys_end; ptr = ptr->fore) { key = ptr->key; if (check && key == never) continue; *keys++ = key; @@ -1096,11 +1132,9 @@ get_values(st_table *table, st_data_t *v https://github.com/ruby/ruby/blob/trunk/st.c#L1132 } } else { - st_table_entry *ptr; + st_table_entry *ptr = table->head; st_data_t *values_end = values + size; - - list_for_each(st_head(table), ptr, olist) { - if (values >= values_end) break; + for (; ptr && values < values_end; ptr = ptr->fore) { key = ptr->key; if (check && key == never) continue; *values++ = ptr->record; @@ -1126,8 +1160,7 @@ st_values_check(st_table *table, st_data https://github.com/ruby/ruby/blob/trunk/st.c#L1160 int st_reverse_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t never) { - st_table_entry *ptr, **last, *tmp, *next; - struct list_head *head; + st_table_entry *ptr, **last, *tmp; enum st_retval retval; st_index_t i; @@ -1145,10 +1178,8 @@ st_reverse_foreach_check(st_table *table https://github.com/ruby/ruby/blob/trunk/st.c#L1178 FIND_ENTRY(table, ptr, hash, i); if (retval == ST_CHECK) { if (!ptr) goto deleted; + goto unpacked_continue; } - if (table->num_entries == 0) return 0; - head = st_head(table); - next = list_entry(ptr->olist.next, st_table_entry, olist); goto unpacked; } switch (retval) { @@ -1173,10 +1204,14 @@ st_reverse_foreach_check(st_table *table https://github.com/ruby/ruby/blob/trunk/st.c#L1204 } return 0; } + else { + ptr = table->tail; + } - head = st_head(table); - list_for_each_rev_safe(head, ptr, next, olist) { - if (ptr->key != never) { + if (ptr != 0) { + do { + if (ptr->key == never) + goto unpacked_continue; i = hash_pos(ptr->hash, table->num_bins); retval = (*func)(ptr->key, ptr->record, arg, 0); unpacked: @@ -1192,6 +1227,8 @@ st_reverse_foreach_check(st_table *table https://github.com/ruby/ruby/blob/trunk/st.c#L1227 } /* fall through */ case ST_CONTINUE: + unpacked_continue: + ptr = ptr->back; break; case ST_STOP: return 0; @@ -1199,15 +1236,16 @@ st_reverse_foreach_check(st_table *table https://github.com/ruby/ruby/blob/trunk/st.c#L1236 last = &table->bins[hash_pos(ptr->hash, table->num_bins)]; for (; (tmp = *last) != 0; last = &tmp->next) { if (ptr == tmp) { + tmp = ptr->back; remove_entry(table, ptr); ptr->key = ptr->record = never; ptr->hash = 0; + ptr = tmp; break; } } - if (table->num_entries == 0) return 0; } - } + } while (ptr && table->head); } return 0; } @@ -1215,9 +1253,8 @@ st_reverse_foreach_check(st_table *table https://github.com/ruby/ruby/blob/trunk/st.c#L1253 int st_reverse_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) { - st_table_entry *ptr, **last, *tmp, *next; + st_table_entry *ptr, **last, *tmp; enum st_retval retval; - struct list_head *head; st_index_t i; if (table->entries_packed) { @@ -1232,8 +1269,6 @@ st_reverse_foreach(st_table *table, int https://github.com/ruby/ruby/blob/trunk/st.c#L1269 if (!table->entries_packed) { FIND_ENTRY(table, ptr, hash, i); if (!ptr) return 0; - head = st_head(table); - next = list_entry(ptr->olist.next, st_table_entry, olist); goto unpacked; } switch (retval) { @@ -1249,30 +1284,36 @@ st_reverse_foreach(st_table *table, int https://github.com/ruby/ruby/blob/trunk/st.c#L1284 } return 0; } + else { + ptr = table->tail; + } - head = st_head(table); - list_for_each_rev_safe(head, ptr, next, olist) { - i = hash_pos(ptr->hash, table->num_bins); - retval = (*func)(ptr->key, ptr->record, arg, 0); - unpacked: - switch (retval) { - case ST_CONTINUE: - break; - case ST_CHECK: - case ST_STOP: - return 0; - case ST_DELETE: - last = &table->bins[hash_pos(ptr->hash, table->num_bins)]; - for (; (tmp = *last) != 0; last = &tmp->next) { - if (ptr == tmp) { - *last = ptr->next; - remove_entry(table, ptr); - st_free_entry(ptr); - break; + if (ptr != 0) { + do { + i = hash_pos(ptr->hash, table->num_bins); + retval = (*func)(ptr->key, ptr->record, arg, 0); + unpacked: + switch (retval) { + case ST_CONTINUE: + ptr = ptr->back; + break; + case ST_CHECK: + case ST_STOP: + return 0; + case ST_DELETE: + last = &table->bins[hash_pos(ptr->hash, table->num_bins)]; + for (; (tmp = *last) != 0; last = &tmp->next) { + if (ptr == tmp) { + tmp = ptr->back; + *last = ptr->next; + remove_entry(table, ptr); + st_free_entry(ptr); + ptr = tmp; + break; + } } } - if (table->num_entries == 0) return 0; - } + } while (ptr && table->head); } return 0; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/