Skip to content

Commit

Permalink
Switch many macros from using CONTAINER_OF to using OBJECT_CONTAINING.
Browse files Browse the repository at this point in the history
These macros require one fewer argument by switching, which makes code
that uses them shorter and more readable.
  • Loading branch information
blp committed Oct 1, 2010
1 parent adf7cfd commit 4e8e421
Show file tree
Hide file tree
Showing 33 changed files with 197 additions and 261 deletions.
43 changes: 17 additions & 26 deletions lib/classifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,7 @@ classifier_destroy(struct classifier *cls)
struct hmap *tbl;

for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) {
HMAP_FOR_EACH_SAFE (bucket, next_bucket,
struct cls_bucket, hmap_node, tbl) {
HMAP_FOR_EACH_SAFE (bucket, next_bucket, hmap_node, tbl) {
free(bucket);
}
hmap_destroy(tbl);
Expand Down Expand Up @@ -335,11 +334,11 @@ classifier_find_rule_exactly(const struct classifier *cls,
assert(wildcards == (wildcards & OVSFW_ALL));
table_idx = table_idx_from_wildcards(wildcards);
hash = hash_fields(target, table_idx);
HMAP_FOR_EACH_WITH_HASH (bucket, struct cls_bucket, hmap_node, hash,
HMAP_FOR_EACH_WITH_HASH (bucket, hmap_node, hash,
&cls->tables[table_idx]) {
if (equal_fields(&bucket->fixed, target, table_idx)) {
struct cls_rule *pos;
LIST_FOR_EACH (pos, struct cls_rule, node.list, &bucket->rules) {
LIST_FOR_EACH (pos, node.list, &bucket->rules) {
if (pos->priority < priority) {
return NULL;
} else if (pos->priority == priority &&
Expand Down Expand Up @@ -374,13 +373,12 @@ classifier_rule_overlaps(const struct classifier *cls,
for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) {
struct cls_bucket *bucket;

HMAP_FOR_EACH (bucket, struct cls_bucket, hmap_node, tbl) {
HMAP_FOR_EACH (bucket, hmap_node, tbl) {
struct cls_rule *rule;

LIST_FOR_EACH (rule, struct cls_rule, node.list,
&bucket->rules) {
LIST_FOR_EACH (rule, node.list, &bucket->rules) {
if (rule->priority == priority
&& rules_match_2wild(rule, &target_rule, 0)) {
&& rules_match_2wild(rule, &target_rule, 0)) {
return true;
}
}
Expand Down Expand Up @@ -409,8 +407,7 @@ classifier_for_each_match(const struct classifier *cls,
table++) {
struct cls_bucket *bucket, *next_bucket;

HMAP_FOR_EACH_SAFE (bucket, next_bucket,
struct cls_bucket, hmap_node, table) {
HMAP_FOR_EACH_SAFE (bucket, next_bucket, hmap_node, table) {
/* XXX there is a bit of room for optimization here based on
* rejecting entire buckets on their fixed fields, but it will
* only be worthwhile for big buckets (which we hope we won't
Expand All @@ -422,8 +419,7 @@ classifier_for_each_match(const struct classifier *cls,
* bucket itself will be destroyed. The bucket contains the
* list head so that's a use-after-free error. */
prev_rule = NULL;
LIST_FOR_EACH (rule, struct cls_rule, node.list,
&bucket->rules) {
LIST_FOR_EACH (rule, node.list, &bucket->rules) {
if (rules_match_1wild(rule, target, 0)) {
if (prev_rule) {
callback(prev_rule, aux);
Expand All @@ -442,7 +438,7 @@ classifier_for_each_match(const struct classifier *cls,
if (target->wc.wildcards) {
struct cls_rule *rule, *next_rule;

HMAP_FOR_EACH_SAFE (rule, next_rule, struct cls_rule, node.hmap,
HMAP_FOR_EACH_SAFE (rule, next_rule, node.hmap,
&cls->exact_table) {
if (rules_match_1wild(rule, target, 0)) {
callback(rule, aux);
Expand Down Expand Up @@ -477,17 +473,15 @@ classifier_for_each(const struct classifier *cls, int include,
for (tbl = &cls->tables[0]; tbl < &cls->tables[CLS_N_FIELDS]; tbl++) {
struct cls_bucket *bucket, *next_bucket;

HMAP_FOR_EACH_SAFE (bucket, next_bucket,
struct cls_bucket, hmap_node, tbl) {
HMAP_FOR_EACH_SAFE (bucket, next_bucket, hmap_node, tbl) {
struct cls_rule *prev_rule, *rule;

/* We can't just use LIST_FOR_EACH_SAFE here because, if the
* callback deletes the last rule in the bucket, then the
* bucket itself will be destroyed. The bucket contains the
* list head so that's a use-after-free error. */
prev_rule = NULL;
LIST_FOR_EACH (rule, struct cls_rule, node.list,
&bucket->rules) {
LIST_FOR_EACH (rule, node.list, &bucket->rules) {
if (prev_rule) {
callback(prev_rule, aux);
}
Expand All @@ -503,8 +497,7 @@ classifier_for_each(const struct classifier *cls, int include,
if (include & CLS_INC_EXACT) {
struct cls_rule *rule, *next_rule;

HMAP_FOR_EACH_SAFE (rule, next_rule,
struct cls_rule, node.hmap, &cls->exact_table) {
HMAP_FOR_EACH_SAFE (rule, next_rule, node.hmap, &cls->exact_table) {
callback(rule, aux);
}
}
Expand Down Expand Up @@ -641,7 +634,7 @@ static struct cls_rule *
bucket_insert(struct cls_bucket *bucket, struct cls_rule *rule)
{
struct cls_rule *pos;
LIST_FOR_EACH (pos, struct cls_rule, node.list, &bucket->rules) {
LIST_FOR_EACH (pos, node.list, &bucket->rules) {
if (pos->priority == rule->priority) {
if (pos->wc.wildcards == rule->wc.wildcards
&& rules_match_1wild(pos, rule, rule->table_idx))
Expand Down Expand Up @@ -679,8 +672,7 @@ static struct cls_bucket *
find_bucket(struct hmap *table, size_t hash, const struct cls_rule *rule)
{
struct cls_bucket *bucket;
HMAP_FOR_EACH_WITH_HASH (bucket, struct cls_bucket, hmap_node, hash,
table) {
HMAP_FOR_EACH_WITH_HASH (bucket, hmap_node, hash, table) {
if (equal_fields(&bucket->fixed, &rule->flow, rule->table_idx)) {
return bucket;
}
Expand Down Expand Up @@ -850,7 +842,7 @@ search_bucket(struct cls_bucket *bucket, int field_idx,
return NULL;
}

LIST_FOR_EACH (pos, struct cls_rule, node.list, &bucket->rules) {
LIST_FOR_EACH (pos, node.list, &bucket->rules) {
if (rules_match_1wild(target, pos, field_idx)) {
return pos;
}
Expand Down Expand Up @@ -878,7 +870,7 @@ search_table(const struct hmap *table, int field_idx,
return search_bucket(bucket, field_idx, target);
}

HMAP_FOR_EACH_WITH_HASH (bucket, struct cls_bucket, hmap_node,
HMAP_FOR_EACH_WITH_HASH (bucket, hmap_node,
hash_fields(&target->flow, field_idx), table) {
struct cls_rule *rule = search_bucket(bucket, field_idx, target);
if (rule) {
Expand All @@ -894,8 +886,7 @@ search_exact_table(const struct classifier *cls, size_t hash,
{
struct cls_rule *rule;

HMAP_FOR_EACH_WITH_HASH (rule, struct cls_rule, node.hmap,
hash, &cls->exact_table) {
HMAP_FOR_EACH_WITH_HASH (rule, node.hmap, hash, &cls->exact_table) {
if (flow_equal(&rule->flow, target)) {
return rule;
}
Expand Down
20 changes: 9 additions & 11 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ get_port_by_name(struct dp_netdev *dp,
{
struct dp_netdev_port *port;

LIST_FOR_EACH (port, struct dp_netdev_port, node, &dp->port_list) {
LIST_FOR_EACH (port, node, &dp->port_list) {
if (!strcmp(netdev_get_name(port->netdev), devname)) {
*portp = port;
return 0;
Expand Down Expand Up @@ -545,8 +545,7 @@ dp_netdev_flow_flush(struct dp_netdev *dp)
{
struct dp_netdev_flow *flow, *next;

HMAP_FOR_EACH_SAFE (flow, next, struct dp_netdev_flow, node,
&dp->flow_table) {
HMAP_FOR_EACH_SAFE (flow, next, node, &dp->flow_table) {
dp_netdev_free_flow(dp, flow);
}
}
Expand All @@ -567,7 +566,7 @@ dpif_netdev_port_list(const struct dpif *dpif, struct odp_port *ports, int n)
int i;

i = 0;
LIST_FOR_EACH (port, struct dp_netdev_port, node, &dp->port_list) {
LIST_FOR_EACH (port, node, &dp->port_list) {
struct odp_port *odp_port = &ports[i];
if (i >= n) {
break;
Expand Down Expand Up @@ -661,8 +660,7 @@ dp_netdev_lookup_flow(const struct dp_netdev *dp, const flow_t *key)
struct dp_netdev_flow *flow;

assert(!key->reserved[0] && !key->reserved[1] && !key->reserved[2]);
HMAP_FOR_EACH_WITH_HASH (flow, struct dp_netdev_flow, node,
flow_hash(key, 0), &dp->flow_table) {
HMAP_FOR_EACH_WITH_HASH (flow, node, flow_hash(key, 0), &dp->flow_table) {
if (flow_equal(&flow->key, key)) {
return flow;
}
Expand Down Expand Up @@ -886,7 +884,7 @@ dpif_netdev_flow_list(const struct dpif *dpif, struct odp_flow flows[], int n)
int i;

i = 0;
HMAP_FOR_EACH (flow, struct dp_netdev_flow, node, &dp->flow_table) {
HMAP_FOR_EACH (flow, node, &dp->flow_table) {
if (i >= n) {
break;
}
Expand Down Expand Up @@ -1044,10 +1042,10 @@ dp_netdev_run(void)
struct dp_netdev *dp;

ofpbuf_init(&packet, DP_NETDEV_HEADROOM + max_mtu);
LIST_FOR_EACH (dp, struct dp_netdev, node, &dp_netdev_list) {
LIST_FOR_EACH (dp, node, &dp_netdev_list) {
struct dp_netdev_port *port;

LIST_FOR_EACH (port, struct dp_netdev_port, node, &dp->port_list) {
LIST_FOR_EACH (port, node, &dp->port_list) {
int error;

/* Reset packet contents. */
Expand All @@ -1072,9 +1070,9 @@ dp_netdev_wait(void)
{
struct dp_netdev *dp;

LIST_FOR_EACH (dp, struct dp_netdev, node, &dp_netdev_list) {
LIST_FOR_EACH (dp, node, &dp_netdev_list) {
struct dp_netdev_port *port;
LIST_FOR_EACH (port, struct dp_netdev_port, node, &dp->port_list) {
LIST_FOR_EACH (port, node, &dp->port_list) {
netdev_recv_wait(port->netdev);
}
}
Expand Down
49 changes: 24 additions & 25 deletions lib/hmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,8 @@ struct hmap_node *hmap_random_node(const struct hmap *);
*
* HMAP_FOR_EACH_WITH_HASH iterates NODE over all of the nodes in HMAP that
* have hash value equal to HASH. HMAP_FOR_EACH_IN_BUCKET iterates NODE over
* all of the nodes in HMAP that would fall in the same bucket as HASH. STRUCT
* and MEMBER must be the name of the struct that contains the 'struct
* hmap_node' and the name of the 'struct hmap_node' member, respectively.
* all of the nodes in HMAP that would fall in the same bucket as HASH. MEMBER
* must be the name of the 'struct hmap_node' member within NODE.
*
* These macros may be used interchangeably to search for a particular value in
* an hmap, see, e.g. shash_find() for an example. Usually, using
Expand All @@ -113,18 +112,18 @@ struct hmap_node *hmap_random_node(const struct hmap *);
*
* HASH is only evaluated once.
*/
#define HMAP_FOR_EACH_WITH_HASH(NODE, STRUCT, MEMBER, HASH, HMAP) \
for ((NODE) = CONTAINER_OF(hmap_first_with_hash(HMAP, HASH), \
STRUCT, MEMBER); \
#define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \
for ((NODE) = OBJECT_CONTAINING(hmap_first_with_hash(HMAP, HASH), \
NODE, MEMBER); \
&(NODE)->MEMBER != NULL; \
(NODE) = CONTAINER_OF(hmap_next_with_hash(&(NODE)->MEMBER), \
STRUCT, MEMBER))
#define HMAP_FOR_EACH_IN_BUCKET(NODE, STRUCT, MEMBER, HASH, HMAP) \
for ((NODE) = CONTAINER_OF(hmap_first_in_bucket(HMAP, HASH), \
STRUCT, MEMBER); \
(NODE) = OBJECT_CONTAINING(hmap_next_with_hash(&(NODE)->MEMBER), \
NODE, MEMBER))
#define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP) \
for ((NODE) = OBJECT_CONTAINING(hmap_first_in_bucket(HMAP, HASH), \
NODE, MEMBER); \
&(NODE)->MEMBER != NULL; \
(NODE) = CONTAINER_OF(hmap_next_in_bucket(&(NODE)->MEMBER), \
STRUCT, MEMBER))
(NODE) = OBJECT_CONTAINING(hmap_next_in_bucket(&(NODE)->MEMBER), \
NODE, MEMBER))

static inline struct hmap_node *hmap_first_with_hash(const struct hmap *,
size_t hash);
Expand All @@ -138,18 +137,18 @@ static inline struct hmap_node *hmap_next_in_bucket(const struct hmap_node *);
* The _SAFE version is needed when NODE may be freed. It is not needed when
* NODE may be removed from the hash map but its members remain accessible and
* intact. */
#define HMAP_FOR_EACH(NODE, STRUCT, MEMBER, HMAP) \
for ((NODE) = CONTAINER_OF(hmap_first(HMAP), STRUCT, MEMBER); \
&(NODE)->MEMBER != NULL; \
(NODE) = CONTAINER_OF(hmap_next(HMAP, &(NODE)->MEMBER), \
STRUCT, MEMBER))

#define HMAP_FOR_EACH_SAFE(NODE, NEXT, STRUCT, MEMBER, HMAP) \
for ((NODE) = CONTAINER_OF(hmap_first(HMAP), STRUCT, MEMBER); \
(&(NODE)->MEMBER != NULL \
? (NEXT) = CONTAINER_OF(hmap_next(HMAP, &(NODE)->MEMBER), \
STRUCT, MEMBER), 1 \
: 0); \
#define HMAP_FOR_EACH(NODE, MEMBER, HMAP) \
for ((NODE) = OBJECT_CONTAINING(hmap_first(HMAP), NODE, MEMBER); \
&(NODE)->MEMBER != NULL; \
(NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \
NODE, MEMBER))

#define HMAP_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HMAP) \
for ((NODE) = OBJECT_CONTAINING(hmap_first(HMAP), NODE, MEMBER); \
(&(NODE)->MEMBER != NULL \
? (NEXT) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \
NODE, MEMBER), 1 \
: 0); \
(NODE) = (NEXT))

static inline struct hmap_node *hmap_first(const struct hmap *);
Expand Down
24 changes: 12 additions & 12 deletions lib/list.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,18 +53,18 @@ struct list *list_back(struct list *);
size_t list_size(const struct list *);
bool list_is_empty(const struct list *);

#define LIST_FOR_EACH(ITER, STRUCT, MEMBER, LIST) \
for (ITER = CONTAINER_OF((LIST)->next, STRUCT, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ITER = CONTAINER_OF((ITER)->MEMBER.next, STRUCT, MEMBER))
#define LIST_FOR_EACH_REVERSE(ITER, STRUCT, MEMBER, LIST) \
for (ITER = CONTAINER_OF((LIST)->prev, STRUCT, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ITER = CONTAINER_OF((ITER)->MEMBER.prev, STRUCT, MEMBER))
#define LIST_FOR_EACH_SAFE(ITER, NEXT, STRUCT, MEMBER, LIST) \
for (ITER = CONTAINER_OF((LIST)->next, STRUCT, MEMBER); \
(NEXT = CONTAINER_OF((ITER)->MEMBER.next, STRUCT, MEMBER), \
&(ITER)->MEMBER != (LIST)); \
#define LIST_FOR_EACH(ITER, MEMBER, LIST) \
for (ITER = OBJECT_CONTAINING((LIST)->next, ITER, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ITER = OBJECT_CONTAINING((ITER)->MEMBER.next, ITER, MEMBER))
#define LIST_FOR_EACH_REVERSE(ITER, MEMBER, LIST) \
for (ITER = OBJECT_CONTAINING((LIST)->prev, ITER, MEMBER); \
&(ITER)->MEMBER != (LIST); \
ITER = OBJECT_CONTAINING((ITER)->MEMBER.prev, ITER, MEMBER))
#define LIST_FOR_EACH_SAFE(ITER, NEXT, MEMBER, LIST) \
for (ITER = OBJECT_CONTAINING((LIST)->next, ITER, MEMBER); \
(NEXT = OBJECT_CONTAINING((ITER)->MEMBER.next, ITER, MEMBER), \
&(ITER)->MEMBER != (LIST)); \
ITER = NEXT)

#endif /* list.h */
4 changes: 2 additions & 2 deletions lib/lockfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ lockfile_postfork(void)
{
struct lockfile *lockfile;

HMAP_FOR_EACH (lockfile, struct lockfile, hmap_node, &lock_table) {
HMAP_FOR_EACH (lockfile, hmap_node, &lock_table) {
if (lockfile->fd >= 0) {
VLOG_WARN("%s: child does not inherit lock", lockfile->name);
lockfile_unhash(lockfile);
Expand All @@ -171,7 +171,7 @@ lockfile_find(dev_t device, ino_t inode)
{
struct lockfile *lockfile;

HMAP_FOR_EACH_WITH_HASH (lockfile, struct lockfile, hmap_node,
HMAP_FOR_EACH_WITH_HASH (lockfile, hmap_node,
lockfile_hash(device, inode), &lock_table) {
if (lockfile->device == device && lockfile->inode == inode) {
return lockfile;
Expand Down
2 changes: 1 addition & 1 deletion lib/mac-learning.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ search_bucket(struct list *bucket, const uint8_t mac[ETH_ADDR_LEN],
uint16_t vlan)
{
struct mac_entry *e;
LIST_FOR_EACH (e, struct mac_entry, hash_node, bucket) {
LIST_FOR_EACH (e, hash_node, bucket) {
if (eth_addr_equals(e->mac, mac) && e->vlan == vlan) {
return e;
}
Expand Down
11 changes: 4 additions & 7 deletions lib/netdev-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -1483,8 +1483,7 @@ tc_find_queue__(const struct netdev *netdev, unsigned int queue_id,
netdev_dev_linux_cast(netdev_get_dev(netdev));
struct tc_queue *queue;

HMAP_FOR_EACH_IN_BUCKET (queue, struct tc_queue, hmap_node,
hash, &netdev_dev->tc->queues) {
HMAP_FOR_EACH_IN_BUCKET (queue, hmap_node, hash, &netdev_dev->tc->queues) {
if (queue->queue_id == queue_id) {
return queue;
}
Expand Down Expand Up @@ -1679,8 +1678,7 @@ netdev_linux_dump_queues(const struct netdev *netdev,

last_error = 0;
shash_init(&details);
HMAP_FOR_EACH (queue, struct tc_queue, hmap_node,
&netdev_dev->tc->queues) {
HMAP_FOR_EACH (queue, hmap_node, &netdev_dev->tc->queues) {
shash_clear(&details);

error = netdev_dev->tc->ops->class_get(netdev, queue, &details);
Expand Down Expand Up @@ -2012,7 +2010,7 @@ static void
poll_notify(struct list *list)
{
struct netdev_linux_notifier *notifier;
LIST_FOR_EACH (notifier, struct netdev_linux_notifier, node, list) {
LIST_FOR_EACH (notifier, node, list) {
struct netdev_notifier *n = &notifier->notifier;
n->cb(n);
}
Expand Down Expand Up @@ -2551,8 +2549,7 @@ htb_tc_destroy(struct tc *tc)
struct htb *htb = CONTAINER_OF(tc, struct htb, tc);
struct htb_class *hc, *next;

HMAP_FOR_EACH_SAFE (hc, next, struct htb_class, tc_queue.hmap_node,
&htb->tc.queues) {
HMAP_FOR_EACH_SAFE (hc, next, tc_queue.hmap_node, &htb->tc.queues) {
hmap_remove(&htb->tc.queues, &hc->tc_queue.hmap_node);
free(hc);
}
Expand Down
3 changes: 1 addition & 2 deletions lib/netdev-vport.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,7 @@ netdev_vport_poll_notify(const struct netdev *netdev)
if (list) {
struct netdev_vport_notifier *notifier;

LIST_FOR_EACH (notifier, struct netdev_vport_notifier,
list_node, list) {
LIST_FOR_EACH (notifier, list_node, list) {
struct netdev_notifier *n = &notifier->notifier;
n->cb(n);
}
Expand Down
Loading

0 comments on commit 4e8e421

Please sign in to comment.