Skip to content

Commit

Permalink
lib/list: Add LIST_FOR_EACH_POP.
Browse files Browse the repository at this point in the history
Makes popping each member of the list a bit easier.

Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Russell Bryant <rbryant@redhat.com>
Acked-by: Ben Pfaff <blp@nicira.com>
  • Loading branch information
Jarno Rajahalme committed Apr 6, 2015
1 parent 660527a commit 5f03c98
Show file tree
Hide file tree
Showing 19 changed files with 70 additions and 66 deletions.
5 changes: 2 additions & 3 deletions lib/dp-packet.c
Expand Up @@ -465,10 +465,9 @@ dp_packet_to_string(const struct dp_packet *b, size_t maxbytes)
void
dp_packet_list_delete(struct ovs_list *list)
{
struct dp_packet *b, *next;
struct dp_packet *b;

LIST_FOR_EACH_SAFE (b, next, list_node, list) {
list_remove(&b->list_node);
LIST_FOR_EACH_POP (b, list_node, list) {
dp_packet_delete(b);
}
}
Expand Down
3 changes: 3 additions & 0 deletions lib/list.h
Expand Up @@ -73,6 +73,9 @@ static inline bool list_is_short(const struct ovs_list *);
? INIT_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER), 1 \
: 0); \
(ITER) = (NEXT))
#define LIST_FOR_EACH_POP(ITER, MEMBER, LIST) \
while (!list_is_empty(LIST) \
&& (INIT_CONTAINER(ITER, list_pop_front(LIST), MEMBER), 1))

/* Inline implementations. */

Expand Down
5 changes: 2 additions & 3 deletions lib/lldp/lldpd-structs.c
Expand Up @@ -28,13 +28,12 @@ VLOG_DEFINE_THIS_MODULE(lldpd_structs);
void
lldpd_chassis_mgmt_cleanup(struct lldpd_chassis *chassis)
{
struct lldpd_mgmt *mgmt, *mgmt_next;
struct lldpd_mgmt *mgmt;

VLOG_DBG("cleanup management addresses for chassis %s",
chassis->c_name ? chassis->c_name : "(unknown)");

LIST_FOR_EACH_SAFE (mgmt, mgmt_next, m_entries, &chassis->c_mgmt) {
list_remove(&mgmt->m_entries);
LIST_FOR_EACH_POP (mgmt, m_entries, &chassis->c_mgmt) {
free(mgmt);
}

Expand Down
5 changes: 2 additions & 3 deletions lib/lldp/lldpd.c
Expand Up @@ -164,7 +164,7 @@ static void
lldpd_move_chassis(struct lldpd_chassis *ochassis,
struct lldpd_chassis *chassis)
{
struct lldpd_mgmt *mgmt, *mgmt_next;
struct lldpd_mgmt *mgmt;
int refcount = ochassis->c_refcount;
int index = ochassis->c_index;
struct ovs_list listcopy;
Expand All @@ -182,8 +182,7 @@ lldpd_move_chassis(struct lldpd_chassis *ochassis,
list_init(&ochassis->c_mgmt);

/* Copy of management addresses */
LIST_FOR_EACH_SAFE (mgmt, mgmt_next, m_entries, &chassis->c_mgmt) {
list_remove(&mgmt->m_entries);
LIST_FOR_EACH_POP (mgmt, m_entries, &chassis->c_mgmt) {
list_insert(&ochassis->c_mgmt, &mgmt->m_entries);
}

Expand Down
5 changes: 2 additions & 3 deletions lib/mcast-snooping.c
Expand Up @@ -307,10 +307,9 @@ static void
mcast_snooping_flush_group(struct mcast_snooping *ms, struct mcast_group *grp)
OVS_REQ_WRLOCK(ms->rwlock)
{
struct mcast_group_bundle *b, *next_b;
struct mcast_group_bundle *b;

LIST_FOR_EACH_SAFE (b, next_b, bundle_node, &grp->bundle_lru) {
list_remove(&b->bundle_node);
LIST_FOR_EACH_POP (b, bundle_node, &grp->bundle_lru) {
free(b);
}
mcast_snooping_flush_group__(ms, grp);
Expand Down
5 changes: 2 additions & 3 deletions lib/ofp-util.c
Expand Up @@ -6886,10 +6886,9 @@ ofputil_decode_port_stats_request(const struct ofp_header *request,
void
ofputil_bucket_list_destroy(struct ovs_list *buckets)
{
struct ofputil_bucket *bucket, *next_bucket;
struct ofputil_bucket *bucket;

LIST_FOR_EACH_SAFE (bucket, next_bucket, list_node, buckets) {
list_remove(&bucket->list_node);
LIST_FOR_EACH_POP (bucket, list_node, buckets) {
free(bucket->ofpacts);
free(bucket);
}
Expand Down
5 changes: 2 additions & 3 deletions lib/ofpbuf.c
Expand Up @@ -477,10 +477,9 @@ ofpbuf_to_string(const struct ofpbuf *b, size_t maxbytes)
void
ofpbuf_list_delete(struct ovs_list *list)
{
struct ofpbuf *b, *next;
struct ofpbuf *b;

LIST_FOR_EACH_SAFE (b, next, list_node, list) {
list_remove(&b->list_node);
LIST_FOR_EACH_POP (b, list_node, list) {
ofpbuf_delete(b);
}
}
8 changes: 2 additions & 6 deletions lib/ovs-lldp.c
Expand Up @@ -421,12 +421,9 @@ aa_get_vlan_queued(struct ovs_list *list)
ovs_mutex_lock(&mutex);

HMAP_FOR_EACH (lldp, hmap_node, all_lldps) {
struct bridge_aa_vlan *node, *node_next;
struct bridge_aa_vlan *node;

LIST_FOR_EACH_SAFE (node,
node_next,
list_node,
&lldp->active_mapping_queue) {
LIST_FOR_EACH_POP (node, list_node, &lldp->active_mapping_queue) {
struct bridge_aa_vlan *copy;

copy = xmalloc(sizeof *copy);
Expand All @@ -437,7 +434,6 @@ aa_get_vlan_queued(struct ovs_list *list)
list_push_back(list, &copy->list_node);

/* Cleanup */
list_remove(&node->list_node);
free(node->port_name);
free(node);
}
Expand Down
5 changes: 2 additions & 3 deletions lib/ovs-numa.c
Expand Up @@ -380,10 +380,9 @@ ovs_numa_dump_cores_on_numa(int numa_id)
void
ovs_numa_dump_destroy(struct ovs_numa_dump *dump)
{
struct ovs_numa_info *iter, *next;
struct ovs_numa_info *iter;

LIST_FOR_EACH_SAFE (iter, next, list_node, &dump->dump) {
list_remove(&iter->list_node);
LIST_FOR_EACH_POP (iter, list_node, &dump->dump) {
free(iter);
}

Expand Down
5 changes: 2 additions & 3 deletions lib/ovs-rcu.c
Expand Up @@ -239,7 +239,7 @@ ovsrcu_postpone__(void (*function)(void *aux), void *aux)
static bool
ovsrcu_call_postponed(void)
{
struct ovsrcu_cbset *cbset, *next_cbset;
struct ovsrcu_cbset *cbset;
struct ovs_list cbsets;

guarded_list_pop_all(&flushed_cbsets, &cbsets);
Expand All @@ -249,13 +249,12 @@ ovsrcu_call_postponed(void)

ovsrcu_synchronize();

LIST_FOR_EACH_SAFE (cbset, next_cbset, list_node, &cbsets) {
LIST_FOR_EACH_POP (cbset, list_node, &cbsets) {
struct ovsrcu_cb *cb;

for (cb = cbset->cbs; cb < &cbset->cbs[cbset->n_cbs]; cb++) {
cb->function(cb->aux);
}
list_remove(&cbset->list_node);
free(cbset);
}

Expand Down
6 changes: 2 additions & 4 deletions lib/vconn.c
Expand Up @@ -881,13 +881,11 @@ int
vconn_transact_multiple_noreply(struct vconn *vconn, struct ovs_list *requests,
struct ofpbuf **replyp)
{
struct ofpbuf *request, *next;
struct ofpbuf *request;

LIST_FOR_EACH_SAFE (request, next, list_node, requests) {
LIST_FOR_EACH_POP (request, list_node, requests) {
int error;

list_remove(&request->list_node);

error = vconn_transact_noreply(vconn, request, replyp);
if (error || *replyp) {
ofpbuf_list_delete(requests);
Expand Down
5 changes: 2 additions & 3 deletions ofproto/bundles.c
Expand Up @@ -100,11 +100,10 @@ ofp_bundle_create(uint32_t id, uint16_t flags)
static void
ofp_bundle_remove(struct ofconn *ofconn, struct ofp_bundle *item)
{
struct bundle_message *msg, *next;
struct bundle_message *msg;
struct hmap *bundles;

LIST_FOR_EACH_SAFE (msg, next, node, &item->msg_list) {
list_remove(&msg->node);
LIST_FOR_EACH_POP (msg, node, &item->msg_list) {
free(msg->msg);
free(msg);
}
Expand Down
16 changes: 6 additions & 10 deletions ofproto/connmgr.c
Expand Up @@ -1093,10 +1093,9 @@ ofconn_send_reply(const struct ofconn *ofconn, struct ofpbuf *msg)
void
ofconn_send_replies(const struct ofconn *ofconn, struct ovs_list *replies)
{
struct ofpbuf *reply, *next;
struct ofpbuf *reply;

LIST_FOR_EACH_SAFE (reply, next, list_node, replies) {
list_remove(&reply->list_node);
LIST_FOR_EACH_POP (reply, list_node, replies) {
ofconn_send_reply(ofconn, reply);
}
}
Expand Down Expand Up @@ -1724,11 +1723,9 @@ connmgr_send_packet_in(struct connmgr *mgr,
static void
do_send_packet_ins(struct ofconn *ofconn, struct ovs_list *txq)
{
struct ofpbuf *pin, *next_pin;

LIST_FOR_EACH_SAFE (pin, next_pin, list_node, txq) {
list_remove(&pin->list_node);
struct ofpbuf *pin;

LIST_FOR_EACH_POP (pin, list_node, txq) {
if (rconn_send_with_limit(ofconn->rconn, pin,
ofconn->packet_in_counter, 100) == EAGAIN) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
Expand Down Expand Up @@ -2255,12 +2252,11 @@ ofmonitor_flush(struct connmgr *mgr)
struct ofconn *ofconn;

LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
struct ofpbuf *msg, *next;
struct ofpbuf *msg;

LIST_FOR_EACH_SAFE (msg, next, list_node, &ofconn->updates) {
LIST_FOR_EACH_POP (msg, list_node, &ofconn->updates) {
unsigned int n_bytes;

list_remove(&msg->list_node);
ofconn_send(ofconn, msg, ofconn->monitor_counter);
n_bytes = rconn_packet_counter_n_bytes(ofconn->monitor_counter);
if (!ofconn->monitor_paused && n_bytes > 128 * 1024) {
Expand Down
5 changes: 2 additions & 3 deletions ofproto/ofproto-dpif-rid.c
Expand Up @@ -67,7 +67,7 @@ recirc_run(void)
/* Do maintenance at most 4 times / sec. */
ovs_mutex_lock(&mutex);
if (now - last > 250) {
struct recirc_id_node *node, *next;
struct recirc_id_node *node;

last = now;

Expand All @@ -86,8 +86,7 @@ recirc_run(void)
/* Delete the expired. These have been lingering for at least 250 ms,
* which should be enough for any ongoing recirculations to be
* finished. */
LIST_FOR_EACH_SAFE (node, next, exp_node, &expired) {
list_remove(&node->exp_node);
LIST_FOR_EACH_POP (node, exp_node, &expired) {
cmap_remove(&id_map, &node->id_node, node->id);
ovsrcu_postpone(free, node);
}
Expand Down
5 changes: 2 additions & 3 deletions ofproto/ofproto-dpif-xlate.c
Expand Up @@ -949,14 +949,13 @@ xlate_bundle_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
static void
xlate_xbundle_remove(struct xlate_cfg *xcfg, struct xbundle *xbundle)
{
struct xport *xport, *next;
struct xport *xport;

if (!xbundle) {
return;
}

LIST_FOR_EACH_SAFE (xport, next, bundle_node, &xbundle->xports) {
list_remove(&xport->bundle_node);
LIST_FOR_EACH_POP (xport, bundle_node, &xbundle->xports) {
xport->xbundle = NULL;
}

Expand Down
15 changes: 6 additions & 9 deletions ofproto/ofproto-dpif.c
Expand Up @@ -886,7 +886,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
struct dpif_port port;
struct shash_node *node;
struct ovs_list garbage_list;
struct odp_garbage *garbage, *next;
struct odp_garbage *garbage;

struct sset names;
char *backer_name;
Expand Down Expand Up @@ -964,9 +964,8 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
}
dpif_port_dump_done(&port_dump);

LIST_FOR_EACH_SAFE (garbage, next, list_node, &garbage_list) {
LIST_FOR_EACH_POP (garbage, list_node, &garbage_list) {
dpif_port_del(backer->dpif, garbage->odp_port);
list_remove(&garbage->list_node);
free(garbage);
}

Expand Down Expand Up @@ -1377,7 +1376,7 @@ static void
destruct(struct ofproto *ofproto_)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
struct ofproto_packet_in *pin, *next_pin;
struct ofproto_packet_in *pin;
struct rule_dpif *rule;
struct oftable *table;
struct ovs_list pins;
Expand All @@ -1400,8 +1399,7 @@ destruct(struct ofproto *ofproto_)
}

guarded_list_pop_all(&ofproto->pins, &pins);
LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &pins) {
list_remove(&pin->list_node);
LIST_FOR_EACH_POP (pin, list_node, &pins) {
free(CONST_CAST(void *, pin->up.packet));
free(pin);
}
Expand Down Expand Up @@ -1456,13 +1454,12 @@ run(struct ofproto *ofproto_)
/* Do not perform any periodic activity required by 'ofproto' while
* waiting for flow restore to complete. */
if (!ofproto_get_flow_restore_wait()) {
struct ofproto_packet_in *pin, *next_pin;
struct ofproto_packet_in *pin;
struct ovs_list pins;

guarded_list_pop_all(&ofproto->pins, &pins);
LIST_FOR_EACH_SAFE (pin, next_pin, list_node, &pins) {
LIST_FOR_EACH_POP (pin, list_node, &pins) {
connmgr_send_packet_in(ofproto->up.connmgr, pin);
list_remove(&pin->list_node);
free(CONST_CAST(void *, pin->up.packet));
free(pin);
}
Expand Down
5 changes: 2 additions & 3 deletions ofproto/ofproto.c
Expand Up @@ -2961,9 +2961,9 @@ static void
learned_cookies_flush(struct ofproto *ofproto, struct ovs_list *dead_cookies)
OVS_REQUIRES(ofproto_mutex)
{
struct learned_cookie *c, *next;
struct learned_cookie *c;

LIST_FOR_EACH_SAFE (c, next, u.list_node, dead_cookies) {
LIST_FOR_EACH_POP (c, u.list_node, dead_cookies) {
struct rule_criteria criteria;
struct rule_collection rules;
struct match match;
Expand All @@ -2977,7 +2977,6 @@ learned_cookies_flush(struct ofproto *ofproto, struct ovs_list *dead_cookies)
rule_criteria_destroy(&criteria);
rule_collection_destroy(&rules);

list_remove(&c->u.list_node);
free(c);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/library.at
Expand Up @@ -38,7 +38,7 @@ AT_CHECK([ovstest test-atomic])
AT_CLEANUP

AT_SETUP([test linked lists])
AT_CHECK([ovstest test-list], [0], [..
AT_CHECK([ovstest test-list], [0], [...
])
AT_CLEANUP

Expand Down
26 changes: 26 additions & 0 deletions tests/test-list.c
Expand Up @@ -159,6 +159,31 @@ test_list_for_each_safe(void)
}
}

/* Tests that LIST_FOR_EACH_POP removes the elements of a list. */
static void
test_list_for_each_pop(void)
{
enum { MAX_ELEMS = 10 };
size_t n;

for (n = 0; n <= MAX_ELEMS; n++) {
struct element elements[MAX_ELEMS];
int values[MAX_ELEMS];
struct ovs_list list;
struct element *e;
size_t n_remaining;

make_list(&list, elements, values, n);

n_remaining = n;
LIST_FOR_EACH_POP (e, node, &list) {
n_remaining--;
memmove(values, values + 1, sizeof *values * n_remaining);
check_list(&list, values, n_remaining);
}
}
}

static void
run_test(void (*function)(void))
{
Expand All @@ -171,6 +196,7 @@ test_list_main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
{
run_test(test_list_construction);
run_test(test_list_for_each_safe);
run_test(test_list_for_each_pop);
printf("\n");
}

Expand Down

0 comments on commit 5f03c98

Please sign in to comment.