From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-0.8 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, MSGID_RANDY shortcircuit=no autolearn=no version=3.3.2 X-Original-To: spew@80x24.org Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id CF85E1F770; Thu, 2 Oct 2014 18:48:13 +0000 (UTC) Date: Thu, 2 Oct 2014 18:48:13 +0000 From: Eric Wong To: spew@80x24.org Subject: [PATCH 2/1] st.c: fix up st_foreach* for ccan linked-list Message-ID: References: <1411411308-24223-1-git-send-email-e@80x24.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1411411308-24223-1-git-send-email-e@80x24.org> List-Id: This needs tests, but it seems the packed => unpacked transitions are totally untested in the current Ruby implementation. Fortunately, it seems hash.c bans such transitions. --- st.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/st.c b/st.c index f08fcb7..10604db 100644 --- a/st.c +++ b/st.c @@ -867,9 +867,9 @@ st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data 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, *resume_tail = 0; - struct list_head resume_head; + st_table_entry *ptr, **last, *tmp; struct list_head *head; + struct list_node *cur, *n; enum st_retval retval; st_index_t i; @@ -882,16 +882,17 @@ st_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t hash = PHASH(table, i); if (key == never) continue; retval = (*func)(key, val, arg, 0); - if (!table->entries_packed) { + if (!table->entries_packed) { /* XXX untested, never happens */ FIND_ENTRY(table, ptr, hash, i); if (retval == ST_CHECK) { if (!ptr) goto deleted; } if (table->num_entries == 0) return 0; - resume_head.n = ptr->olist; - head = &resume_head; - next = list_next(st_head(table), ptr, olist); - resume_tail = list_tail(st_head(table), st_table_entry, olist); + + cur = ptr->olist.next; + n = cur->next; + head = st_head(table); + ptr = container_of(cur, struct st_table_entry, olist); goto unpacked; } switch (retval) { @@ -918,7 +919,10 @@ st_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t } head = st_head(table); - list_for_each_safe(head, ptr, next, olist) { + for (cur = head->n.next, n = cur->next; + cur != &head->n; + cur = n, n = cur->next) { + ptr = container_of(cur, struct st_table_entry, olist); if (ptr->key != never) { i = hash_pos(ptr->hash, table->num_bins); retval = (*func)(ptr->key, ptr->record, arg, 0); @@ -951,8 +955,6 @@ st_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t if (table->num_entries == 0) return 0; } } - - if (resume_tail == ptr) break; } return 0; } @@ -960,10 +962,10 @@ st_foreach_check(st_table *table, int (*func)(ANYARGS), st_data_t arg, st_data_t int st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) { - st_table_entry *ptr, **last, *tmp, *next, *resume_tail = 0; + st_table_entry *ptr, **last, *tmp; enum st_retval retval; - struct list_head resume_head; struct list_head *head; + struct list_node *cur, *n; st_index_t i; if (table->entries_packed) { @@ -977,10 +979,11 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) if (!table->entries_packed) { FIND_ENTRY(table, ptr, hash, i); if (!ptr) return 0; - resume_head.n = ptr->olist; - head = &resume_head; - next = list_next(st_head(table), ptr, olist); - resume_tail = list_tail(st_head(table), st_table_entry, olist); + + cur = ptr->olist.next; + n = cur->next; + head = st_head(table); + ptr = container_of(cur, struct st_table_entry, olist); goto unpacked; } switch (retval) { @@ -999,7 +1002,10 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) } head = st_head(table); - list_for_each_safe(head, ptr, next, olist) { + for (cur = head->n.next, n = cur->next; + cur != &head->n; + cur = n, n = cur->next) { + ptr = container_of(cur, struct st_table_entry, olist); i = hash_pos(ptr->hash, table->num_bins); retval = (*func)(ptr->key, ptr->record, arg, 0); unpacked: @@ -1021,8 +1027,6 @@ st_foreach(st_table *table, int (*func)(ANYARGS), st_data_t arg) } if (table->num_entries == 0) return 0; } - - if (resume_tail == ptr) break; } return 0; } -- EW